Make FP_TO_UINT Illegal. This allows us to generate significantly better
codegen for FP_TO_UINT by using the legalizer's SELECT variant.
Implement a codegen improvement for SELECT_CC, selecting the false node in
the MBB that feeds the phi node. This allows us to codegen:
void foo(int *a, int b, int c) { int d = (a < b) ? 5 : 9; *a = d; }
as:
_foo:
li r2, 5
cmpw cr0, r4, r3
bgt .LBB_foo_2 ; entry
.LBB_foo_1: ; entry
li r2, 9
.LBB_foo_2: ; entry
stw r2, 0(r3)
blr
insted of:
_foo:
li r2, 5
li r5, 9
cmpw cr0, r4, r3
bgt .LBB_foo_2 ; entry
.LBB_foo_1: ; entry
or r2, r5, r5
.LBB_foo_2: ; entry
stw r2, 0(r3)
blr
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22784 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/PowerPC/PPCISelPattern.cpp b/lib/Target/PowerPC/PPCISelPattern.cpp
index 9725c2c..80a405e 100644
--- a/lib/Target/PowerPC/PPCISelPattern.cpp
+++ b/lib/Target/PowerPC/PPCISelPattern.cpp
@@ -88,6 +88,9 @@
setOperationAction(ISD::SELECT, MVT::f32, Expand);
setOperationAction(ISD::SELECT, MVT::f64, Expand);
+ // PowerPC does not have FP_TO_UINT
+ setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
+
setSetCCResultContents(ZeroOrOneSetCCResult);
addLegalFPImmediate(+0.0); // Necessary for FSEL
addLegalFPImmediate(-0.0); //
@@ -1341,8 +1344,8 @@
switch (opcode) {
default:
- Node->dump();
- assert(0 && "\nNode not handled!\n");
+ Node->dump(); std::cerr << '\n';
+ assert(0 && "Node not handled!\n");
case ISD::UNDEF:
BuildMI(BB, PPC::IMPLICIT_DEF, 0, Result);
return Result;
@@ -2000,75 +2003,14 @@
return Result+N.ResNo;
}
- case ISD::FP_TO_UINT:
case ISD::FP_TO_SINT: {
- bool U = (ISD::FP_TO_UINT == opcode);
Tmp1 = SelectExpr(N.getOperand(0));
- if (!U) {
- Tmp2 = MakeFPReg();
- BuildMI(BB, PPC::FCTIWZ, 1, Tmp2).addReg(Tmp1);
- int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8);
- addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(Tmp2), FrameIdx);
- addFrameReference(BuildMI(BB, PPC::LWZ, 2, Result), FrameIdx, 4);
- return Result;
- } else {
- unsigned Zero = getConstDouble(0.0);
- unsigned MaxInt = getConstDouble((1LL << 32) - 1);
- unsigned Border = getConstDouble(1LL << 31);
- unsigned UseZero = MakeFPReg();
- unsigned UseMaxInt = MakeFPReg();
- unsigned UseChoice = MakeFPReg();
- unsigned TmpReg = MakeFPReg();
- unsigned TmpReg2 = MakeFPReg();
- unsigned ConvReg = MakeFPReg();
- unsigned IntTmp = MakeIntReg();
- unsigned XorReg = MakeIntReg();
- MachineFunction *F = BB->getParent();
- int FrameIdx = F->getFrameInfo()->CreateStackObject(8, 8);
- // Update machine-CFG edges
- MachineBasicBlock *XorMBB = new MachineBasicBlock(BB->getBasicBlock());
- MachineBasicBlock *PhiMBB = new MachineBasicBlock(BB->getBasicBlock());
- MachineBasicBlock *OldMBB = BB;
- ilist<MachineBasicBlock>::iterator It = BB; ++It;
- F->getBasicBlockList().insert(It, XorMBB);
- F->getBasicBlockList().insert(It, PhiMBB);
- BB->addSuccessor(XorMBB);
- BB->addSuccessor(PhiMBB);
- // Convert from floating point to unsigned 32-bit value
- // Use 0 if incoming value is < 0.0
- BuildMI(BB, PPC::FSEL, 3, UseZero).addReg(Tmp1).addReg(Tmp1).addReg(Zero);
- // Use 2**32 - 1 if incoming value is >= 2**32
- BuildMI(BB, PPC::FSUB, 2, UseMaxInt).addReg(MaxInt).addReg(Tmp1);
- BuildMI(BB, PPC::FSEL, 3, UseChoice).addReg(UseMaxInt).addReg(UseZero)
- .addReg(MaxInt);
- // Subtract 2**31
- BuildMI(BB, PPC::FSUB, 2, TmpReg).addReg(UseChoice).addReg(Border);
- // Use difference if >= 2**31
- BuildMI(BB, PPC::FCMPU, 2, PPC::CR0).addReg(UseChoice).addReg(Border);
- BuildMI(BB, PPC::FSEL, 3, TmpReg2).addReg(TmpReg).addReg(TmpReg)
- .addReg(UseChoice);
- // Convert to integer
- BuildMI(BB, PPC::FCTIWZ, 1, ConvReg).addReg(TmpReg2);
- addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(ConvReg), FrameIdx);
- addFrameReference(BuildMI(BB, PPC::LWZ, 2, IntTmp), FrameIdx, 4);
- BuildMI(BB, PPC::BLT, 2).addReg(PPC::CR0).addMBB(PhiMBB);
- BuildMI(BB, PPC::B, 1).addMBB(XorMBB);
-
- // XorMBB:
- // add 2**31 if input was >= 2**31
- BB = XorMBB;
- BuildMI(BB, PPC::XORIS, 2, XorReg).addReg(IntTmp).addImm(0x8000);
- XorMBB->addSuccessor(PhiMBB);
-
- // PhiMBB:
- // DestReg = phi [ IntTmp, OldMBB ], [ XorReg, XorMBB ]
- BB = PhiMBB;
- BuildMI(BB, PPC::PHI, 4, Result).addReg(IntTmp).addMBB(OldMBB)
- .addReg(XorReg).addMBB(XorMBB);
- return Result;
- }
- assert(0 && "Should never get here");
- return 0;
+ Tmp2 = MakeFPReg();
+ BuildMI(BB, PPC::FCTIWZ, 1, Tmp2).addReg(Tmp1);
+ int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8);
+ addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(Tmp2), FrameIdx);
+ addFrameReference(BuildMI(BB, PPC::LWZ, 2, Result), FrameIdx, 4);
+ return Result;
}
case ISD::SETCC: {
@@ -2217,8 +2159,12 @@
assert(0 && "Should never get here");
}
- unsigned TrueValue = SelectExpr(N.getOperand(2)); //Use if TRUE
- unsigned FalseValue = SelectExpr(N.getOperand(3)); //Use if FALSE
+ // If the False value only has one use, we can generate better code by
+ // selecting it in the fallthrough basic block rather than here, which
+ // increases register pressure.
+ bool FalseHasOneUse = N.getOperand(3).Val->hasOneUse();
+ unsigned TrueValue = SelectExpr(N.getOperand(2));
+ unsigned FalseValue = FalseHasOneUse ? 0 : SelectExpr(N.getOperand(3));
unsigned CCReg = SelectCC(N.getOperand(0), N.getOperand(1), CC);
Opc = getBCCForSetCC(CC);
@@ -2249,6 +2195,7 @@
// %FalseValue = ...
// # fallthrough to sinkMBB
BB = copy0MBB;
+ if (FalseHasOneUse) FalseValue = SelectExpr(N.getOperand(3));
// Update machine-CFG edges
BB->addSuccessor(sinkMBB);