memory operands that have a direct operand should have their stores created
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
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 1066d6c..d2b7e44 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -3265,6 +3265,45 @@
// 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 @@
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 @@
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");