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:
parent
b7749b90ee
commit
459918405b
@ -115,6 +115,10 @@ private:
|
||||
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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user