[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp

Nate Begeman natebegeman at mac.com
Wed Oct 6 02:53:24 PDT 2004



Changes in directory llvm/lib/Target/PowerPC:

PPC32ISelSimple.cpp updated: 1.85 -> 1.86
---
Log message:

Implement floating point select for lt, gt, le, ge using the powerpc fsel
instruction.

Now, rather than emitting the following loop out of bisect:
.LBB_main_19:	; no_exit.0.i
	rlwinm r3, r2, 3, 0, 28
	lfdx f1, r3, r27
	addis r3, r30, ha16(.CPI_main_1-"L00000$pb")
	lfd f2, lo16(.CPI_main_1-"L00000$pb")(r3)
	fsub f2, f2, f1
	addis r3, r30, ha16(.CPI_main_1-"L00000$pb")
	lfd f4, lo16(.CPI_main_1-"L00000$pb")(r3)
	fcmpu cr0, f1, f4
	bge .LBB_main_64	; no_exit.0.i
.LBB_main_63:	; no_exit.0.i
	b .LBB_main_65	; no_exit.0.i
.LBB_main_64:	; no_exit.0.i
	fmr f2, f1
.LBB_main_65:	; no_exit.0.i
	addi r3, r2, 1
	rlwinm r3, r3, 3, 0, 28
	lfdx f1, r3, r27
	addis r3, r30, ha16(.CPI_main_1-"L00000$pb")
	lfd f4, lo16(.CPI_main_1-"L00000$pb")(r3)
	fsub f4, f4, f1
	addis r3, r30, ha16(.CPI_main_1-"L00000$pb")
	lfd f5, lo16(.CPI_main_1-"L00000$pb")(r3)
	fcmpu cr0, f1, f5
	bge .LBB_main_67	; no_exit.0.i
.LBB_main_66:	; no_exit.0.i
	b .LBB_main_68	; no_exit.0.i
.LBB_main_67:	; no_exit.0.i
	fmr f4, f1
.LBB_main_68:	; no_exit.0.i
	fadd f1, f2, f4
	addis r3, r30, ha16(.CPI_main_2-"L00000$pb")
	lfd f2, lo16(.CPI_main_2-"L00000$pb")(r3)
	fmul f1, f1, f2
	rlwinm r3, r2, 3, 0, 28
	lfdx f2, r3, r28
	fadd f4, f2, f1
	fcmpu cr0, f4, f0
	bgt .LBB_main_70	; no_exit.0.i
.LBB_main_69:	; no_exit.0.i
	b .LBB_main_71	; no_exit.0.i
.LBB_main_70:	; no_exit.0.i
	fmr f0, f4
.LBB_main_71:	; no_exit.0.i
	fsub f1, f2, f1
	addi r2, r2, -1
	fcmpu cr0, f1, f3
	blt .LBB_main_73	; no_exit.0.i
.LBB_main_72:	; no_exit.0.i
	b .LBB_main_74	; no_exit.0.i
.LBB_main_73:	; no_exit.0.i
	fmr f3, f1
.LBB_main_74:	; no_exit.0.i
	cmpwi cr0, r2, -1
	fmr f16, f0
	fmr f17, f3
	bgt .LBB_main_19	; no_exit.0.i

We emit this instead:
.LBB_main_19:	; no_exit.0.i
	rlwinm r3, r2, 3, 0, 28
	lfdx f1, r3, r27
	addis r3, r30, ha16(.CPI_main_1-"L00000$pb")
	lfd f2, lo16(.CPI_main_1-"L00000$pb")(r3)
	fsub f2, f2, f1
	fsel f1, f1, f1, f2
	addi r3, r2, 1
	rlwinm r3, r3, 3, 0, 28
	lfdx f2, r3, r27
	addis r3, r30, ha16(.CPI_main_1-"L00000$pb")
	lfd f4, lo16(.CPI_main_1-"L00000$pb")(r3)
	fsub f4, f4, f2
	fsel f2, f2, f2, f4
	fadd f1, f1, f2
	addis r3, r30, ha16(.CPI_main_2-"L00000$pb")
	lfd f2, lo16(.CPI_main_2-"L00000$pb")(r3)
	fmul f1, f1, f2
	rlwinm r3, r2, 3, 0, 28
	lfdx f2, r3, r28
	fadd f4, f2, f1
	fsub f5, f0, f4
	fsel f0, f5, f0, f4
	fsub f1, f2, f1
	addi r2, r2, -1
	fsub f2, f1, f3
	fsel f3, f2, f3, f1
	cmpwi cr0, r2, -1
	fmr f16, f0
	fmr f17, f3
	bgt .LBB_main_19	; no_exit.0.i


---
Diffs of the changes:  (+113 -25)

Index: llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp
diff -u llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.85 llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.86
--- llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp:1.85	Wed Sep 29 00:00:31 2004
+++ llvm/lib/Target/PowerPC/PPC32ISelSimple.cpp	Wed Oct  6 04:53:04 2004
@@ -32,6 +32,8 @@
 using namespace llvm;
 
 namespace {
+  Statistic<> NumFSEL("ppc-codegen", "Number of fsel emitted");
+
   /// TypeClass - Used by the PowerPC backend to group LLVM types by their basic
   /// PPC Representation.
   ///
@@ -1289,6 +1291,85 @@
   if (SetCondInst *SCI = canFoldSetCCIntoBranchOrSelect(Cond)) {
     // We successfully folded the setcc into the select instruction.
     unsigned OpNum = getSetCCNumber(SCI->getOpcode());
+    /*
+    if (OpNum >= 2 && OpNum <= 5) {
+      unsigned SetCondClass = getClassB(SCI->getOperand(0)->getType());
+      if ((SetCondClass == cFP32 || SetCondClass == cFP64) &&
+          (SelectClass == cFP32 || SelectClass == cFP64)) {
+        unsigned CondReg = getReg(SCI->getOperand(0), MBB, IP);
+        unsigned TrueReg = getReg(TrueVal, MBB, IP);
+        unsigned FalseReg = getReg(FalseVal, MBB, IP);
+        // if the comparison of the floating point value used to for the select
+        // is against 0, then we can emit an fsel without subtraction.
+        ConstantFP *Op1C = dyn_cast<ConstantFP>(SCI->getOperand(1));
+        if (Op1C && (Op1C->isExactlyValue(-0.0) || Op1C->isExactlyValue(0.0))) {
+          switch(OpNum) {
+          case 2:   // LT
+            BuildMI(*MBB, IP, PPC::FSEL, 3, DestReg).addReg(CondReg)
+              .addReg(FalseReg).addReg(TrueReg);
+            break;
+          case 3:   // GE == !LT
+            BuildMI(*MBB, IP, PPC::FSEL, 3, DestReg).addReg(CondReg)
+              .addReg(TrueReg).addReg(FalseReg);
+            break;
+          case 4: {  // GT
+            unsigned NegatedReg = makeAnotherReg(SCI->getOperand(0)->getType());
+            BuildMI(*MBB, IP, PPC::FNEG, 1, NegatedReg).addReg(CondReg);
+            BuildMI(*MBB, IP, PPC::FSEL, 3, DestReg).addReg(NegatedReg)
+              .addReg(FalseReg).addReg(TrueReg);
+            }
+            break;
+          case 5: {  // LE == !GT
+            unsigned NegatedReg = makeAnotherReg(SCI->getOperand(0)->getType());
+            BuildMI(*MBB, IP, PPC::FNEG, 1, NegatedReg).addReg(CondReg);
+            BuildMI(*MBB, IP, PPC::FSEL, 3, DestReg).addReg(NegatedReg)
+              .addReg(TrueReg).addReg(FalseReg);
+            }
+            break;
+          default:
+            assert(0 && "Invalid SetCC opcode to fsel");
+            abort();
+            break;
+          }
+        } else {
+          unsigned OtherCondReg = getReg(SCI->getOperand(1), MBB, IP);
+          unsigned SelectReg = makeAnotherReg(SCI->getOperand(0)->getType());
+          switch(OpNum) {
+          case 2:   // LT
+            BuildMI(*MBB, IP, PPC::FSUB, 2, SelectReg).addReg(CondReg)
+              .addReg(OtherCondReg);
+            BuildMI(*MBB, IP, PPC::FSEL, 3, DestReg).addReg(SelectReg)
+              .addReg(FalseReg).addReg(TrueReg);
+            break;
+          case 3:   // GE == !LT
+            BuildMI(*MBB, IP, PPC::FSUB, 2, SelectReg).addReg(CondReg)
+              .addReg(OtherCondReg);
+            BuildMI(*MBB, IP, PPC::FSEL, 3, DestReg).addReg(SelectReg)
+              .addReg(TrueReg).addReg(FalseReg);
+            break;
+          case 4:   // GT
+            BuildMI(*MBB, IP, PPC::FSUB, 2, SelectReg).addReg(OtherCondReg)
+              .addReg(CondReg);
+            BuildMI(*MBB, IP, PPC::FSEL, 3, DestReg).addReg(SelectReg)
+              .addReg(FalseReg).addReg(TrueReg);
+            break;
+          case 5:   // LE == !GT
+            BuildMI(*MBB, IP, PPC::FSUB, 2, SelectReg).addReg(OtherCondReg)
+              .addReg(CondReg);
+            BuildMI(*MBB, IP, PPC::FSEL, 3, DestReg).addReg(SelectReg)
+              .addReg(TrueReg).addReg(FalseReg);
+            break;
+          default:
+            assert(0 && "Invalid SetCC opcode to fsel");
+            abort();
+            break;
+          }
+        }
+        ++NumFSEL;
+        return;
+      }
+    }
+    */
     OpNum = EmitComparison(OpNum, SCI->getOperand(0),SCI->getOperand(1),MBB,IP);
     Opcode = getPPCOpcodeForSetCCNumber(SCI->getOpcode());
   } else {
@@ -2242,7 +2323,7 @@
                       ResultReg);
 }
 
-void PPC32ISel::emitDivRemOperation(MachineBasicBlock *BB,
+void PPC32ISel::emitDivRemOperation(MachineBasicBlock *MBB,
                                     MachineBasicBlock::iterator IP,
                                     Value *Op0, Value *Op1, bool isDiv,
                                     unsigned ResultReg) {
@@ -2252,12 +2333,12 @@
   case cFP32:
     if (isDiv) {
       // Floating point divide...
-      emitBinaryFPOperation(BB, IP, Op0, Op1, 3, ResultReg);
+      emitBinaryFPOperation(MBB, IP, Op0, Op1, 3, ResultReg);
       return;
     } else {
       // Floating point remainder via fmodf(float x, float y);
-      unsigned Op0Reg = getReg(Op0, BB, IP);
-      unsigned Op1Reg = getReg(Op1, BB, IP);
+      unsigned Op0Reg = getReg(Op0, MBB, IP);
+      unsigned Op1Reg = getReg(Op1, MBB, IP);
       MachineInstr *TheCall =
         BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(fmodfFn, true);
       std::vector<ValueRecord> Args;
@@ -2270,12 +2351,12 @@
   case cFP64:
     if (isDiv) {
       // Floating point divide...
-      emitBinaryFPOperation(BB, IP, Op0, Op1, 3, ResultReg);
+      emitBinaryFPOperation(MBB, IP, Op0, Op1, 3, ResultReg);
       return;
     } else {               
       // Floating point remainder via fmod(double x, double y);
-      unsigned Op0Reg = getReg(Op0, BB, IP);
-      unsigned Op1Reg = getReg(Op1, BB, IP);
+      unsigned Op0Reg = getReg(Op0, MBB, IP);
+      unsigned Op1Reg = getReg(Op1, MBB, IP);
       MachineInstr *TheCall =
         BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(fmodFn, true);
       std::vector<ValueRecord> Args;
@@ -2288,8 +2369,8 @@
   case cLong: {
     static Function* const Funcs[] =
       { __moddi3Fn, __divdi3Fn, __umoddi3Fn, __udivdi3Fn };
-    unsigned Op0Reg = getReg(Op0, BB, IP);
-    unsigned Op1Reg = getReg(Op1, BB, IP);
+    unsigned Op0Reg = getReg(Op0, MBB, IP);
+    unsigned Op1Reg = getReg(Op1, MBB, IP);
     unsigned NameIdx = Ty->isUnsigned()*2 + isDiv;
     MachineInstr *TheCall =
       BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(Funcs[NameIdx], true);
@@ -2313,41 +2394,48 @@
       int V = CI->getValue();
 
       if (V == 1) {       // X /s 1 => X
-        unsigned Op0Reg = getReg(Op0, BB, IP);
-        BuildMI(*BB, IP, PPC::OR, 2, ResultReg).addReg(Op0Reg).addReg(Op0Reg);
+        unsigned Op0Reg = getReg(Op0, MBB, IP);
+        BuildMI(*MBB, IP, PPC::OR, 2, ResultReg).addReg(Op0Reg).addReg(Op0Reg);
         return;
       }
 
       if (V == -1) {      // X /s -1 => -X
-        unsigned Op0Reg = getReg(Op0, BB, IP);
-        BuildMI(*BB, IP, PPC::NEG, 1, ResultReg).addReg(Op0Reg);
+        unsigned Op0Reg = getReg(Op0, MBB, IP);
+        BuildMI(*MBB, IP, PPC::NEG, 1, ResultReg).addReg(Op0Reg);
         return;
       }
 
       unsigned log2V = ExactLog2(V);
       if (log2V != 0 && Ty->isSigned()) {
-        unsigned Op0Reg = getReg(Op0, BB, IP);
+        unsigned Op0Reg = getReg(Op0, MBB, IP);
         unsigned TmpReg = makeAnotherReg(Op0->getType());
         
-        BuildMI(*BB, IP, PPC::SRAWI, 2, TmpReg).addReg(Op0Reg).addImm(log2V);
-        BuildMI(*BB, IP, PPC::ADDZE, 1, ResultReg).addReg(TmpReg);
+        BuildMI(*MBB, IP, PPC::SRAWI, 2, TmpReg).addReg(Op0Reg).addImm(log2V);
+        BuildMI(*MBB, IP, PPC::ADDZE, 1, ResultReg).addReg(TmpReg);
         return;
       }
     }
 
-  unsigned Op0Reg = getReg(Op0, BB, IP);
-  unsigned Op1Reg = getReg(Op1, BB, IP);
-  unsigned Opcode = Ty->isSigned() ? PPC::DIVW : PPC::DIVWU;
-  
+  unsigned Op0Reg = getReg(Op0, MBB, IP);
+
   if (isDiv) {
-    BuildMI(*BB, IP, Opcode, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
+    unsigned Op1Reg = getReg(Op1, MBB, IP);
+    unsigned Opcode = Ty->isSigned() ? PPC::DIVW : PPC::DIVWU;
+    BuildMI(*MBB, IP, Opcode, 2, ResultReg).addReg(Op0Reg).addReg(Op1Reg);
   } else { // Remainder
+    // FIXME: don't load the CI part of a CI divide twice
+    ConstantInt *CI = dyn_cast<ConstantInt>(Op1);
     unsigned TmpReg1 = makeAnotherReg(Op0->getType());
     unsigned TmpReg2 = makeAnotherReg(Op0->getType());
-    
-    BuildMI(*BB, IP, Opcode, 2, TmpReg1).addReg(Op0Reg).addReg(Op1Reg);
-    BuildMI(*BB, IP, PPC::MULLW, 2, TmpReg2).addReg(TmpReg1).addReg(Op1Reg);
-    BuildMI(*BB, IP, PPC::SUBF, 2, ResultReg).addReg(TmpReg2).addReg(Op0Reg);
+    emitDivRemOperation(MBB, IP, Op0, Op1, true, TmpReg1);
+    if (CI && canUseAsImmediateForOpcode(CI, 0)) {
+      BuildMI(*MBB, IP, PPC::MULLI, 2, TmpReg2).addReg(TmpReg1)
+        .addSImm(CI->getRawValue());
+    } else {
+      unsigned Op1Reg = getReg(Op1, MBB, IP);
+      BuildMI(*MBB, IP, PPC::MULLW, 2, TmpReg2).addReg(TmpReg1).addReg(Op1Reg);
+    }
+    BuildMI(*MBB, IP, PPC::SUBF, 2, ResultReg).addReg(TmpReg2).addReg(Op0Reg);
   }
 }
 






More information about the llvm-commits mailing list