[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Nate Begeman natebegeman at mac.com
Sat Aug 13 18:21:04 PDT 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

LegalizeDAG.cpp updated: 1.158 -> 1.159
---
Log message:

Teach the legalizer how to legalize FP_TO_UINT.
Teach the legalizer to promote FP_TO_UINT to FP_TO_SINT if the wider
  FP_TO_UINT is also illegal.  This allows us on PPC to codegen
  unsigned short foo(float a) { return a; }

as:
_foo:
.LBB_foo_0:     ; entry
        fctiwz f0, f1
        stfd f0, -8(r1)
        lwz r2, -4(r1)
        rlwinm r3, r2, 0, 16, 31
        blr

instead of:
_foo:
.LBB_foo_0:     ; entry
        fctiwz f0, f1
        stfd f0, -8(r1)
        lwz r2, -4(r1)
        lis r3, ha16(.CPI_foo_0)
        lfs f0, lo16(.CPI_foo_0)(r3)
        fcmpu cr0, f1, f0
        blt .LBB_foo_2  ; entry
.LBB_foo_1:     ; entry
        fsubs f0, f1, f0
        fctiwz f0, f0
        stfd f0, -16(r1)
        lwz r2, -12(r1)
        xoris r2, r2, 32768
.LBB_foo_2:     ; entry
        rlwinm r3, r2, 0, 16, 31
        blr


---
Diffs of the changes:  (+32 -3)

 LegalizeDAG.cpp |   35 ++++++++++++++++++++++++++++++++---
 1 files changed, 32 insertions(+), 3 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.158 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.159
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.158	Wed Aug 10 20:12:20 2005
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	Sat Aug 13 20:20:53 2005
@@ -1610,7 +1610,25 @@
       switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))){
       default: assert(0 && "Unknown operation action!");
       case TargetLowering::Expand:
-        assert(0 && "Cannot expand FP_TO*INT yet");
+        if (Node->getOpcode() == ISD::FP_TO_UINT) {
+          SDOperand True, False;
+          MVT::ValueType VT =  Node->getOperand(0).getValueType();
+          MVT::ValueType NVT = Node->getValueType(0);
+          unsigned ShiftAmt = MVT::getSizeInBits(Node->getValueType(0))-1;
+          Tmp2 = DAG.getConstantFP((double)(1ULL << ShiftAmt), VT);
+          Tmp3 = DAG.getSetCC(TLI.getSetCCResultTy(),
+                            Node->getOperand(0), Tmp2, ISD::SETLT);
+          True = DAG.getNode(ISD::FP_TO_SINT, NVT, Node->getOperand(0));
+          False = DAG.getNode(ISD::FP_TO_SINT, NVT,
+                              DAG.getNode(ISD::SUB, VT, Node->getOperand(0),
+                                          Tmp2));
+          False = DAG.getNode(ISD::XOR, NVT, False, 
+                              DAG.getConstant(1ULL << ShiftAmt, NVT));
+          Result = LegalizeOp(DAG.getNode(ISD::SELECT, NVT, Tmp3, True, False));
+        } else {
+          assert(0 && "Do not know how to expand FP_TO_SINT yet!");
+        }
+        break;
       case TargetLowering::Promote:
         Result = PromoteLegalFP_TO_INT(Tmp1, Node->getValueType(0),
                                        Node->getOpcode() == ISD::FP_TO_SINT);
@@ -1907,7 +1925,18 @@
     case Expand:
       assert(0 && "not implemented");
     }
-    Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
+    // If we're promoting a UINT to a larger size, check to see if the new node
+    // will be legal.  If it isn't, check to see if FP_TO_SINT is legal, since
+    // we can use that instead.  This allows us to generate better code for
+    // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not
+    // legal, such as PowerPC.
+    if (Node->getOpcode() == ISD::FP_TO_UINT && 
+        TargetLowering::Legal != TLI.getOperationAction(ISD::FP_TO_UINT, NVT) &&
+        TargetLowering::Legal == TLI.getOperationAction(ISD::FP_TO_SINT, NVT)) {
+      Result = DAG.getNode(ISD::FP_TO_SINT, NVT, Tmp1);
+    } else {
+      Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
+    }
     break;
 
   case ISD::FABS:
@@ -2078,7 +2107,7 @@
       break;
     case ISD::CTTZ:
       //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
-      Tmp2 = DAG.getSetCC(MVT::i1, Tmp1,
+      Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), Tmp1,
                           DAG.getConstant(getSizeInBits(NVT), NVT), ISD::SETEQ);
       Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
                            DAG.getConstant(getSizeInBits(VT),NVT), Tmp1);






More information about the llvm-commits mailing list