[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelPattern.cpp

Chris Lattner lattner at cs.uiuc.edu
Fri Jul 29 17:06:05 PDT 2005



Changes in directory llvm/lib/Target/X86:

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

Use a custom expander for all FP to int conversions, as the X86 only has
FP-to-int-in-memory: this exposes the load from the stored slot to the 
selection dag, allowing it to be folded into other operaions.


---
Diffs of the changes:  (+41 -71)

 X86ISelPattern.cpp |  112 +++++++++++++++++++----------------------------------
 1 files changed, 41 insertions(+), 71 deletions(-)


Index: llvm/lib/Target/X86/X86ISelPattern.cpp
diff -u llvm/lib/Target/X86/X86ISelPattern.cpp:1.158 llvm/lib/Target/X86/X86ISelPattern.cpp:1.159
--- llvm/lib/Target/X86/X86ISelPattern.cpp:1.158	Thu Jul 28 20:00:29 2005
+++ llvm/lib/Target/X86/X86ISelPattern.cpp	Fri Jul 29 19:05:54 2005
@@ -59,6 +59,8 @@
       /// to the X86::FIST*m instructions and the rounding mode change stuff. It
       /// has two inputs (token chain and address) and two outputs (FP value and
       /// token chain).
+      FP_TO_INT16_IN_MEM,
+      FP_TO_INT32_IN_MEM,
       FP_TO_INT64_IN_MEM,
       
       /// CALL/TAILCALL - These operations represent an abstract X86 call
@@ -128,8 +130,10 @@
       if (!X86ScalarSSE) {
         // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64
         // isn't legal.
-        setOperationAction(ISD::SINT_TO_FP       , MVT::i64  , Custom);
-        setOperationAction(ISD::FP_TO_SINT       , MVT::i64  , Custom);
+        setOperationAction(ISD::SINT_TO_FP     , MVT::i64  , Custom);
+        setOperationAction(ISD::FP_TO_SINT     , MVT::i64  , Custom);
+        setOperationAction(ISD::FP_TO_SINT     , MVT::i32  , Custom);
+        setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Custom);
       }
       
       // Handle FP_TO_UINT by promoting the destination to a larger signed
@@ -987,24 +991,34 @@
     return DAG.getNode(X86ISD::FILD64m, RTs, Ops);
   }
   case ISD::FP_TO_SINT: {
-    assert(Op.getValueType() == MVT::i64 &&
+    assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 &&
            Op.getOperand(0).getValueType() == MVT::f64 &&
            "Unknown FP_TO_SINT to lower!");
     // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
     // stack slot.
     MachineFunction &MF = DAG.getMachineFunction();
-    int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
+    unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8;
+    int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
     SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
 
-    // Build the FISTP64
+    unsigned Opc;
+    switch (Op.getValueType()) {
+    default: assert(0 && "Invalid FP_TO_SINT to lower!");
+    case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break;
+    case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break;
+    case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break;
+    }
+    
+    // Build the FP_TO_INT*_IN_MEM
     std::vector<SDOperand> Ops;
     Ops.push_back(DAG.getEntryNode());
     Ops.push_back(Op.getOperand(0));
     Ops.push_back(StackSlot);
-    SDOperand FIST = DAG.getNode(X86ISD::FP_TO_INT64_IN_MEM, MVT::Other, Ops);
+    SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops);
     
     // Load the result.
-    return DAG.getLoad(MVT::i64, FIST, StackSlot, DAG.getSrcValue(NULL));
+    return DAG.getLoad(Op.getValueType(), FIST, StackSlot,
+                       DAG.getSrcValue(NULL));
   }
   }
 }
@@ -2449,76 +2463,23 @@
     }
     return Result;
   }
-  case ISD::FP_TO_SINT: {
+  case ISD::FP_TO_SINT:
     Tmp1 = SelectExpr(N.getOperand(0));  // Get the operand register
 
     // If the target supports SSE2 and is performing FP operations in SSE regs
     // instead of the FP stack, then we can use the efficient CVTSS2SI and
     // CVTSD2SI instructions.
-    if (X86ScalarSSE) {
-      if (MVT::f32 == N.getOperand(0).getValueType()) {
-        BuildMI(BB, X86::CVTTSS2SIrr, 1, Result).addReg(Tmp1);
-      } else if (MVT::f64 == N.getOperand(0).getValueType()) {
-        BuildMI(BB, X86::CVTTSD2SIrr, 1, Result).addReg(Tmp1);
-      } else {
-        assert(0 && "Not an f32 or f64?");
-        abort();
-      }
-      return Result;
-    }
-
-    // Change the floating point control register to use "round towards zero"
-    // mode when truncating to an integer value.
-    //
-    MachineFunction *F = BB->getParent();
-    int CWFrameIdx = F->getFrameInfo()->CreateStackObject(2, 2);
-    addFrameReference(BuildMI(BB, X86::FNSTCW16m, 4), CWFrameIdx);
-
-    // Load the old value of the high byte of the control word...
-    unsigned HighPartOfCW = MakeReg(MVT::i8);
-    addFrameReference(BuildMI(BB, X86::MOV8rm, 4, HighPartOfCW),
-                      CWFrameIdx, 1);
-
-    // Set the high part to be round to zero...
-    addFrameReference(BuildMI(BB, X86::MOV8mi, 5),
-                      CWFrameIdx, 1).addImm(12);
-
-    // Reload the modified control word now...
-    addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
-
-    // Restore the memory image of control word to original value
-    addFrameReference(BuildMI(BB, X86::MOV8mr, 5),
-                      CWFrameIdx, 1).addReg(HighPartOfCW);
-
-    // Spill the integer to memory and reload it from there.
-    unsigned Size = MVT::getSizeInBits(Node->getValueType(0))/8;
-    int FrameIdx = F->getFrameInfo()->CreateStackObject(Size, Size);
-
-    switch (Node->getValueType(0)) {
-    default: assert(0 && "Unsupported store class!");
-    case MVT::i16:
-      addFrameReference(BuildMI(BB, X86::FIST16m, 5), FrameIdx).addReg(Tmp1);
-      break;
-    case MVT::i32:
-      addFrameReference(BuildMI(BB, X86::FIST32m, 5), FrameIdx).addReg(Tmp1);
-      break;
-    }
-
-    switch (Node->getValueType(0)) {
-    default:
-      assert(0 && "Unknown integer type!");
-    case MVT::i32:
-      addFrameReference(BuildMI(BB, X86::MOV32rm, 4, Result), FrameIdx);
-      break;
-    case MVT::i16:
-      addFrameReference(BuildMI(BB, X86::MOV16rm, 4, Result), FrameIdx);
-      break;
+    assert(X86ScalarSSE);
+    if (MVT::f32 == N.getOperand(0).getValueType()) {
+      BuildMI(BB, X86::CVTTSS2SIrr, 1, Result).addReg(Tmp1);
+    } else if (MVT::f64 == N.getOperand(0).getValueType()) {
+      BuildMI(BB, X86::CVTTSD2SIrr, 1, Result).addReg(Tmp1);
+    } else {
+      assert(0 && "Not an f32 or f64?");
+      abort();
     }
-
-    // Reload the original control word now.
-    addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
     return Result;
-  }
+
   case ISD::ADD:
     Op0 = N.getOperand(0);
     Op1 = N.getOperand(1);
@@ -4347,6 +4308,8 @@
     SelectExpr(N.getValue(0));
     return;
     
+  case X86ISD::FP_TO_INT16_IN_MEM:
+  case X86ISD::FP_TO_INT32_IN_MEM:
   case X86ISD::FP_TO_INT64_IN_MEM: {
     assert(N.getOperand(1).getValueType() == MVT::f64);
     X86AddressMode AM;
@@ -4383,8 +4346,15 @@
     // Restore the memory image of control word to original value
     addFrameReference(BuildMI(BB, X86::MOV8mr, 5),
                       CWFrameIdx, 1).addReg(HighPartOfCW);
+
+    // Get the X86 opcode to use.
+    switch (N.getOpcode()) {
+    case X86ISD::FP_TO_INT16_IN_MEM: Tmp1 = X86::FIST16m; break;
+    case X86ISD::FP_TO_INT32_IN_MEM: Tmp1 = X86::FIST32m; break;
+    case X86ISD::FP_TO_INT64_IN_MEM: Tmp1 = X86::FISTP64m; break;
+    }
     
-    addFullAddress(BuildMI(BB, X86::FISTP64m, 5), AM).addReg(ValReg);
+    addFullAddress(BuildMI(BB, Tmp1, 5), AM).addReg(ValReg);
     
     // Reload the original control word now.
     addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);






More information about the llvm-commits mailing list