[CodeGen][ARM64EC] Copy first four arguments to FP registers in vararg exit thunks - #209581
Conversation
…g exit thunks ARM64EC vararg functions receive all types of the first four arguments in x0-x3. Because x86_64 expects floating-point arguments in FP registers, always copy x0-x3 to d0-d3 in the exit thunks, matching MSVC's behavior.
|
@llvm/pr-subscribers-backend-aarch64 Author: Jacek Caban (cjacek) ChangesARM64EC vararg functions receive all types of the first four arguments in x0-x3. Because x86_64 expects floating-point arguments in FP registers, always copy x0-x3 to d0-d3 in the exit thunks, matching MSVC's behavior. Full diff: https://github.com/llvm/llvm-project/pull/209581.diff 2 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index d6f2633297e51..abb62492342f8 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -10556,6 +10556,27 @@ AArch64TargetLowering::LowerCall(CallLoweringInfo &CLI,
const TargetOptions &Options = DAG.getTarget().Options;
if (Options.EmitCallSiteInfo)
CSInfo.ArgRegPairs.emplace_back(VA.getLocReg(), i);
+ if (IsArm64ECVarArgExitThunk) {
+ Register FPReg;
+ switch (VA.getLocReg()) {
+ case AArch64::X0:
+ FPReg = AArch64::D0;
+ break;
+ case AArch64::X1:
+ FPReg = AArch64::D1;
+ break;
+ case AArch64::X2:
+ FPReg = AArch64::D2;
+ break;
+ case AArch64::X3:
+ FPReg = AArch64::D3;
+ break;
+ }
+ if (FPReg) {
+ RegsToPass.emplace_back(FPReg, Arg);
+ RegsUsed.insert(FPReg);
+ }
+ }
}
} else {
assert(VA.isMemLoc());
diff --git a/llvm/test/CodeGen/AArch64/arm64ec-exit-thunks.ll b/llvm/test/CodeGen/AArch64/arm64ec-exit-thunks.ll
index 03ce3ca919a56..78b59cfa196d8 100644
--- a/llvm/test/CodeGen/AArch64/arm64ec-exit-thunks.ll
+++ b/llvm/test/CodeGen/AArch64/arm64ec-exit-thunks.ll
@@ -313,7 +313,11 @@ declare void @has_varargs(...) nounwind;
; CHECK-NEXT: mov x2, x5
; CHECK-NEXT: bl "#memcpy"
; CHECK-NEXT: sub sp, sp, #32
+; CHECK-NEXT: fmov d0, x22
+; CHECK-NEXT: fmov d1, x21
; CHECK-NEXT: mov x9, x26
+; CHECK-NEXT: fmov d2, x20
+; CHECK-NEXT: fmov d3, x19
; CHECK-NEXT: mov x0, x22
; CHECK-NEXT: mov x1, x21
; CHECK-NEXT: mov x2, x20
@@ -391,7 +395,11 @@ declare [2 x i8] @has_varargs_small_struct(...) nounwind;
; CHECK-NEXT: mov x2, x5
; CHECK-NEXT: bl "#memcpy"
; CHECK-NEXT: sub sp, sp, #32
+; CHECK-NEXT: fmov d0, x22
+; CHECK-NEXT: fmov d1, x21
; CHECK-NEXT: mov x9, x26
+; CHECK-NEXT: fmov d2, x20
+; CHECK-NEXT: fmov d3, x19
; CHECK-NEXT: mov x0, x22
; CHECK-NEXT: mov x1, x21
; CHECK-NEXT: mov x2, x20
@@ -566,7 +574,11 @@ declare void @has_varargs_sret(ptr sret([100 x i8]), ...) nounwind;
; CHECK-NEXT: mov x2, x4
; CHECK-NEXT: bl "#memcpy"
; CHECK-NEXT: sub sp, sp, #32
+; CHECK-NEXT: fmov d0, x22
+; CHECK-NEXT: fmov d1, x21
; CHECK-NEXT: mov x9, x26
+; CHECK-NEXT: fmov d2, x20
+; CHECK-NEXT: fmov d3, x19
; CHECK-NEXT: mov x0, x22
; CHECK-NEXT: mov x1, x21
; CHECK-NEXT: mov x2, x20
|
🐧 Linux x64 Test Results
Failed Tests(click on a test name to see its output) lldb-apilldb-api.tools/lldb-dap/breakpoint/TestDAP_logpoints.pyIf these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the |
efriedma-quic
left a comment
There was a problem hiding this comment.
The x64 ABI spec says "For floating-point values only, both the integer register and the floating-point register must contain the value", but I guess we can't tell if a value is a floating-point value at this point because we've already moved everything into integer registers.
I'm not sure anything actually uses the values from the FP registers in practice, but I guess matching MSVC is a good enough excuse.
LGTM
|
Merged, thanks! |
|
I presume this is relevant to backport to 23.x? |
|
/cherry-pick 9c6a9f5 EDIT: Trying to retrigger the backport. |
Yes, it probably makes sense to ship together with the rest of vararg thunks fixes. |
|
/pull-request #210315 |
…g exit thunks (llvm#209581) ARM64EC vararg functions receive all types of the first four arguments in x0-x3. Because x86_64 expects floating-point arguments in FP registers, always copy x0-x3 to d0-d3 in the exit thunks, matching MSVC's behavior. (cherry picked from commit 9c6a9f5)
ARM64EC vararg functions receive all types of the first four arguments in x0-x3. Because x86_64 expects floating-point arguments in FP registers, always copy x0-x3 to d0-d3 in the exit thunks, matching MSVC's behavior.