[llvm] [X86] Use ABI alignment for `BuildFILD`s store/reload stack slot (PR #215372)

Dennis Duda via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 24 13:47:17 PDT 2026


https://github.com/seritools updated https://github.com/llvm/llvm-project/pull/215372

>From 8b3aaf9f7050f1d1a28963dc7b1f63be133156fa Mon Sep 17 00:00:00 2001
From: Dennis Duda <git at seri.tools>
Date: Sun, 9 Aug 2026 00:07:27 +0200
Subject: [PATCH] [X86] Use ABI alignment for `BuildFILD`s store/reload stack
 slot

It's a private stack slot, ABI alignment is enough here. Prevents dynamic stack realignment on targets with 4-byte-aligned stack for `f64`s.

Co-authored-by: Claude (Claude-Opus-5) <noreply at anthropic.com>
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       | 11 ++++---
 llvm/test/CodeGen/X86/fp-intrinsics.ll        |  6 ++--
 .../CodeGen/X86/fp-strict-scalar-inttofp.ll   | 28 +++++-----------
 llvm/test/CodeGen/X86/scalar-int-to-fp.ll     | 32 +++++++------------
 .../CodeGen/X86/vec-strict-inttofp-128.ll     | 18 +++++------
 .../CodeGen/X86/vec-strict-inttofp-256.ll     |  6 ++--
 .../CodeGen/X86/vec-strict-inttofp-512.ll     |  6 ++--
 7 files changed, 45 insertions(+), 62 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index a0c92a22b7e2f..268794e55d510 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -20676,21 +20676,24 @@ std::pair<SDValue, SDValue> X86TargetLowering::BuildFILD(
   if (useSSE) {
     MachineFunction &MF = DAG.getMachineFunction();
     unsigned SSFISize = DstVT.getStoreSize();
-    int SSFI =
-        MF.getFrameInfo().CreateStackObject(SSFISize, Align(SSFISize), false);
+    // The slot is private, so ABI alignment is enough. More might realign the
+    // frame.
+    Align SlotAlign = DAG.getEVTAlign(DstVT);
+    int SSFI = MF.getFrameInfo().CreateStackObject(SSFISize, SlotAlign, false);
     auto PtrVT = getPointerTy(MF.getDataLayout());
     SDValue StackSlot = DAG.getFrameIndex(SSFI, PtrVT);
     Tys = DAG.getVTList(MVT::Other);
     SDValue FSTOps[] = {Chain, Result, StackSlot};
     MachineMemOperand *StoreMMO = DAG.getMachineFunction().getMachineMemOperand(
         MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI),
-        MachineMemOperand::MOStore, SSFISize, Align(SSFISize));
+        MachineMemOperand::MOStore, SSFISize, SlotAlign);
 
     Chain =
         DAG.getMemIntrinsicNode(X86ISD::FST, DL, Tys, FSTOps, DstVT, StoreMMO);
     Result = DAG.getLoad(
         DstVT, DL, Chain, StackSlot,
-        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI));
+        MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SSFI),
+        SlotAlign);
     Chain = Result.getValue(1);
   }
 
diff --git a/llvm/test/CodeGen/X86/fp-intrinsics.ll b/llvm/test/CodeGen/X86/fp-intrinsics.ll
index 5d69a217fb402..fd459be0d0ec1 100644
--- a/llvm/test/CodeGen/X86/fp-intrinsics.ll
+++ b/llvm/test/CodeGen/X86/fp-intrinsics.ll
@@ -2250,13 +2250,13 @@ define double @sifdl(i64 %x) #0 {
 ;
 ; X86-SSE-LABEL: sifdl:
 ; X86-SSE:       # %bb.0: # %entry
-; X86-SSE-NEXT:    subl $12, %esp
-; X86-SSE-NEXT:    .cfi_def_cfa_offset 16
+; X86-SSE-NEXT:    subl $8, %esp
+; X86-SSE-NEXT:    .cfi_def_cfa_offset 12
 ; X86-SSE-NEXT:    fildll {{[0-9]+}}(%esp)
 ; X86-SSE-NEXT:    fstpl (%esp)
 ; X86-SSE-NEXT:    fldl (%esp)
 ; X86-SSE-NEXT:    wait
-; X86-SSE-NEXT:    addl $12, %esp
+; X86-SSE-NEXT:    addl $8, %esp
 ; X86-SSE-NEXT:    .cfi_def_cfa_offset 4
 ; X86-SSE-NEXT:    retl
 ;
diff --git a/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll b/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
index f0aa3827ce937..1e7b4ef7b6285 100644
--- a/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
+++ b/llvm/test/CodeGen/X86/fp-strict-scalar-inttofp.ll
@@ -900,20 +900,14 @@ define double @sitofp_i32tof64(i32 %x) #0 {
 define double @sitofp_i64tof64(i64 %x) #0 {
 ; SSE-X86-LABEL: sitofp_i64tof64:
 ; SSE-X86:       # %bb.0:
-; SSE-X86-NEXT:    pushl %ebp
-; SSE-X86-NEXT:    .cfi_def_cfa_offset 8
-; SSE-X86-NEXT:    .cfi_offset %ebp, -8
-; SSE-X86-NEXT:    movl %esp, %ebp
-; SSE-X86-NEXT:    .cfi_def_cfa_register %ebp
-; SSE-X86-NEXT:    andl $-8, %esp
 ; SSE-X86-NEXT:    subl $8, %esp
-; SSE-X86-NEXT:    fildll 8(%ebp)
+; SSE-X86-NEXT:    .cfi_def_cfa_offset 12
+; SSE-X86-NEXT:    fildll {{[0-9]+}}(%esp)
 ; SSE-X86-NEXT:    fstpl (%esp)
 ; SSE-X86-NEXT:    fldl (%esp)
 ; SSE-X86-NEXT:    wait
-; SSE-X86-NEXT:    movl %ebp, %esp
-; SSE-X86-NEXT:    popl %ebp
-; SSE-X86-NEXT:    .cfi_def_cfa %esp, 4
+; SSE-X86-NEXT:    addl $8, %esp
+; SSE-X86-NEXT:    .cfi_def_cfa_offset 4
 ; SSE-X86-NEXT:    retl
 ;
 ; SSE-X64-LABEL: sitofp_i64tof64:
@@ -923,20 +917,14 @@ define double @sitofp_i64tof64(i64 %x) #0 {
 ;
 ; AVX-X86-LABEL: sitofp_i64tof64:
 ; AVX-X86:       # %bb.0:
-; AVX-X86-NEXT:    pushl %ebp
-; AVX-X86-NEXT:    .cfi_def_cfa_offset 8
-; AVX-X86-NEXT:    .cfi_offset %ebp, -8
-; AVX-X86-NEXT:    movl %esp, %ebp
-; AVX-X86-NEXT:    .cfi_def_cfa_register %ebp
-; AVX-X86-NEXT:    andl $-8, %esp
 ; AVX-X86-NEXT:    subl $8, %esp
-; AVX-X86-NEXT:    fildll 8(%ebp)
+; AVX-X86-NEXT:    .cfi_def_cfa_offset 12
+; AVX-X86-NEXT:    fildll {{[0-9]+}}(%esp)
 ; AVX-X86-NEXT:    fstpl (%esp)
 ; AVX-X86-NEXT:    fldl (%esp)
 ; AVX-X86-NEXT:    wait
-; AVX-X86-NEXT:    movl %ebp, %esp
-; AVX-X86-NEXT:    popl %ebp
-; AVX-X86-NEXT:    .cfi_def_cfa %esp, 4
+; AVX-X86-NEXT:    addl $8, %esp
+; AVX-X86-NEXT:    .cfi_def_cfa_offset 4
 ; AVX-X86-NEXT:    retl
 ;
 ; AVX-X64-LABEL: sitofp_i64tof64:
diff --git a/llvm/test/CodeGen/X86/scalar-int-to-fp.ll b/llvm/test/CodeGen/X86/scalar-int-to-fp.ll
index 43c1a84f7cd6c..3dd67ae0fb9c8 100644
--- a/llvm/test/CodeGen/X86/scalar-int-to-fp.ll
+++ b/llvm/test/CodeGen/X86/scalar-int-to-fp.ll
@@ -889,28 +889,20 @@ define double @s64_to_d(i64 %a) nounwind {
 ;
 ; AVX512F_32-LABEL: s64_to_d:
 ; AVX512F_32:       # %bb.0:
-; AVX512F_32-NEXT:    pushl %ebp
-; AVX512F_32-NEXT:    movl %esp, %ebp
-; AVX512F_32-NEXT:    andl $-8, %esp
 ; AVX512F_32-NEXT:    subl $8, %esp
-; AVX512F_32-NEXT:    fildll 8(%ebp)
+; AVX512F_32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; AVX512F_32-NEXT:    fstpl (%esp)
 ; AVX512F_32-NEXT:    fldl (%esp)
-; AVX512F_32-NEXT:    movl %ebp, %esp
-; AVX512F_32-NEXT:    popl %ebp
+; AVX512F_32-NEXT:    addl $8, %esp
 ; AVX512F_32-NEXT:    retl
 ;
 ; SSE2_32-LABEL: s64_to_d:
 ; SSE2_32:       # %bb.0:
-; SSE2_32-NEXT:    pushl %ebp
-; SSE2_32-NEXT:    movl %esp, %ebp
-; SSE2_32-NEXT:    andl $-8, %esp
 ; SSE2_32-NEXT:    subl $8, %esp
-; SSE2_32-NEXT:    fildll 8(%ebp)
+; SSE2_32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; SSE2_32-NEXT:    fstpl (%esp)
 ; SSE2_32-NEXT:    fldl (%esp)
-; SSE2_32-NEXT:    movl %ebp, %esp
-; SSE2_32-NEXT:    popl %ebp
+; SSE2_32-NEXT:    addl $8, %esp
 ; SSE2_32-NEXT:    retl
 ;
 ; SSE2_64-LABEL: s64_to_d:
@@ -990,10 +982,10 @@ define double @s64_to_d_2(i64 %a) nounwind {
 ; AVX512F_32-NEXT:    adcl $0, %ecx
 ; AVX512F_32-NEXT:    vmovd %eax, %xmm0
 ; AVX512F_32-NEXT:    vpinsrd $1, %ecx, %xmm0, %xmm0
-; AVX512F_32-NEXT:    vmovq %xmm0, {{[0-9]+}}(%esp)
-; AVX512F_32-NEXT:    fildll {{[0-9]+}}(%esp)
-; AVX512F_32-NEXT:    fstpl (%esp)
-; AVX512F_32-NEXT:    fldl (%esp)
+; AVX512F_32-NEXT:    vmovq %xmm0, (%esp)
+; AVX512F_32-NEXT:    fildll (%esp)
+; AVX512F_32-NEXT:    fstpl {{[0-9]+}}(%esp)
+; AVX512F_32-NEXT:    fldl {{[0-9]+}}(%esp)
 ; AVX512F_32-NEXT:    movl %ebp, %esp
 ; AVX512F_32-NEXT:    popl %ebp
 ; AVX512F_32-NEXT:    retl
@@ -1011,10 +1003,10 @@ define double @s64_to_d_2(i64 %a) nounwind {
 ; SSE2_32-NEXT:    movd %ecx, %xmm0
 ; SSE2_32-NEXT:    movd %eax, %xmm1
 ; SSE2_32-NEXT:    punpckldq {{.*#+}} xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
-; SSE2_32-NEXT:    movq %xmm1, {{[0-9]+}}(%esp)
-; SSE2_32-NEXT:    fildll {{[0-9]+}}(%esp)
-; SSE2_32-NEXT:    fstpl (%esp)
-; SSE2_32-NEXT:    fldl (%esp)
+; SSE2_32-NEXT:    movq %xmm1, (%esp)
+; SSE2_32-NEXT:    fildll (%esp)
+; SSE2_32-NEXT:    fstpl {{[0-9]+}}(%esp)
+; SSE2_32-NEXT:    fldl {{[0-9]+}}(%esp)
 ; SSE2_32-NEXT:    movl %ebp, %esp
 ; SSE2_32-NEXT:    popl %ebp
 ; SSE2_32-NEXT:    retl
diff --git a/llvm/test/CodeGen/X86/vec-strict-inttofp-128.ll b/llvm/test/CodeGen/X86/vec-strict-inttofp-128.ll
index cd4ceca6716b1..1d23d38bb6670 100644
--- a/llvm/test/CodeGen/X86/vec-strict-inttofp-128.ll
+++ b/llvm/test/CodeGen/X86/vec-strict-inttofp-128.ll
@@ -1149,11 +1149,11 @@ define <2 x double> @sitofp_v2i64_v2f64(<2 x i64> %x) #0 {
 ; SSE-32-NEXT:    subl $32, %esp
 ; SSE-32-NEXT:    movq %xmm0, {{[0-9]+}}(%esp)
 ; SSE-32-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
-; SSE-32-NEXT:    movq %xmm0, {{[0-9]+}}(%esp)
+; SSE-32-NEXT:    movq %xmm0, (%esp)
 ; SSE-32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; SSE-32-NEXT:    fstpl {{[0-9]+}}(%esp)
-; SSE-32-NEXT:    fildll {{[0-9]+}}(%esp)
-; SSE-32-NEXT:    fstpl (%esp)
+; SSE-32-NEXT:    fildll (%esp)
+; SSE-32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; SSE-32-NEXT:    wait
 ; SSE-32-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
 ; SSE-32-NEXT:    movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
@@ -1185,11 +1185,11 @@ define <2 x double> @sitofp_v2i64_v2f64(<2 x i64> %x) #0 {
 ; SSE41-32-NEXT:    subl $32, %esp
 ; SSE41-32-NEXT:    movq %xmm0, {{[0-9]+}}(%esp)
 ; SSE41-32-NEXT:    pshufd {{.*#+}} xmm0 = xmm0[2,3,2,3]
-; SSE41-32-NEXT:    movq %xmm0, {{[0-9]+}}(%esp)
+; SSE41-32-NEXT:    movq %xmm0, (%esp)
 ; SSE41-32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; SSE41-32-NEXT:    fstpl {{[0-9]+}}(%esp)
-; SSE41-32-NEXT:    fildll {{[0-9]+}}(%esp)
-; SSE41-32-NEXT:    fstpl (%esp)
+; SSE41-32-NEXT:    fildll (%esp)
+; SSE41-32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; SSE41-32-NEXT:    wait
 ; SSE41-32-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
 ; SSE41-32-NEXT:    movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
@@ -1221,11 +1221,11 @@ define <2 x double> @sitofp_v2i64_v2f64(<2 x i64> %x) #0 {
 ; AVX-32-NEXT:    subl $32, %esp
 ; AVX-32-NEXT:    vmovlps %xmm0, {{[0-9]+}}(%esp)
 ; AVX-32-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[2,3,2,3]
-; AVX-32-NEXT:    vmovlps %xmm0, {{[0-9]+}}(%esp)
+; AVX-32-NEXT:    vmovlps %xmm0, (%esp)
 ; AVX-32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; AVX-32-NEXT:    fstpl {{[0-9]+}}(%esp)
-; AVX-32-NEXT:    fildll {{[0-9]+}}(%esp)
-; AVX-32-NEXT:    fstpl (%esp)
+; AVX-32-NEXT:    fildll (%esp)
+; AVX-32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; AVX-32-NEXT:    wait
 ; AVX-32-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
 ; AVX-32-NEXT:    vmovhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
diff --git a/llvm/test/CodeGen/X86/vec-strict-inttofp-256.ll b/llvm/test/CodeGen/X86/vec-strict-inttofp-256.ll
index 7e446d5366387..fbc038165f031 100644
--- a/llvm/test/CodeGen/X86/vec-strict-inttofp-256.ll
+++ b/llvm/test/CodeGen/X86/vec-strict-inttofp-256.ll
@@ -646,15 +646,15 @@ define <4 x double> @sitofp_v4i64_v4f64(<4 x i64> %x) #0 {
 ; AVX-32-NEXT:    vextractf128 $1, %ymm0, %xmm0
 ; AVX-32-NEXT:    vmovlps %xmm0, {{[0-9]+}}(%esp)
 ; AVX-32-NEXT:    vshufps {{.*#+}} xmm0 = xmm0[2,3,2,3]
-; AVX-32-NEXT:    vmovlps %xmm0, {{[0-9]+}}(%esp)
+; AVX-32-NEXT:    vmovlps %xmm0, (%esp)
 ; AVX-32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; AVX-32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; AVX-32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; AVX-32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; AVX-32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; AVX-32-NEXT:    fstpl {{[0-9]+}}(%esp)
-; AVX-32-NEXT:    fildll {{[0-9]+}}(%esp)
-; AVX-32-NEXT:    fstpl (%esp)
+; AVX-32-NEXT:    fildll (%esp)
+; AVX-32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; AVX-32-NEXT:    wait
 ; AVX-32-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero
 ; AVX-32-NEXT:    vmovhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]
diff --git a/llvm/test/CodeGen/X86/vec-strict-inttofp-512.ll b/llvm/test/CodeGen/X86/vec-strict-inttofp-512.ll
index 59294dd17fbca..bf60f0631749d 100644
--- a/llvm/test/CodeGen/X86/vec-strict-inttofp-512.ll
+++ b/llvm/test/CodeGen/X86/vec-strict-inttofp-512.ll
@@ -278,7 +278,7 @@ define <8 x double> @sitofp_v8i64_v8f64(<8 x i64> %x) #0 {
 ; NODQ-32-NEXT:    vextractf32x4 $3, %zmm0, %xmm1
 ; NODQ-32-NEXT:    vmovlps %xmm1, {{[0-9]+}}(%esp)
 ; NODQ-32-NEXT:    vshufps {{.*#+}} xmm1 = xmm1[2,3,2,3]
-; NODQ-32-NEXT:    vmovlps %xmm1, {{[0-9]+}}(%esp)
+; NODQ-32-NEXT:    vmovlps %xmm1, (%esp)
 ; NODQ-32-NEXT:    vmovlps %xmm0, {{[0-9]+}}(%esp)
 ; NODQ-32-NEXT:    vshufps {{.*#+}} xmm1 = xmm0[2,3,2,3]
 ; NODQ-32-NEXT:    vmovlps %xmm1, {{[0-9]+}}(%esp)
@@ -292,8 +292,8 @@ define <8 x double> @sitofp_v8i64_v8f64(<8 x i64> %x) #0 {
 ; NODQ-32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; NODQ-32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; NODQ-32-NEXT:    fstpl {{[0-9]+}}(%esp)
-; NODQ-32-NEXT:    fildll {{[0-9]+}}(%esp)
-; NODQ-32-NEXT:    fstpl (%esp)
+; NODQ-32-NEXT:    fildll (%esp)
+; NODQ-32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; NODQ-32-NEXT:    fildll {{[0-9]+}}(%esp)
 ; NODQ-32-NEXT:    fstpl {{[0-9]+}}(%esp)
 ; NODQ-32-NEXT:    fildll {{[0-9]+}}(%esp)



More information about the llvm-commits mailing list