Merge commit 468a0cb5f from llvm git (by Craig Topper):

[X86] Add X87 FCMOV support to X86FlagsCopyLowering.

  Fixes PR44396

Merge commit 86f48999f from llvm git (by Craig Topper):

  [X86] Fix typo in getCMovOpcode.

  The 64-bit HasMemoryOperand line was using CMOV32rm instead of
  CMOV64rm. Not sure how to test this. We have no test coverage that
  passes true for HasMemoryOperand.

This fixes 'Assertion failed: (MI.findRegisterDefOperand(X86::EFLAGS) &&
"Expected a def of EFLAGS for this instruction!"), function
runOnMachineFunction' when compiling the misc/gpsim port for i386.

Reported by:	yuri
Upstream PR:	https://bugs.llvm.org/show_bug.cgi?id=44396
MFC after:	1 week
This commit is contained in:
Dimitry Andric 2020-01-01 19:45:00 +00:00
parent 705d79b4bd
commit 2a168f03ac
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=356256
2 changed files with 74 additions and 1 deletions

View File

@ -115,6 +115,10 @@ class X86FlagsCopyLoweringPass : public MachineFunctionPass {
MachineBasicBlock::iterator TestPos, DebugLoc TestLoc,
MachineInstr &CMovI, MachineOperand &FlagUse,
CondRegArray &CondRegs);
void rewriteFCMov(MachineBasicBlock &TestMBB,
MachineBasicBlock::iterator TestPos, DebugLoc TestLoc,
MachineInstr &CMovI, MachineOperand &FlagUse,
CondRegArray &CondRegs);
void rewriteCondJmp(MachineBasicBlock &TestMBB,
MachineBasicBlock::iterator TestPos, DebugLoc TestLoc,
MachineInstr &JmpI, CondRegArray &CondRegs);
@ -334,6 +338,28 @@ static MachineBasicBlock &splitBlock(MachineBasicBlock &MBB,
return NewMBB;
}
static X86::CondCode getCondFromFCMOV(unsigned Opcode) {
switch (Opcode) {
default: return X86::COND_INVALID;
case X86::CMOVBE_Fp32: case X86::CMOVBE_Fp64: case X86::CMOVBE_Fp80:
return X86::COND_BE;
case X86::CMOVB_Fp32: case X86::CMOVB_Fp64: case X86::CMOVB_Fp80:
return X86::COND_B;
case X86::CMOVE_Fp32: case X86::CMOVE_Fp64: case X86::CMOVE_Fp80:
return X86::COND_E;
case X86::CMOVNBE_Fp32: case X86::CMOVNBE_Fp64: case X86::CMOVNBE_Fp80:
return X86::COND_A;
case X86::CMOVNB_Fp32: case X86::CMOVNB_Fp64: case X86::CMOVNB_Fp80:
return X86::COND_AE;
case X86::CMOVNE_Fp32: case X86::CMOVNE_Fp64: case X86::CMOVNE_Fp80:
return X86::COND_NE;
case X86::CMOVNP_Fp32: case X86::CMOVNP_Fp64: case X86::CMOVNP_Fp80:
return X86::COND_NP;
case X86::CMOVP_Fp32: case X86::CMOVP_Fp64: case X86::CMOVP_Fp80:
return X86::COND_P;
}
}
bool X86FlagsCopyLoweringPass::runOnMachineFunction(MachineFunction &MF) {
LLVM_DEBUG(dbgs() << "********** " << getPassName() << " : " << MF.getName()
<< " **********\n");
@ -593,6 +619,8 @@ bool X86FlagsCopyLoweringPass::runOnMachineFunction(MachineFunction &MF) {
// Otherwise we can just rewrite in-place.
if (X86::getCondFromCMov(MI) != X86::COND_INVALID) {
rewriteCMov(*TestMBB, TestPos, TestLoc, MI, *FlagUse, CondRegs);
} else if (getCondFromFCMOV(MI.getOpcode()) != X86::COND_INVALID) {
rewriteFCMov(*TestMBB, TestPos, TestLoc, MI, *FlagUse, CondRegs);
} else if (X86::getCondFromSETCC(MI) != X86::COND_INVALID) {
rewriteSetCC(*TestMBB, TestPos, TestLoc, MI, *FlagUse, CondRegs);
} else if (MI.getOpcode() == TargetOpcode::COPY) {
@ -851,6 +879,51 @@ void X86FlagsCopyLoweringPass::rewriteCMov(MachineBasicBlock &TestMBB,
LLVM_DEBUG(dbgs() << " fixed cmov: "; CMovI.dump());
}
void X86FlagsCopyLoweringPass::rewriteFCMov(MachineBasicBlock &TestMBB,
MachineBasicBlock::iterator TestPos,
DebugLoc TestLoc,
MachineInstr &CMovI,
MachineOperand &FlagUse,
CondRegArray &CondRegs) {
// First get the register containing this specific condition.
X86::CondCode Cond = getCondFromFCMOV(CMovI.getOpcode());
unsigned CondReg;
bool Inverted;
std::tie(CondReg, Inverted) =
getCondOrInverseInReg(TestMBB, TestPos, TestLoc, Cond, CondRegs);
MachineBasicBlock &MBB = *CMovI.getParent();
// Insert a direct test of the saved register.
insertTest(MBB, CMovI.getIterator(), CMovI.getDebugLoc(), CondReg);
auto getFCMOVOpcode = [](unsigned Opcode, bool Inverted) {
switch (Opcode) {
default: llvm_unreachable("Unexpected opcode!");
case X86::CMOVBE_Fp32: case X86::CMOVNBE_Fp32:
case X86::CMOVB_Fp32: case X86::CMOVNB_Fp32:
case X86::CMOVE_Fp32: case X86::CMOVNE_Fp32:
case X86::CMOVP_Fp32: case X86::CMOVNP_Fp32:
return Inverted ? X86::CMOVE_Fp32 : X86::CMOVNE_Fp32;
case X86::CMOVBE_Fp64: case X86::CMOVNBE_Fp64:
case X86::CMOVB_Fp64: case X86::CMOVNB_Fp64:
case X86::CMOVE_Fp64: case X86::CMOVNE_Fp64:
case X86::CMOVP_Fp64: case X86::CMOVNP_Fp64:
return Inverted ? X86::CMOVE_Fp64 : X86::CMOVNE_Fp64;
case X86::CMOVBE_Fp80: case X86::CMOVNBE_Fp80:
case X86::CMOVB_Fp80: case X86::CMOVNB_Fp80:
case X86::CMOVE_Fp80: case X86::CMOVNE_Fp80:
case X86::CMOVP_Fp80: case X86::CMOVNP_Fp80:
return Inverted ? X86::CMOVE_Fp80 : X86::CMOVNE_Fp80;
}
};
// Rewrite the CMov to use the !ZF flag from the test.
CMovI.setDesc(TII->get(getFCMOVOpcode(CMovI.getOpcode(), Inverted)));
FlagUse.setIsKill(true);
LLVM_DEBUG(dbgs() << " fixed fcmov: "; CMovI.dump());
}
void X86FlagsCopyLoweringPass::rewriteCondJmp(
MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
DebugLoc TestLoc, MachineInstr &JmpI, CondRegArray &CondRegs) {

View File

@ -2198,7 +2198,7 @@ unsigned X86::getCMovOpcode(unsigned RegBytes, bool HasMemoryOperand) {
default: llvm_unreachable("Illegal register size!");
case 2: return HasMemoryOperand ? X86::CMOV16rm : X86::CMOV16rr;
case 4: return HasMemoryOperand ? X86::CMOV32rm : X86::CMOV32rr;
case 8: return HasMemoryOperand ? X86::CMOV32rm : X86::CMOV64rr;
case 8: return HasMemoryOperand ? X86::CMOV64rm : X86::CMOV64rr;
}
}