From 44b2c5098f5cf766b4eff43d9eb0d8a9a143e7d8 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 28 Apr 2007 06:42:38 +0000 Subject: [PATCH] memory inputs to an inline asm are required to have an address available. 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 | 4 +- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 50 ++++++++++++------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 99394c73a39..cc8cc61cb19 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -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); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 829dae50d1f..2cd925187c8 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -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(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(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; + } } - // 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 =