[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