From 09e4b7e1b7d624a3010ace2c23783e77b366fa7e Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 28 Apr 2007 21:12:06 +0000 Subject: [PATCH] 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 --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 77 ++++++++++--------- 1 file changed, 42 insertions(+), 35 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 1066d6c7c99..d2b7e44e9f8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -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(OpVal) || isa(OpVal) || + isa(OpVal)) { + OpInfo.CallOperand = DAG.getConstantPool(cast(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(OpVal) || isa(OpVal) || - isa(OpVal)) { - InOperandVal = DAG.getConstantPool(cast(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"); -- 2.34.1