Skip to content

Commit 292f34b

Browse files
authored
[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.
1 parent 43a94cb commit 292f34b

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
@@ -832,9 +832,9 @@ bool AArch64CallLowering::doCallerAndCalleePassArgsTheSameWay(
832832

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

840840
const Function &CallerF = MF.getFunction();
@@ -854,6 +854,9 @@ bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable(
854854

855855
AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg,
856856
Subtarget, /*IsReturn*/ false);
857+
// determineAssignments() may modify argument flags, so make a copy.
858+
SmallVector<ArgInfo, 8> OutArgs;
859+
append_range(OutArgs, OrigOutArgs);
857860
if (!determineAssignments(CalleeAssigner, OutArgs, OutInfo)) {
858861
LLVM_DEBUG(dbgs() << "... Could not analyze call operands.\n");
859862
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)