memory operands that have a direct operand should have their stores created
authorChris Lattner <sabre@nondot.org>
Sat, 28 Apr 2007 21:12:06 +0000 (21:12 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 28 Apr 2007 21:12:06 +0000 (21:12 +0000)
before the copies into physregs are done.  This avoids having flag operands
skip the store, causing cycles in the dag at sched time.  This fixes infinite
loops on these tests:

test/CodeGen/Generic/2007-04-08-MultipleFrameIndices.ll for PR1308
test/CodeGen/PowerPC/2007-01-29-lbrx-asm.ll
test/CodeGen/PowerPC/2007-01-31-InlineAsmAddrMode.ll
test/CodeGen/X86/2006-07-12-InlineAsmQConstraint.ll for PR828

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

lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 1066d6c7c99bdcf0eadfb51c51f6c1e5e971ddf2..d2b7e44e9f87fe2515807f57096f0c0fbdd0303d 100644 (file)
@@ -3265,6 +3265,45 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
     // FIXME: merge this into GetMostGeneralConstraint.
     OpInfo.ConstraintType = TLI.getConstraintType(OpInfo.ConstraintCode);
 
+    
+    // If this is a memory input, and if the operand is not indirect, do what we
+    // need to to provide an address for the memory input.
+    if (OpInfo.ConstraintType == TargetLowering::C_Memory &&
+        !OpInfo.isIndirect) {
+      assert(OpInfo.Type == InlineAsm::isInput &&
+             "Can only indirectify direct input operands!");
+      
+      // Memory operands really want the address of the value.  If we don't have
+      // an indirect input, put it in the constpool if we can, otherwise spill
+      // it to a stack slot.
+      
+      // If the operand is a float, integer, or vector constant, spill to a
+      // constant pool entry to get its address.
+      Value *OpVal = OpInfo.CallOperandVal;
+      if (isa<ConstantFP>(OpVal) || isa<ConstantInt>(OpVal) ||
+          isa<ConstantVector>(OpVal)) {
+        OpInfo.CallOperand = 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, OpInfo.CallOperand, StackSlot, NULL, 0);
+        OpInfo.CallOperand = StackSlot;
+      }
+     
+      // There is no longer a Value* corresponding to this operand.
+      OpInfo.CallOperandVal = 0;
+      // It is now an indirect operand.
+      OpInfo.isIndirect = true;
+    }
+    
+    
     if (TLI.getRegForInlineAsmConstraint(OpInfo.ConstraintCode, OpVT).first ==0)
       continue;  // Not assigned a fixed reg.
     
@@ -3323,19 +3362,12 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
       if (OpInfo.ConstraintType != TargetLowering::C_RegisterClass &&
           OpInfo.ConstraintType != TargetLowering::C_Register) {
         // Memory output, or 'other' output (e.g. 'X' constraint).
-        SDOperand InOperandVal = OpInfo.CallOperand;
-        
-        // Check that the operand (the address to store to) isn't a float.
-        if (!MVT::isInteger(InOperandVal.getValueType()))
-          assert(0 && "MATCH FAIL!");
-        
-        if (!OpInfo.isIndirect)
-          assert(0 && "MATCH FAIL!");
+        assert(OpInfo.isIndirect && "Memory output must be indirect operand");
 
         // Add information to the INLINEASM node to know about this output.
         unsigned ResOpType = 4/*MEM*/ | (1 << 3);
         AsmNodeOperands.push_back(DAG.getConstant(ResOpType, MVT::i32));
-        AsmNodeOperands.push_back(InOperandVal);
+        AsmNodeOperands.push_back(OpInfo.CallOperand);
         break;
       }
 
@@ -3440,32 +3472,7 @@ void SelectionDAGLowering::visitInlineAsm(CallInst &I) {
         AsmNodeOperands.push_back(InOperandVal);
         break;
       } else if (OpInfo.ConstraintType == TargetLowering::C_Memory) {
-        // 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 (!OpInfo.isIndirect) {
-          // If the operand is a float, integer, or vector constant, spill to a
-          // constant pool entry to get its address.
-          Value *OpVal = OpInfo.CallOperandVal;
-          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;
-          }
-        }
-        
+        assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
         assert(InOperandVal.getValueType() == TLI.getPointerTy() &&
                "Memory operands expect pointer values");