memory inputs to an inline asm are required to have an address available.
authorChris Lattner <sabre@nondot.org>
Sat, 28 Apr 2007 06:42:38 +0000 (06:42 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 28 Apr 2007 06:42:38 +0000 (06:42 +0000)
If the operand is not already an indirect operand, spill it to a constant
pool entry or a stack slot.

This fixes PR1356 and CodeGen/X86/2007-04-27-InlineAsm-IntMemInput.ll

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36536 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 99394c73a39d3ed93c2d5e0a99a96e9465b0c4d4..cc8cc61cb19fbfade57627e340ea9f0b9955124e 100644 (file)
@@ -3123,11 +3123,11 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         // slots and always reusing the same one.  We currently always create
         // new ones, as reuse may inhibit scheduling.
         const Type *Ty = MVT::getTypeForValueType(ExtraVT);
-        unsigned TySize = (unsigned)TLI.getTargetData()->getTypeSize(Ty);
+        uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
         unsigned Align  = TLI.getTargetData()->getPrefTypeAlignment(Ty);
         MachineFunction &MF = DAG.getMachineFunction();
         int SSFI =
-          MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align);
+          MF.getFrameInfo()->CreateStackObject(TySize, Align);
         SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
         Result = DAG.getTruncStore(DAG.getEntryNode(), Node->getOperand(0),
                                    StackSlot, NULL, 0, ExtraVT);
index 829dae50d1f446925d8946f030a63fe3fab1f7ec..2cd925187c8108cf2f2b229b1c3ed1f71974e71f 100644 (file)
@@ -3397,6 +3397,9 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
         CTy = TLI.getConstraintType(ConstraintCode);
         
       if (CTy == TargetLowering::C_Other) {
+        assert(!Constraints[i].isIndirect && 
+               "Don't know how to handle indirect other inputs yet!");
+        
         InOperandVal = TLI.isOperandValidForConstraint(InOperandVal,
                                                        ConstraintCode[0], DAG);
         if (!InOperandVal.Val) {
@@ -3411,26 +3414,35 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
         AsmNodeOperands.push_back(InOperandVal);
         break;
       } else if (CTy == TargetLowering::C_Memory) {
-        // Memory input.
-        
-        // If the operand is a float, spill to a constant pool entry to get its
-        // address.
-        if (ConstantFP *Val = dyn_cast<ConstantFP>(I.getOperand(OpNum-1)))
-          InOperandVal = DAG.getConstantPool(Val, TLI.getPointerTy());
-        
-        if (!MVT::isInteger(InOperandVal.getValueType())) {
-          cerr << "Match failed, cannot handle this yet!\n";
-          InOperandVal.Val->dump();
-          exit(1);
+        // Memory input.  Memory operands really want the address of the value,
+        // so we want an indirect input.  If we don't have an indirect input,
+        // spill the value somewhere if we can, otherwise spill it to a stack
+        // slot.
+        if (!Constraints[i].isIndirect) {
+          // If the operand is a float, integer, or vector constant, spill to a
+          // constant pool entry to get its address.
+          Value *OpVal = I.getOperand(OpNum-1);
+          if (isa<ConstantFP>(OpVal) || isa<ConstantInt>(OpVal) ||
+              isa<ConstantVector>(OpVal)) {
+            InOperandVal = DAG.getConstantPool(cast<Constant>(OpVal),
+                                               TLI.getPointerTy());
+          } else {
+            // Otherwise, create a stack slot and emit a store to it before the
+            // asm.
+            const Type *Ty = OpVal->getType();
+            uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
+            unsigned Align  = TLI.getTargetData()->getPrefTypeAlignment(Ty);
+            MachineFunction &MF = DAG.getMachineFunction();
+            int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align);
+            SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
+            Chain = DAG.getStore(Chain, InOperandVal, StackSlot, NULL, 0);
+            InOperandVal = StackSlot;
+          }
         }
         
-        // Extend/truncate to the right pointer type if needed.
-        MVT::ValueType PtrType = TLI.getPointerTy();
-        if (InOperandVal.getValueType() < PtrType)
-          InOperandVal = DAG.getNode(ISD::ZERO_EXTEND, PtrType, InOperandVal);
-        else if (InOperandVal.getValueType() > PtrType)
-          InOperandVal = DAG.getNode(ISD::TRUNCATE, PtrType, InOperandVal);
-
+        assert(InOperandVal.getValueType() == TLI.getPointerTy() &&
+               "Memory operands expect pointer values");
+               
         // Add information to the INLINEASM node to know about this input.
         unsigned ResOpType = 4/*MEM*/ | (1 << 3);
         AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32));
@@ -3439,6 +3451,8 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
       }
         
       assert(CTy == TargetLowering::C_RegisterClass && "Unknown op type!");
+      assert(!Constraints[i].isIndirect && 
+             "Don't know how to handle indirect register inputs yet!");
 
       // Copy the input into the appropriate registers.
       RegsForValue InRegs =