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

Chris Lattner lattner at cs.uiuc.edu
Fri Jul 15 17:20:11 PDT 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

LegalizeDAG.cpp updated: 1.140 -> 1.141
---
Log message:

Break the code for expanding UINT_TO_FP operations out into its own
SelectionDAGLegalize::ExpandLegalUINT_TO_FP method.

Add a new method, PromoteLegalUINT_TO_FP, which allows targets to request
that UINT_TO_FP operations be promoted to a larger input type.  This is 
useful for targets that have some UINT_TO_FP or SINT_TO_FP operations but
not all of them (like X86).

The same should be done with SINT_TO_FP, but this patch does not do that
yet.



---
Diffs of the changes:  (+116 -35)

 LegalizeDAG.cpp |  151 +++++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 116 insertions(+), 35 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.140 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.141
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.140	Tue Jul 12 21:00:04 2005
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	Fri Jul 15 19:19:57 2005
@@ -124,6 +124,10 @@
                           SDOperand &Hi);
   SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,
                           SDOperand Source);
+
+  SDOperand ExpandLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT);
+  SDOperand PromoteLegalUINT_TO_FP(SDOperand LegalOp, MVT::ValueType DestVT);
+ 
   bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt,
                    SDOperand &Lo, SDOperand &Hi);
   void ExpandShiftParts(unsigned NodeOp, SDOperand Op, SDOperand Amt,
@@ -147,6 +151,102 @@
          "Too many value types for ValueTypeActions to hold!");
 }
 
+/// ExpandLegalUINT_TO_FP - This function is responsible for legalizing a 
+/// UINT_TO_FP operation of the specified operand when the target requests that
+/// we expand it.  At this point, we know that the result and operand types are
+/// legal for the target.
+SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0,
+                                                      MVT::ValueType DestVT) {
+  assert(Op0.getValueType() == MVT::i32 &&
+         "This code only works for i32 input: extend in the future");
+  SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
+  
+  SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(), 
+                                   Op0,
+                                   DAG.getConstant(0, 
+                                                   Op0.getValueType()));
+  SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
+  SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
+                                    SignSet, Four, Zero);
+  
+  uint64_t FF = 0x5f800000ULL;
+  if (TLI.isLittleEndian()) FF <<= 32;
+  static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
+  
+  MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool();
+  SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor),
+                                        TLI.getPointerTy());
+  CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
+  SDOperand FudgeInReg;
+  if (DestVT == MVT::f32)
+    FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
+                             DAG.getSrcValue(NULL));
+  else {
+    assert(DestVT == MVT::f64 && "Unexpected conversion");
+    FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
+                                           DAG.getEntryNode(), CPIdx,
+                                           DAG.getSrcValue(NULL), MVT::f32));
+  }
+  
+  NeedsAnotherIteration = true;
+  return DAG.getNode(ISD::ADD, DestVT, Tmp1, FudgeInReg);
+}
+
+/// PromoteLegalUINT_TO_FP - This function is responsible for legalizing a 
+/// UINT_TO_FP operation of the specified operand when the target requests that
+/// we promote it.  At this point, we know that the result and operand types are
+/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
+/// operation that takes a larger input.
+SDOperand SelectionDAGLegalize::PromoteLegalUINT_TO_FP(SDOperand LegalOp,
+                                                       MVT::ValueType DestVT) {
+  // First step, figure out the appropriate *INT_TO_FP operation to use.
+  MVT::ValueType NewInTy = LegalOp.getValueType();
+  
+  unsigned OpToUse = 0;
+  
+  // Scan for the appropriate larger type to use.
+  while (1) {
+    NewInTy = (MVT::ValueType)(NewInTy+1);
+    assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!");
+    
+    // If the target supports SINT_TO_FP of this type, use it.
+    switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) {
+      default: break;
+      case TargetLowering::Legal:
+        if (!TLI.hasNativeSupportFor(NewInTy))
+          break;  // Can't use this datatype.
+        // FALL THROUGH.
+      case TargetLowering::Custom:
+        OpToUse = ISD::SINT_TO_FP;
+        break;
+    }
+    if (OpToUse) break;
+    
+    // If the target supports UINT_TO_FP of this type, use it.
+    switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) {
+      default: break;
+      case TargetLowering::Legal:
+        if (!TLI.hasNativeSupportFor(NewInTy))
+          break;  // Can't use this datatype.
+        // FALL THROUGH.
+      case TargetLowering::Custom:
+        OpToUse = ISD::UINT_TO_FP;
+        break;
+    }
+    if (OpToUse) break;
+    
+    // Otherwise, try a larger type.
+  }
+
+  // Make sure to legalize any nodes we create here in the next pass.
+  NeedsAnotherIteration = true;
+  
+  // Okay, we found the operation and type to use.  Zero extend our input to the
+  // desired type then run the operation on it.
+  return DAG.getNode(OpToUse, DestVT,
+                     DAG.getNode(ISD::ZERO_EXTEND, NewInTy, LegalOp));
+}
+
 void SelectionDAGLegalize::LegalizeDAG() {
   SDOperand OldRoot = DAG.getRoot();
   SDOperand NewRoot = LegalizeOp(OldRoot);
@@ -1338,42 +1438,23 @@
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
     case Legal:
       //still made need to expand if the op is illegal, but the types are legal
-      if (Node->getOpcode() == ISD::UINT_TO_FP &&
-          TLI.getOperationAction(Node->getOpcode(), 
-                                 Node->getOperand(0).getValueType()) 
-          == TargetLowering::Expand) {
-        SDOperand Op0 = LegalizeOp(Node->getOperand(0));
-        Tmp1 = DAG.getNode(ISD::SINT_TO_FP, Node->getValueType(0), 
-                           Op0);
-        
-        SDOperand SignSet = DAG.getSetCC(ISD::SETLT, TLI.getSetCCResultTy(), 
-                                         Op0,
-                                         DAG.getConstant(0, 
-                                         Op0.getValueType()));
-        SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
-        SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
-                                          SignSet, Four, Zero);
-        uint64_t FF = 0x5f800000ULL;
-        if (TLI.isLittleEndian()) FF <<= 32;
-        static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
-
-        MachineConstantPool *CP = DAG.getMachineFunction().getConstantPool();
-        SDOperand CPIdx = DAG.getConstantPool(CP->getConstantPoolIndex(FudgeFactor),
-                                              TLI.getPointerTy());
-        CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
-        SDOperand FudgeInReg;
-        if (Node->getValueType(0) == MVT::f32)
-          FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
-                                   DAG.getSrcValue(NULL));
-        else {
-          assert(Node->getValueType(0) == MVT::f64 && "Unexpected conversion");
-          FudgeInReg = 
-            LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
-                                      DAG.getEntryNode(), CPIdx,
-                                      DAG.getSrcValue(NULL), MVT::f32));
+      if (Node->getOpcode() == ISD::UINT_TO_FP) {
+        switch (TLI.getOperationAction(Node->getOpcode(), 
+                                       Node->getOperand(0).getValueType())) {
+        default: assert(0 && "Unknown operation action!");
+        case TargetLowering::Expand:
+          Result = ExpandLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)),
+                                         Node->getValueType(0));
+          AddLegalizedOperand(Op, Result);
+          return Result;
+        case TargetLowering::Promote:
+          Result = PromoteLegalUINT_TO_FP(LegalizeOp(Node->getOperand(0)),
+                                          Node->getValueType(0));
+          AddLegalizedOperand(Op, Result);
+          return Result;
+        case TargetLowering::Legal:
+          break;
         }
-        Result = DAG.getNode(ISD::ADD, Node->getValueType(0), Tmp1, FudgeInReg);
-        break;
       }
       Tmp1 = LegalizeOp(Node->getOperand(0));
       if (Tmp1 != Node->getOperand(0))






More information about the llvm-commits mailing list