diff options
| -rw-r--r-- | include/llvm/Target/TargetLowering.h | 13 | ||||
| -rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 | ||||
| -rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 26 | ||||
| -rw-r--r-- | lib/Transforms/Scalar/CodeGenPrepare.cpp | 2 | ||||
| -rw-r--r-- | test/CodeGen/PowerPC/2007-04-24-InlineAsm-I-Modifier.ll | 7 | ||||
| -rw-r--r-- | test/CodeGen/X86/2008-04-26-Asm-Optimize-Imm.ll | 11 |
6 files changed, 48 insertions, 13 deletions
diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index 559f038..9b4c8af 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -109,7 +109,8 @@ public: /// srl/add/sra. bool isPow2DivCheap() const { return Pow2DivIsCheap; } - /// getSetCCResultType - Return the ValueType of the result of setcc operations. + /// getSetCCResultType - Return the ValueType of the result of setcc + /// operations. virtual MVT::ValueType getSetCCResultType(const SDOperand &) const; /// getSetCCResultContents - For targets without boolean registers, this flag @@ -1080,8 +1081,12 @@ public: /// ComputeConstraintToUse - Determines the constraint code and constraint /// type to use for the specific AsmOperandInfo, setting - /// OpInfo.ConstraintCode and OpInfo.ConstraintType. - virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo) const; + /// OpInfo.ConstraintCode and OpInfo.ConstraintType. If the actual operand + /// being passed in is available, it can be passed in as Op, otherwise an + /// empty SDOperand can be passed. + virtual void ComputeConstraintToUse(AsmOperandInfo &OpInfo, + SDOperand Op, + SelectionDAG *DAG = 0) const; /// getConstraintType - Given a constraint, return the type of constraint it /// is for this target. @@ -1130,7 +1135,7 @@ public: // insert. The specified MachineInstr is created but not inserted into any // basic blocks, and the scheduler passes ownership of it to this method. virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, - MachineBasicBlock *MBB); + MachineBasicBlock *MBB); //===--------------------------------------------------------------------===// // Addressing mode description hooks (used by LSR etc). diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 7e8b614..b63470f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -3822,7 +3822,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { OpInfo.ConstraintVT = OpVT; // Compute the constraint code and ConstraintType to use. - TLI.ComputeConstraintToUse(OpInfo); + TLI.ComputeConstraintToUse(OpInfo, OpInfo.CallOperand, &DAG); // Keep track of whether we see an earlyclobber. SawEarlyClobber |= OpInfo.isEarlyClobber; diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index cd43349..dd9d96c 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1688,7 +1688,8 @@ static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) { /// 'm' over 'r', for example. /// static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, - const TargetLowering &TLI) { + const TargetLowering &TLI, + SDOperand Op, SelectionDAG *DAG) { assert(OpInfo.Codes.size() > 1 && "Doesn't have multiple constraint options"); unsigned BestIdx = 0; TargetLowering::ConstraintType BestType = TargetLowering::C_Unknown; @@ -1699,6 +1700,23 @@ static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, TargetLowering::ConstraintType CType = TLI.getConstraintType(OpInfo.Codes[i]); + // If this is an 'other' constraint, see if the operand is valid for it. + // For example, on X86 we might have an 'rI' constraint. If the operand + // is an integer in the range [0..31] we want to use I (saving a load + // of a register), otherwise we must use 'r'. + if (CType == TargetLowering::C_Other && Op.Val) { + assert(OpInfo.Codes[i].size() == 1 && + "Unhandled multi-letter 'other' constraint"); + std::vector<SDOperand> ResultOps; + TLI.LowerAsmOperandForConstraint(Op, OpInfo.Codes[i][0], + ResultOps, *DAG); + if (!ResultOps.empty()) { + BestType = CType; + BestIdx = i; + break; + } + } + // This constraint letter is more general than the previous one, use it. int Generality = getConstraintGenerality(CType); if (Generality > BestGenerality) { @@ -1715,7 +1733,9 @@ static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, /// ComputeConstraintToUse - Determines the constraint code and constraint /// type to use for the specific AsmOperandInfo, setting /// OpInfo.ConstraintCode and OpInfo.ConstraintType. -void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo) const { +void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo, + SDOperand Op, + SelectionDAG *DAG) const { assert(!OpInfo.Codes.empty() && "Must have at least one constraint"); // Single-letter constraints ('r') are very common. @@ -1723,7 +1743,7 @@ void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo) const { OpInfo.ConstraintCode = OpInfo.Codes[0]; OpInfo.ConstraintType = getConstraintType(OpInfo.ConstraintCode); } else { - ChooseConstraint(OpInfo, *this); + ChooseConstraint(OpInfo, *this, Op, DAG); } // 'X' matches anything. diff --git a/lib/Transforms/Scalar/CodeGenPrepare.cpp b/lib/Transforms/Scalar/CodeGenPrepare.cpp index cdabade..87c9374b 100644 --- a/lib/Transforms/Scalar/CodeGenPrepare.cpp +++ b/lib/Transforms/Scalar/CodeGenPrepare.cpp @@ -962,7 +962,7 @@ bool CodeGenPrepare::OptimizeInlineAsmInst(Instruction *I, CallSite CS, } // Compute the constraint code and ConstraintType to use. - TLI->ComputeConstraintToUse(OpInfo); + TLI->ComputeConstraintToUse(OpInfo, SDOperand()); if (OpInfo.ConstraintType == TargetLowering::C_Memory && OpInfo.isIndirect) { diff --git a/test/CodeGen/PowerPC/2007-04-24-InlineAsm-I-Modifier.ll b/test/CodeGen/PowerPC/2007-04-24-InlineAsm-I-Modifier.ll index 8405703..656b831 100644 --- a/test/CodeGen/PowerPC/2007-04-24-InlineAsm-I-Modifier.ll +++ b/test/CodeGen/PowerPC/2007-04-24-InlineAsm-I-Modifier.ll @@ -1,15 +1,14 @@ ; RUN: llvm-as < %s | llc -march=ppc32 -mtriple=powerpc-apple-darwin8.8.0 | grep {foo r3, r4} -; RUN: llvm-as < %s | llc -march=ppc32 -mtriple=powerpc-apple-darwin8.8.0 | grep {bar r3, r} +; RUN: llvm-as < %s | llc -march=ppc32 -mtriple=powerpc-apple-darwin8.8.0 | grep {bari r3, 47} ; PR1351 -define i32 @test1(i32 %Y, i32 %X) { +define i32 @test1(i32 %Y, i32 %X) nounwind { %tmp1 = tail call i32 asm "foo${1:I} $0, $1", "=r,rI"( i32 %X ) ret i32 %tmp1 } -;; TODO: We'd actually prefer this to be 'bari r3, 47', but 'bar r3, rN' is also ok. -define i32 @test2(i32 %Y, i32 %X) { +define i32 @test2(i32 %Y, i32 %X) nounwind { %tmp1 = tail call i32 asm "bar${1:I} $0, $1", "=r,rI"( i32 47 ) ret i32 %tmp1 } diff --git a/test/CodeGen/X86/2008-04-26-Asm-Optimize-Imm.ll b/test/CodeGen/X86/2008-04-26-Asm-Optimize-Imm.ll new file mode 100644 index 0000000..82721a5 --- /dev/null +++ b/test/CodeGen/X86/2008-04-26-Asm-Optimize-Imm.ll @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc | grep {1 \$2 3} +; rdar://5720231 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin8" + +define void @test() nounwind { +entry: + tail call void asm sideeffect " ${0:c} $1 ${2:c} ", "imr,imr,i,~{dirflag},~{fpsr},~{flags}"( i32 1, i32 2, i32 3 ) nounwind + ret void +} + |
