diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index a2c6f0c3950..c1ed4a64283 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -1779,24 +1779,26 @@ ARMTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, RegsToPass[i].second.getValueType())); // Add a register mask operand representing the call-preserved registers. - const uint32_t *Mask; - const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo(); - const ARMBaseRegisterInfo *ARI = static_cast(TRI); - if (isThisReturn) { - // For 'this' returns, use the R0-preserving mask if applicable - Mask = ARI->getThisReturnPreservedMask(CallConv); - if (!Mask) { - // Set isThisReturn to false if the calling convention is not one that - // allows 'returned' to be modeled in this way, so LowerCallResult does - // not try to pass 'this' straight through - isThisReturn = false; + if (!isTailCall) { + const uint32_t *Mask; + const TargetRegisterInfo *TRI = getTargetMachine().getRegisterInfo(); + const ARMBaseRegisterInfo *ARI = static_cast(TRI); + if (isThisReturn) { + // For 'this' returns, use the R0-preserving mask if applicable + Mask = ARI->getThisReturnPreservedMask(CallConv); + if (!Mask) { + // Set isThisReturn to false if the calling convention is not one that + // allows 'returned' to be modeled in this way, so LowerCallResult does + // not try to pass 'this' straight through + isThisReturn = false; + Mask = ARI->getCallPreservedMask(CallConv); + } + } else Mask = ARI->getCallPreservedMask(CallConv); - } - } else - Mask = ARI->getCallPreservedMask(CallConv); - assert(Mask && "Missing call preserved mask for calling convention"); - Ops.push_back(DAG.getRegisterMask(Mask)); + assert(Mask && "Missing call preserved mask for calling convention"); + Ops.push_back(DAG.getRegisterMask(Mask)); + } if (InFlag.getNode()) Ops.push_back(InFlag); diff --git a/test/CodeGen/ARM/ifconv-regmask.ll b/test/CodeGen/ARM/ifconv-regmask.ll new file mode 100644 index 00000000000..d45f65f9567 --- /dev/null +++ b/test/CodeGen/ARM/ifconv-regmask.ll @@ -0,0 +1,35 @@ +; RUN: llc < %s -mtriple=thumbv7s-apple-ios6.0.0 -verify-machineinstrs + +%union.opcode = type { i32 } + +@opcode = external global %union.opcode, align 4 + +; Function Attrs: nounwind ssp +define i32 @sfu() { +entry: + %bf.load = load i32* getelementptr inbounds (%union.opcode* @opcode, i32 0, i32 0), align 4 + %bf.lshr = lshr i32 %bf.load, 26 + %bf.clear = and i32 %bf.lshr, 7 + switch i32 %bf.clear, label %return [ + i32 0, label %sw.bb + i32 1, label %sw.bb1 + ] + +sw.bb: ; preds = %entry + %call = tail call i32 @func0() + br label %return + +sw.bb1: ; preds = %entry + %call2 = tail call i32 @func1() + br label %return + +return: ; preds = %sw.bb1, %sw.bb, %entry + %retval.0 = phi i32 [ %call2, %sw.bb1 ], [ %call, %sw.bb ], [ -1, %entry ] + ret i32 %retval.0 +} + +; Function Attrs: nounwind ssp +declare i32 @func0() + +; Function Attrs: nounwind ssp +declare i32 @func1()