diff options
author | Nikita Popov <npopov@redhat.com> | 2023-10-30 15:01:01 +0100 |
---|---|---|
committer | Tobias Hieta <tobias@hieta.se> | 2023-10-31 09:00:30 +0100 |
commit | 309d55140c46384b6de7a7573206cbeba3f7077f (patch) | |
tree | 237eea05c51c2e4dde10e9673da8d66d0b4f42eb | |
parent | 9477268e4247c7689b8252659151837f9e11b9d0 (diff) |
[AArch64][GlobalISel] Fix incorrect ABI when tail call not supported (#70215)llvmorg-17.0.4
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 https://github.com/llvm/llvm-project/issues/70207.
(cherry picked from commit 292f34b0d3cb2a04be5ebb85aaeb838b29f71323)
-rw-r--r-- | llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp | 7 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-tail-call-fallback.ll | 18 |
2 files changed, 12 insertions, 13 deletions
diff --git a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp index e78d8bb487a9..c56e3373d3a7 100644 --- a/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp +++ b/llvm/lib/Target/AArch64/GISel/AArch64CallLowering.cpp @@ -829,9 +829,9 @@ bool AArch64CallLowering::doCallerAndCalleePassArgsTheSameWay( bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable( CallLoweringInfo &Info, MachineFunction &MF, - SmallVectorImpl<ArgInfo> &OutArgs) const { + SmallVectorImpl<ArgInfo> &OrigOutArgs) const { // If there are no outgoing arguments, then we are done. - if (OutArgs.empty()) + if (OrigOutArgs.empty()) return true; const Function &CallerF = MF.getFunction(); @@ -851,6 +851,9 @@ bool AArch64CallLowering::areCalleeOutgoingArgsTailCallable( AArch64OutgoingValueAssigner CalleeAssigner(AssignFnFixed, AssignFnVarArg, Subtarget, /*IsReturn*/ false); + // determineAssignments() may modify argument flags, so make a copy. + SmallVector<ArgInfo, 8> OutArgs; + append_range(OutArgs, OrigOutArgs); if (!determineAssignments(CalleeAssigner, OutArgs, OutInfo)) { LLVM_DEBUG(dbgs() << "... Could not analyze call operands.\n"); return false; diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-tail-call-fallback.ll b/llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-tail-call-fallback.ll index fc6eefb4016b..ebd2beca6781 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-tail-call-fallback.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/call-lowering-tail-call-fallback.ll @@ -3,30 +3,26 @@ declare void @func(i64, i64, i64, i64, i64, i128, i128) -; FIXME: This is a miscompile. ; Make sure the check for whether a tail call is allowed does not affect the ; calling convention if it fails. ; The first i128 argument should be passed in registers, not on the stack. define void @pr70207(i128 %arg1, i128 %arg2) nounwind { ; CHECK-LABEL: pr70207: ; CHECK: // %bb.0: -; CHECK-NEXT: sub sp, sp, #64 +; CHECK-NEXT: mov x8, x2 ; CHECK-NEXT: mov x6, x0 -; CHECK-NEXT: mov x8, x1 -; CHECK-NEXT: mov x9, x2 -; CHECK-NEXT: mov x10, x3 +; CHECK-NEXT: mov x7, x1 +; CHECK-NEXT: mov x9, x3 ; CHECK-NEXT: mov x0, xzr ; CHECK-NEXT: mov x1, xzr ; CHECK-NEXT: mov x2, xzr ; CHECK-NEXT: mov x3, xzr ; CHECK-NEXT: mov x4, xzr -; CHECK-NEXT: str x30, [sp, #48] // 8-byte Folded Spill -; CHECK-NEXT: str x8, [sp] -; CHECK-NEXT: str x9, [sp, #16] -; CHECK-NEXT: str x10, [sp, #32] +; CHECK-NEXT: str x8, [sp, #-32]! +; CHECK-NEXT: stp x9, x30, [sp, #8] // 8-byte Folded Spill ; CHECK-NEXT: bl func -; CHECK-NEXT: ldr x30, [sp, #48] // 8-byte Folded Reload -; CHECK-NEXT: add sp, sp, #64 +; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload +; CHECK-NEXT: add sp, sp, #32 ; CHECK-NEXT: ret tail call void @func(i64 0, i64 0, i64 0, i64 0, i64 0, i128 %arg1, i128 %arg2) ret void |