Skip to content

Commit 309d551

Browse files
nikictru
authored andcommitted
[AArch64][GlobalISel] Fix incorrect ABI when tail call not supported (#70215)
The check for whether a tail call is supported calls determineAssignments(), which may modify argument flags. As such, even though the check fails and a non-tail call will be emitted, it will not have a different (incorrect) ABI. Fix this by operating on a separate copy of the arguments. Fixes #70207. (cherry picked from commit 292f34b)
1 parent 9477268 commit 309d551

File tree

2 files changed

+12
-13
lines changed

2 files changed

+12
-13
lines changed

llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -829,9 +829,9 @@ bool AArch64CallLowering::doCallerAndCalleePassArgsTheSameWay(
829829

830830
bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable(
831831
CallLoweringInfo &Info, MachineFunction &MF,
832-
SmallVectorImpl<ArgInfo> &OutArgs) const {
832+
SmallVectorImpl<ArgInfo> &OrigOutArgs) const {
833833
// If there are no outgoing arguments, then we are done.
834-
if (OutArgs.empty())
834+
if (OrigOutArgs.empty())
835835
return true;
836836

837837
const Function &CallerF = MF.getFunction();
@@ -851,6 +851,9 @@ bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable(
851851

852852
AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg,
853853
Subtarget, /*IsReturn*/ false);
854+
// determineAssignments() may modify argument flags, so make a copy.
855+
SmallVector<ArgInfo, 8> OutArgs;
856+
append_range(OutArgs, OrigOutArgs);
854857
if (!determineAssignments(CalleeAssigner, OutArgs, OutInfo)) {
855858
LLVM_DEBUG(dbgs() << "... Could not analyze call operands.\n");
856859
return false;

llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-tail-call-fallback.ll

+7-11
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,26 @@
33

44
declare void @func(i64, i64, i64, i64, i64, i128, i128)
55

6-
; FIXME: This is a miscompile.
76
; Make sure the check for whether a tail call is allowed does not affect the
87
; calling convention if it fails.
98
; The first i128 argument should be passed in registers, not on the stack.
109
define void @pr70207(i128 %arg1, i128 %arg2) nounwind {
1110
; CHECK-LABEL: pr70207:
1211
; CHECK: // %bb.0:
13-
; CHECK-NEXT: sub sp, sp, #64
12+
; CHECK-NEXT: mov x8, x2
1413
; CHECK-NEXT: mov x6, x0
15-
; CHECK-NEXT: mov x8, x1
16-
; CHECK-NEXT: mov x9, x2
17-
; CHECK-NEXT: mov x10, x3
14+
; CHECK-NEXT: mov x7, x1
15+
; CHECK-NEXT: mov x9, x3
1816
; CHECK-NEXT: mov x0, xzr
1917
; CHECK-NEXT: mov x1, xzr
2018
; CHECK-NEXT: mov x2, xzr
2119
; CHECK-NEXT: mov x3, xzr
2220
; CHECK-NEXT: mov x4, xzr
23-
; CHECK-NEXT: str x30, [sp, #48] // 8-byte Folded Spill
24-
; CHECK-NEXT: str x8, [sp]
25-
; CHECK-NEXT: str x9, [sp, #16]
26-
; CHECK-NEXT: str x10, [sp, #32]
21+
; CHECK-NEXT: str x8, [sp, #-32]!
22+
; CHECK-NEXT: stp x9, x30, [sp, #8] // 8-byte Folded Spill
2723
; CHECK-NEXT: bl func
28-
; CHECK-NEXT: ldr x30, [sp, #48] // 8-byte Folded Reload
29-
; CHECK-NEXT: add sp, sp, #64
24+
; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload
25+
; CHECK-NEXT: add sp, sp, #32
3026
; CHECK-NEXT: ret
3127
tail call void @func(i64 0, i64 0, i64 0, i64 0, i64 0, i128 %arg1, i128 %arg2)
3228
ret void

0 commit comments

Comments
 (0)