aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetLowering.h13
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp26
-rw-r--r--lib/Transforms/Scalar/CodeGenPrepare.cpp2
-rw-r--r--test/CodeGen/PowerPC/2007-04-24-InlineAsm-I-Modifier.ll7
-rw-r--r--test/CodeGen/X86/2008-04-26-Asm-Optimize-Imm.ll11
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
+}
+