[llvm] 1eb160f - [ARM] Fix tail call validity checking for varargs calls.
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Mon May 4 12:35:10 PDT 2020
Author: Eli Friedman
Date: 2020-05-04T12:34:14-07:00
New Revision: 1eb160fe8dc4c3359289853415730a73bfe4bb23
URL: https://github.com/llvm/llvm-project/commit/1eb160fe8dc4c3359289853415730a73bfe4bb23
DIFF: https://github.com/llvm/llvm-project/commit/1eb160fe8dc4c3359289853415730a73bfe4bb23.diff
LOG: [ARM] Fix tail call validity checking for varargs calls.
If a varargs function is calling a non-varargs function, or vice versa,
make sure we use the correct "varargs" bit for each.
Fixes https://bugs.llvm.org/show_bug.cgi?id=45234
Differential Revision: https://reviews.llvm.org/D79199
Added:
llvm/test/CodeGen/ARM/tail-call-results.ll
Modified:
llvm/lib/Target/ARM/ARMISelLowering.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index e6428f55d01f..3d6841ed7ce4 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -2663,9 +2663,11 @@ bool ARMTargetLowering::IsEligibleForTailCallOptimization(
// Check that the call results are passed in the same way.
LLVMContext &C = *DAG.getContext();
- if (!CCState::resultsCompatible(CalleeCC, CallerCC, MF, C, Ins,
- CCAssignFnForReturn(CalleeCC, isVarArg),
- CCAssignFnForReturn(CallerCC, isVarArg)))
+ if (!CCState::resultsCompatible(
+ getEffectiveCallingConv(CalleeCC, isVarArg),
+ getEffectiveCallingConv(CallerCC, CallerF.isVarArg()), MF, C, Ins,
+ CCAssignFnForReturn(CalleeCC, isVarArg),
+ CCAssignFnForReturn(CallerCC, CallerF.isVarArg())))
return false;
// The callee has to preserve all registers the caller needs to preserve.
const ARMBaseRegisterInfo *TRI = Subtarget->getRegisterInfo();
diff --git a/llvm/test/CodeGen/ARM/tail-call-results.ll b/llvm/test/CodeGen/ARM/tail-call-results.ll
new file mode 100644
index 000000000000..8b90e18f8010
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/tail-call-results.ll
@@ -0,0 +1,187 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=thumbv7-linux-gnueabihf %s -o - | FileCheck %s
+; RUN: llc -mtriple=thumbv7-linux-gnueabi %s -o - | FileCheck -check-prefix=SOFTFLOAT %s
+; RUN: llc -mtriple=thumbv7-linux-gnueabihf -disable-tail-calls %s -o - | FileCheck -check-prefix=HF-NOTAIL %s
+
+; On hard-float targets, the register used to store a float return value
+; changes if the call signature is varargs. The HF-NOTAIL lines are there to
+; easily see when this happens.
+
+declare float @callee_float()
+declare i32 @callee_int()
+declare float @callee_float_vararg(i32, ...)
+declare i32 @callee_int_vararg(i32, ...)
+
+define float @caller_float__callee_float() {
+; CHECK-LABEL: caller_float__callee_float:
+; CHECK: @ %bb.0:
+; CHECK-NEXT: b callee_float
+;
+; SOFTFLOAT-LABEL: caller_float__callee_float:
+; SOFTFLOAT: @ %bb.0:
+; SOFTFLOAT-NEXT: b callee_float
+;
+; HF-NOTAIL-LABEL: caller_float__callee_float:
+; HF-NOTAIL: @ %bb.0:
+; HF-NOTAIL-NEXT: .save {r7, lr}
+; HF-NOTAIL-NEXT: push {r7, lr}
+; HF-NOTAIL-NEXT: bl callee_float
+; HF-NOTAIL-NEXT: pop {r7, pc}
+ %r = tail call float @callee_float()
+ ret float %r
+}
+
+define float @caller_float__callee_float_vararg() {
+; CHECK-LABEL: caller_float__callee_float_vararg:
+; CHECK: @ %bb.0:
+; CHECK-NEXT: .save {r7, lr}
+; CHECK-NEXT: push {r7, lr}
+; CHECK-NEXT: movs r0, #0
+; CHECK-NEXT: bl callee_float_vararg
+; CHECK-NEXT: vmov s0, r0
+; CHECK-NEXT: pop {r7, pc}
+;
+; SOFTFLOAT-LABEL: caller_float__callee_float_vararg:
+; SOFTFLOAT: @ %bb.0:
+; SOFTFLOAT-NEXT: movs r0, #0
+; SOFTFLOAT-NEXT: b callee_float_vararg
+;
+; HF-NOTAIL-LABEL: caller_float__callee_float_vararg:
+; HF-NOTAIL: @ %bb.0:
+; HF-NOTAIL-NEXT: .save {r7, lr}
+; HF-NOTAIL-NEXT: push {r7, lr}
+; HF-NOTAIL-NEXT: movs r0, #0
+; HF-NOTAIL-NEXT: bl callee_float_vararg
+; HF-NOTAIL-NEXT: vmov s0, r0
+; HF-NOTAIL-NEXT: pop {r7, pc}
+ %r = tail call float (i32, ...) @callee_float_vararg(i32 0)
+ ret float %r
+}
+
+define float @caller_float_vararg__callee_float(i32, ...) {
+; CHECK-LABEL: caller_float_vararg__callee_float:
+; CHECK: @ %bb.0:
+; CHECK-NEXT: .save {r7, lr}
+; CHECK-NEXT: push {r7, lr}
+; CHECK-NEXT: bl callee_float
+; CHECK-NEXT: vmov r0, s0
+; CHECK-NEXT: pop {r7, pc}
+;
+; SOFTFLOAT-LABEL: caller_float_vararg__callee_float:
+; SOFTFLOAT: @ %bb.0:
+; SOFTFLOAT-NEXT: b callee_float
+;
+; HF-NOTAIL-LABEL: caller_float_vararg__callee_float:
+; HF-NOTAIL: @ %bb.0:
+; HF-NOTAIL-NEXT: .save {r7, lr}
+; HF-NOTAIL-NEXT: push {r7, lr}
+; HF-NOTAIL-NEXT: bl callee_float
+; HF-NOTAIL-NEXT: vmov r0, s0
+; HF-NOTAIL-NEXT: pop {r7, pc}
+ %r = tail call float @callee_float()
+ ret float %r
+}
+
+define float @caller_float_vararg__callee_float_vararg(i32, ...) {
+; CHECK-LABEL: caller_float_vararg__callee_float_vararg:
+; CHECK: @ %bb.0:
+; CHECK-NEXT: movs r0, #0
+; CHECK-NEXT: b callee_float_vararg
+;
+; SOFTFLOAT-LABEL: caller_float_vararg__callee_float_vararg:
+; SOFTFLOAT: @ %bb.0:
+; SOFTFLOAT-NEXT: movs r0, #0
+; SOFTFLOAT-NEXT: b callee_float_vararg
+;
+; HF-NOTAIL-LABEL: caller_float_vararg__callee_float_vararg:
+; HF-NOTAIL: @ %bb.0:
+; HF-NOTAIL-NEXT: .save {r7, lr}
+; HF-NOTAIL-NEXT: push {r7, lr}
+; HF-NOTAIL-NEXT: movs r0, #0
+; HF-NOTAIL-NEXT: bl callee_float_vararg
+; HF-NOTAIL-NEXT: pop {r7, pc}
+ %r = tail call float (i32, ...) @callee_float_vararg(i32 0)
+ ret float %r
+}
+
+define i32 @caller_int__callee_int() {
+; CHECK-LABEL: caller_int__callee_int:
+; CHECK: @ %bb.0:
+; CHECK-NEXT: b callee_int
+;
+; SOFTFLOAT-LABEL: caller_int__callee_int:
+; SOFTFLOAT: @ %bb.0:
+; SOFTFLOAT-NEXT: b callee_int
+;
+; HF-NOTAIL-LABEL: caller_int__callee_int:
+; HF-NOTAIL: @ %bb.0:
+; HF-NOTAIL-NEXT: .save {r7, lr}
+; HF-NOTAIL-NEXT: push {r7, lr}
+; HF-NOTAIL-NEXT: bl callee_int
+; HF-NOTAIL-NEXT: pop {r7, pc}
+ %r = tail call i32 @callee_int()
+ ret i32 %r
+}
+
+define i32 @caller_int__callee_int_vararg() {
+; CHECK-LABEL: caller_int__callee_int_vararg:
+; CHECK: @ %bb.0:
+; CHECK-NEXT: movs r0, #0
+; CHECK-NEXT: b callee_int_vararg
+;
+; SOFTFLOAT-LABEL: caller_int__callee_int_vararg:
+; SOFTFLOAT: @ %bb.0:
+; SOFTFLOAT-NEXT: movs r0, #0
+; SOFTFLOAT-NEXT: b callee_int_vararg
+;
+; HF-NOTAIL-LABEL: caller_int__callee_int_vararg:
+; HF-NOTAIL: @ %bb.0:
+; HF-NOTAIL-NEXT: .save {r7, lr}
+; HF-NOTAIL-NEXT: push {r7, lr}
+; HF-NOTAIL-NEXT: movs r0, #0
+; HF-NOTAIL-NEXT: bl callee_int_vararg
+; HF-NOTAIL-NEXT: pop {r7, pc}
+ %r = tail call i32 (i32, ...) @callee_int_vararg(i32 0)
+ ret i32 %r
+}
+
+define i32 @caller_int_vararg__callee_int(i32, ...) {
+; CHECK-LABEL: caller_int_vararg__callee_int:
+; CHECK: @ %bb.0:
+; CHECK-NEXT: b callee_int
+;
+; SOFTFLOAT-LABEL: caller_int_vararg__callee_int:
+; SOFTFLOAT: @ %bb.0:
+; SOFTFLOAT-NEXT: b callee_int
+;
+; HF-NOTAIL-LABEL: caller_int_vararg__callee_int:
+; HF-NOTAIL: @ %bb.0:
+; HF-NOTAIL-NEXT: .save {r7, lr}
+; HF-NOTAIL-NEXT: push {r7, lr}
+; HF-NOTAIL-NEXT: bl callee_int
+; HF-NOTAIL-NEXT: pop {r7, pc}
+ %r = tail call i32 @callee_int()
+ ret i32 %r
+}
+
+define i32 @caller_int_vararg__callee_int_vararg(i32, ...) {
+; CHECK-LABEL: caller_int_vararg__callee_int_vararg:
+; CHECK: @ %bb.0:
+; CHECK-NEXT: movs r0, #0
+; CHECK-NEXT: b callee_int_vararg
+;
+; SOFTFLOAT-LABEL: caller_int_vararg__callee_int_vararg:
+; SOFTFLOAT: @ %bb.0:
+; SOFTFLOAT-NEXT: movs r0, #0
+; SOFTFLOAT-NEXT: b callee_int_vararg
+;
+; HF-NOTAIL-LABEL: caller_int_vararg__callee_int_vararg:
+; HF-NOTAIL: @ %bb.0:
+; HF-NOTAIL-NEXT: .save {r7, lr}
+; HF-NOTAIL-NEXT: push {r7, lr}
+; HF-NOTAIL-NEXT: movs r0, #0
+; HF-NOTAIL-NEXT: bl callee_int_vararg
+; HF-NOTAIL-NEXT: pop {r7, pc}
+ %r = tail call i32 (i32, ...) @callee_int_vararg(i32 0)
+ ret i32 %r
+}
More information about the llvm-commits
mailing list