[llvm-commits] [llvm] r57771 - in /llvm/trunk: lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp test/CodeGen/PowerPC/2008-10-17-AsmMatchingOperands.ll
Chris Lattner
sabre at nondot.org
Sat Oct 18 11:49:30 PDT 2008
Author: lattner
Date: Sat Oct 18 13:49:30 2008
New Revision: 57771
URL: http://llvm.org/viewvc/llvm-project?rev=57771&view=rev
Log:
Reapply r57699 with a fix to not crash on asms with multiple results. Unlike
the previous patch this one actually passes make check.
"Fix PR2356 on PowerPC: if we have an input and output that are tied together
that have different sizes (e.g. i32 and i64) make sure to reserve registers for
the bigger operand."
Added:
llvm/trunk/test/CodeGen/PowerPC/2008-10-17-AsmMatchingOperands.ll
Modified:
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp?rev=57771&r1=57770&r2=57771&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp Sat Oct 18 13:49:30 2008
@@ -4667,6 +4667,7 @@
OpInfo.CallOperandVal = CS.getArgument(ArgNo++);
break;
}
+
// The return value of the call is this value. As such, there is no
// corresponding argument.
assert(CS.getType() != Type::VoidTy && "Bad inline asm!");
@@ -4699,6 +4700,30 @@
}
OpInfo.ConstraintVT = OpVT;
+ }
+
+ // Second pass over the constraints: compute which constraint option to use
+ // and assign registers to constraints that want a specific physreg.
+ for (unsigned i = 0, e = ConstraintInfos.size(); i != e; ++i) {
+ SDISelAsmOperandInfo &OpInfo = ConstraintOperands[i];
+
+ // If this is an output operand with a matching input operand, look up the
+ // matching input. It might have a different type (e.g. the output might be
+ // i32 and the input i64) and we need to pick the larger width to ensure we
+ // reserve the right number of registers.
+ if (OpInfo.hasMatchingInput()) {
+ SDISelAsmOperandInfo &Input = ConstraintOperands[OpInfo.MatchingInput];
+ if (OpInfo.ConstraintVT != Input.ConstraintVT) {
+ assert(OpInfo.ConstraintVT.isInteger() &&
+ Input.ConstraintVT.isInteger() &&
+ "Asm constraints must be the same or different sized integers");
+ if (OpInfo.ConstraintVT.getSizeInBits() <
+ Input.ConstraintVT.getSizeInBits())
+ OpInfo.ConstraintVT = Input.ConstraintVT;
+ else
+ Input.ConstraintVT = OpInfo.ConstraintVT;
+ }
+ }
// Compute the constraint code and ConstraintType to use.
TLI.ComputeConstraintToUse(OpInfo, OpInfo.CallOperand, hasMemory, &DAG);
@@ -4948,22 +4973,28 @@
// and set it as the value of the call.
if (!RetValRegs.Regs.empty()) {
SDValue Val = RetValRegs.getCopyFromRegs(DAG, Chain, &Flag);
-
- // If any of the results of the inline asm is a vector, it may have the
- // wrong width/num elts. This can happen for register classes that can
- // contain multiple different value types. The preg or vreg allocated may
- // not have the same VT as was expected. Convert it to the right type with
- // bit_convert.
- if (const StructType *ResSTy = dyn_cast<StructType>(CS.getType())) {
- for (unsigned i = 0, e = ResSTy->getNumElements(); i != e; ++i) {
- if (Val.getNode()->getValueType(i).isVector())
- Val = DAG.getNode(ISD::BIT_CONVERT,
- TLI.getValueType(ResSTy->getElementType(i)), Val);
- }
- } else {
- if (Val.getValueType().isVector())
- Val = DAG.getNode(ISD::BIT_CONVERT, TLI.getValueType(CS.getType()),
- Val);
+
+ // FIXME: Why don't we do this for inline asms with MRVs?
+ if (CS.getType()->isSingleValueType() && CS.getType()->isSized()) {
+ MVT ResultType = TLI.getValueType(CS.getType());
+
+ // If any of the results of the inline asm is a vector, it may have the
+ // wrong width/num elts. This can happen for register classes that can
+ // contain multiple different value types. The preg or vreg allocated may
+ // not have the same VT as was expected. Convert it to the right type
+ // with bit_convert.
+ if (ResultType != Val.getValueType() && Val.getValueType().isVector()) {
+ Val = DAG.getNode(ISD::BIT_CONVERT, ResultType, Val);
+
+ } else if (ResultType != Val.getValueType() &&
+ ResultType.isInteger() && Val.getValueType().isInteger()) {
+ // If a result value was tied to an input value, the computed result may
+ // have a wider width than the expected result. Extract the relevant
+ // portion.
+ Val = DAG.getNode(ISD::TRUNCATE, ResultType, Val);
+ }
+
+ assert(ResultType == Val.getValueType() && "Asm result value mismatch!");
}
setValue(CS.getInstruction(), Val);
@@ -5219,7 +5250,8 @@
Value != NumValues; ++Value) {
MVT VT = ValueVTs[Value];
const Type *ArgTy = VT.getTypeForMVT();
- SDValue Op = SDValue(Args[i].Node.getNode(), Args[i].Node.getResNo() + Value);
+ SDValue Op = SDValue(Args[i].Node.getNode(),
+ Args[i].Node.getResNo() + Value);
ISD::ArgFlagsTy Flags;
unsigned OriginalAlignment =
getTargetData()->getABITypeAlignment(ArgTy);
Added: llvm/trunk/test/CodeGen/PowerPC/2008-10-17-AsmMatchingOperands.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/PowerPC/2008-10-17-AsmMatchingOperands.ll?rev=57771&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/PowerPC/2008-10-17-AsmMatchingOperands.ll (added)
+++ llvm/trunk/test/CodeGen/PowerPC/2008-10-17-AsmMatchingOperands.ll Sat Oct 18 13:49:30 2008
@@ -0,0 +1,10 @@
+; RUN: llvm-as < %s | llc
+; PR2356
+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-f128:64:128"
+target triple = "powerpc-apple-darwin9"
+
+define i32 @test(i64 %x, i32* %p) nounwind {
+ %asmtmp = call i32 asm "", "=r,0"(i64 0) nounwind ; <i32> [#uses=0]
+ %y = add i32 %asmtmp, 1
+ ret i32 %y
+}
More information about the llvm-commits
mailing list