Skip to content

[PowerPC][AIX] Specify pointer info and alignment for stack store #144526

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Jun 17, 2025

When lowering call arguments to stack, specify a stack MPI, as well as the stack alignment, instead of using the defaults (which would be an unknown location with ABI alignment).

I believe the asm diffs are just changes in scheduling.

When lowering call arguments to stack, specify a stack MPI, as well
as the stack alignment, instead of using the defaults (which would
be an unknown location with ABI alignment).
@nikic
Copy link
Contributor Author

nikic commented Jun 17, 2025

Context is that I tried to implement #133599, but this resulted in changes in call lowering that really shouldn't be influenced by the data layout.

@arsenm @efriedma-quic One thing I'm confused about is that this does not seem to be common practice -- while MachinePointerInfo::getStack() sees the occasional use, I couldn't find any code that actually specifies the base alignment for it. I'm probably missing something here.

@llvmbot
Copy link
Member

llvmbot commented Jun 17, 2025

@llvm/pr-subscribers-backend-powerpc

Author: Nikita Popov (nikic)

Changes

When lowering call arguments to stack, specify a stack MPI, as well as the stack alignment, instead of using the defaults (which would be an unknown location with ABI alignment).

I believe the asm diffs are just changes in scheduling.


Patch is 77.56 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/144526.diff

8 Files Affected:

  • (modified) llvm/lib/Target/PowerPC/PPCISelLowering.cpp (+3-1)
  • (modified) llvm/test/CodeGen/PowerPC/aix-cc-abi-mir.ll (+189-177)
  • (modified) llvm/test/CodeGen/PowerPC/aix-cc-abi.ll (+94-82)
  • (modified) llvm/test/CodeGen/PowerPC/aix-cc-byval-mir.ll (+2-2)
  • (modified) llvm/test/CodeGen/PowerPC/aix-vec-arg-spills-mir.ll (+17-17)
  • (modified) llvm/test/CodeGen/PowerPC/aix-vec-arg-spills.ll (+19-19)
  • (modified) llvm/test/CodeGen/PowerPC/aix-vector-vararg-caller.ll (+13-13)
  • (modified) llvm/test/CodeGen/PowerPC/aix-vector-vararg-fixed-caller.ll (+4-4)
diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
index 0f8e5e57c58b7..f502d8570425a 100644
--- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
+++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp
@@ -7767,7 +7767,9 @@ SDValue PPCTargetLowering::LowerCall_AIX(
           DAG.getConstant(VA.getLocMemOffset(), dl, StackPtr.getValueType());
       PtrOff = DAG.getNode(ISD::ADD, dl, PtrVT, StackPtr, PtrOff);
       MemOpChains.push_back(
-          DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo()));
+          DAG.getStore(Chain, dl, Arg, PtrOff,
+                       MachinePointerInfo::getStack(MF, VA.getLocMemOffset()),
+                       Subtarget.getFrameLowering()->getStackAlign()));
 
       continue;
     }
diff --git a/llvm/test/CodeGen/PowerPC/aix-cc-abi-mir.ll b/llvm/test/CodeGen/PowerPC/aix-cc-abi-mir.ll
index aead5762d0921..9ffb4fd5eae45 100644
--- a/llvm/test/CodeGen/PowerPC/aix-cc-abi-mir.ll
+++ b/llvm/test/CodeGen/PowerPC/aix-cc-abi-mir.ll
@@ -474,14 +474,14 @@ define void @call_test_fpr_max() {
   ; 32BIT-NEXT:   renamable $r3 = LWZtoc @d1, $r2 :: (load (s32) from got)
   ; 32BIT-NEXT:   renamable $f1 = LFD 0, killed renamable $r3 :: (dereferenceable load (s64) from @d1)
   ; 32BIT-NEXT:   ADJCALLSTACKDOWN 128, 0, implicit-def dead $r1, implicit $r1
-  ; 32BIT-NEXT:   STFD renamable $f1, 120, $r1 :: (store (s64))
-  ; 32BIT-NEXT:   STFD renamable $f1, 112, $r1 :: (store (s64))
-  ; 32BIT-NEXT:   STFD renamable $f1, 104, $r1 :: (store (s64))
-  ; 32BIT-NEXT:   STFD renamable $f1, 96, $r1 :: (store (s64))
-  ; 32BIT-NEXT:   STFD renamable $f1, 88, $r1 :: (store (s64))
-  ; 32BIT-NEXT:   STFD renamable $f1, 80, $r1 :: (store (s64))
-  ; 32BIT-NEXT:   STFD renamable $f1, 72, $r1 :: (store (s64))
-  ; 32BIT-NEXT:   STFD renamable $f1, 64, $r1 :: (store (s64))
+  ; 32BIT-NEXT:   STFD renamable $f1, 120, $r1 :: (store (s64) into stack + 120, basealign 16)
+  ; 32BIT-NEXT:   STFD renamable $f1, 112, $r1 :: (store (s64) into stack + 112, align 16)
+  ; 32BIT-NEXT:   STFD renamable $f1, 104, $r1 :: (store (s64) into stack + 104, basealign 16)
+  ; 32BIT-NEXT:   STFD renamable $f1, 96, $r1 :: (store (s64) into stack + 96, align 16)
+  ; 32BIT-NEXT:   STFD renamable $f1, 88, $r1 :: (store (s64) into stack + 88, basealign 16)
+  ; 32BIT-NEXT:   STFD renamable $f1, 80, $r1 :: (store (s64) into stack + 80, align 16)
+  ; 32BIT-NEXT:   STFD renamable $f1, 72, $r1 :: (store (s64) into stack + 72, basealign 16)
+  ; 32BIT-NEXT:   STFD renamable $f1, 64, $r1 :: (store (s64) into stack + 64, align 16)
   ; 32BIT-NEXT:   $f2 = COPY renamable $f1
   ; 32BIT-NEXT:   $f3 = COPY renamable $f1
   ; 32BIT-NEXT:   $f4 = COPY renamable $f1
@@ -494,7 +494,7 @@ define void @call_test_fpr_max() {
   ; 32BIT-NEXT:   $f11 = COPY renamable $f1
   ; 32BIT-NEXT:   $f12 = COPY renamable $f1
   ; 32BIT-NEXT:   $f13 = COPY renamable $f1
-  ; 32BIT-NEXT:   STFD renamable $f1, 56, $r1 :: (store (s64))
+  ; 32BIT-NEXT:   STFD renamable $f1, 56, $r1 :: (store (s64) into stack + 56, basealign 16)
   ; 32BIT-NEXT:   BL_NOP <mcsymbol .test_fpr_max>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $f1, implicit killed $f2, implicit killed $f3, implicit killed $f4, implicit killed $f5, implicit killed $f6, implicit killed $f7, implicit killed $f8, implicit killed $f9, implicit killed $f10, implicit killed $f11, implicit killed $f12, implicit killed $f13, implicit $r2, implicit-def $r1, implicit-def dead $f1
   ; 32BIT-NEXT:   ADJCALLSTACKUP 128, 0, implicit-def dead $r1, implicit $r1
   ; 32BIT-NEXT:   BLR implicit $lr, implicit $rm
@@ -504,10 +504,10 @@ define void @call_test_fpr_max() {
   ; 64BIT-NEXT:   renamable $x3 = LDtoc @d1, $x2 :: (load (s64) from got)
   ; 64BIT-NEXT:   renamable $f1 = LFD 0, killed renamable $x3 :: (dereferenceable load (s64) from @d1)
   ; 64BIT-NEXT:   ADJCALLSTACKDOWN 152, 0, implicit-def dead $r1, implicit $r1
-  ; 64BIT-NEXT:   STFD renamable $f1, 144, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STFD renamable $f1, 136, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STFD renamable $f1, 128, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STFD renamable $f1, 120, $x1 :: (store (s64))
+  ; 64BIT-NEXT:   STFD renamable $f1, 144, $x1 :: (store (s64) into stack + 144, align 16)
+  ; 64BIT-NEXT:   STFD renamable $f1, 136, $x1 :: (store (s64) into stack + 136, basealign 16)
+  ; 64BIT-NEXT:   STFD renamable $f1, 128, $x1 :: (store (s64) into stack + 128, align 16)
+  ; 64BIT-NEXT:   STFD renamable $f1, 120, $x1 :: (store (s64) into stack + 120, basealign 16)
   ; 64BIT-NEXT:   $f2 = COPY renamable $f1
   ; 64BIT-NEXT:   $f3 = COPY renamable $f1
   ; 64BIT-NEXT:   $f4 = COPY renamable $f1
@@ -520,7 +520,7 @@ define void @call_test_fpr_max() {
   ; 64BIT-NEXT:   $f11 = COPY renamable $f1
   ; 64BIT-NEXT:   $f12 = COPY renamable $f1
   ; 64BIT-NEXT:   $f13 = COPY renamable $f1
-  ; 64BIT-NEXT:   STFD renamable $f1, 112, $x1 :: (store (s64))
+  ; 64BIT-NEXT:   STFD renamable $f1, 112, $x1 :: (store (s64) into stack + 112, align 16)
   ; 64BIT-NEXT:   BL8_NOP <mcsymbol .test_fpr_max>, csr_ppc64, implicit-def dead $lr8, implicit $rm, implicit $f1, implicit killed $f2, implicit killed $f3, implicit killed $f4, implicit killed $f5, implicit killed $f6, implicit killed $f7, implicit killed $f8, implicit killed $f9, implicit killed $f10, implicit killed $f11, implicit killed $f12, implicit killed $f13, implicit $x2, implicit-def $r1, implicit-def dead $f1
   ; 64BIT-NEXT:   ADJCALLSTACKUP 152, 0, implicit-def dead $r1, implicit $r1
   ; 64BIT-NEXT:   BLR8 implicit $lr8, implicit $rm
@@ -889,11 +889,11 @@ define void @call_test_stackarg_int() {
   ; 32BIT-NEXT:   renamable $r6 = LWZ 0, renamable $r3 :: (dereferenceable load (s32) from @lli, align 8)
   ; 32BIT-NEXT:   renamable $r3 = LWZ 4, killed renamable $r3 :: (dereferenceable load (s32) from @lli + 4, basealign 8)
   ; 32BIT-NEXT:   ADJCALLSTACKDOWN 80, 0, implicit-def dead $r1, implicit $r1
-  ; 32BIT-NEXT:   STW renamable $r5, 76, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r3, 72, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r6, 68, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r5, 64, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r4, 60, $r1 :: (store (s32))
+  ; 32BIT-NEXT:   STW renamable $r5, 76, $r1 :: (store (s32) into stack + 76, basealign 16)
+  ; 32BIT-NEXT:   STW killed renamable $r3, 72, $r1 :: (store (s32) into stack + 72, align 8, basealign 16)
+  ; 32BIT-NEXT:   STW killed renamable $r6, 68, $r1 :: (store (s32) into stack + 68, basealign 16)
+  ; 32BIT-NEXT:   STW killed renamable $r5, 64, $r1 :: (store (s32) into stack + 64, align 16)
+  ; 32BIT-NEXT:   STW killed renamable $r4, 60, $r1 :: (store (s32) into stack + 60, basealign 16)
   ; 32BIT-NEXT:   $r3 = LI 1
   ; 32BIT-NEXT:   $r4 = LI 2
   ; 32BIT-NEXT:   $r5 = LI 3
@@ -902,7 +902,7 @@ define void @call_test_stackarg_int() {
   ; 32BIT-NEXT:   $r8 = LI 6
   ; 32BIT-NEXT:   $r9 = LI 7
   ; 32BIT-NEXT:   $r10 = LI 8
-  ; 32BIT-NEXT:   STW killed renamable $r11, 56, $r1 :: (store (s32))
+  ; 32BIT-NEXT:   STW killed renamable $r11, 56, $r1 :: (store (s32) into stack + 56, align 8, basealign 16)
   ; 32BIT-NEXT:   BL_NOP <mcsymbol .test_stackarg_int[PR]>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit $r5, implicit $r6, implicit $r7, implicit $r8, implicit $r9, implicit $r10, implicit $r2, implicit-def $r1
   ; 32BIT-NEXT:   ADJCALLSTACKUP 80, 0, implicit-def dead $r1, implicit $r1
   ; 32BIT-NEXT:   BLR implicit $lr, implicit $rm
@@ -926,11 +926,11 @@ define void @call_test_stackarg_int() {
   ; 64BIT-NEXT:   $x8 = LI8 6
   ; 64BIT-NEXT:   $x9 = LI8 7
   ; 64BIT-NEXT:   $x10 = LI8 8
-  ; 64BIT-NEXT:   STD killed renamable $x31, 136, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD renamable $x0, 144, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD killed renamable $x0, 128, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD killed renamable $x12, 120, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD killed renamable $x11, 112, $x1 :: (store (s64))
+  ; 64BIT-NEXT:   STD killed renamable $x31, 136, $x1 :: (store (s64) into stack + 136, basealign 16)
+  ; 64BIT-NEXT:   STD renamable $x0, 144, $x1 :: (store (s64) into stack + 144, align 16)
+  ; 64BIT-NEXT:   STD killed renamable $x0, 128, $x1 :: (store (s64) into stack + 128, align 16)
+  ; 64BIT-NEXT:   STD killed renamable $x12, 120, $x1 :: (store (s64) into stack + 120, basealign 16)
+  ; 64BIT-NEXT:   STD killed renamable $x11, 112, $x1 :: (store (s64) into stack + 112, align 16)
   ; 64BIT-NEXT:   BL8_NOP <mcsymbol .test_stackarg_int[PR]>, csr_ppc64, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit $x4, implicit $x5, implicit $x6, implicit $x7, implicit $x8, implicit $x9, implicit $x10, implicit $x2, implicit-def $r1
   ; 64BIT-NEXT:   ADJCALLSTACKUP 152, 0, implicit-def dead $r1, implicit $r1
   ; 64BIT-NEXT:   BLR8 implicit $lr8, implicit $rm
@@ -956,7 +956,11 @@ define void @call_test_stackarg_float() {
   ; 32BIT-NEXT:   renamable $f1 = LFS 0, killed renamable $r3 :: (dereferenceable load (s32) from @f)
   ; 32BIT-NEXT:   renamable $f2 = LFD 0, killed renamable $r4 :: (dereferenceable load (s64) from @d)
   ; 32BIT-NEXT:   ADJCALLSTACKDOWN 68, 0, implicit-def dead $r1, implicit $r1
-  ; 32BIT-NEXT:   STFD renamable $f2, 60, $r1 :: (store (s64))
+  ; 32BIT-NEXT:   STFD renamable $f2, 0, %stack.0 :: (store (s64) into %stack.0)
+  ; 32BIT-NEXT:   STFS renamable $f1, 56, $r1 :: (store (s32) into stack + 56, align 8, basealign 16)
+  ; 32BIT-NEXT:   renamable $r3 = LWZ 4, %stack.0 :: (load (s32) from %stack.0 + 4)
+  ; 32BIT-NEXT:   STW killed renamable $r3, 64, $r1 :: (store (s32) into stack + 64, align 16)
+  ; 32BIT-NEXT:   renamable $r11 = LWZ 0, %stack.0 :: (load (s32) from %stack.0, align 8)
   ; 32BIT-NEXT:   $r3 = LI 1
   ; 32BIT-NEXT:   $r4 = LI 2
   ; 32BIT-NEXT:   $r5 = LI 3
@@ -965,8 +969,8 @@ define void @call_test_stackarg_float() {
   ; 32BIT-NEXT:   $r8 = LI 6
   ; 32BIT-NEXT:   $r9 = LI 7
   ; 32BIT-NEXT:   $r10 = LI 8
-  ; 32BIT-NEXT:   STFS renamable $f1, 56, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   BL_NOP <mcsymbol .test_stackarg_float[PR]>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit killed $r5, implicit killed $r6, implicit killed $r7, implicit killed $r8, implicit killed $r9, implicit killed $r10, implicit $f1, implicit $f2, implicit $r2, implicit-def $r1
+  ; 32BIT-NEXT:   STW killed renamable $r11, 60, $r1 :: (store (s32) into stack + 60, basealign 16)
+  ; 32BIT-NEXT:   BL_NOP <mcsymbol .test_stackarg_float[PR]>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit $r5, implicit $r6, implicit $r7, implicit $r8, implicit $r9, implicit $r10, implicit $f1, implicit $f2, implicit $r2, implicit-def $r1
   ; 32BIT-NEXT:   ADJCALLSTACKUP 68, 0, implicit-def dead $r1, implicit $r1
   ; 32BIT-NEXT:   BLR implicit $lr, implicit $rm
   ;
@@ -977,7 +981,7 @@ define void @call_test_stackarg_float() {
   ; 64BIT-NEXT:   renamable $f1 = LFS 0, killed renamable $x3 :: (dereferenceable load (s32) from @f)
   ; 64BIT-NEXT:   renamable $f2 = LFD 0, killed renamable $x4 :: (dereferenceable load (s64) from @d)
   ; 64BIT-NEXT:   ADJCALLSTACKDOWN 128, 0, implicit-def dead $r1, implicit $r1
-  ; 64BIT-NEXT:   STFD renamable $f2, 120, $x1 :: (store (s64))
+  ; 64BIT-NEXT:   STFD renamable $f2, 120, $x1 :: (store (s64) into stack + 120, basealign 16)
   ; 64BIT-NEXT:   $x3 = LI8 1
   ; 64BIT-NEXT:   $x4 = LI8 2
   ; 64BIT-NEXT:   $x5 = LI8 3
@@ -986,7 +990,7 @@ define void @call_test_stackarg_float() {
   ; 64BIT-NEXT:   $x8 = LI8 6
   ; 64BIT-NEXT:   $x9 = LI8 7
   ; 64BIT-NEXT:   $x10 = LI8 8
-  ; 64BIT-NEXT:   STFS renamable $f1, 112, $x1 :: (store (s32))
+  ; 64BIT-NEXT:   STFS renamable $f1, 112, $x1 :: (store (s32) into stack + 112, align 16)
   ; 64BIT-NEXT:   BL8_NOP <mcsymbol .test_stackarg_float[PR]>, csr_ppc64, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit $x4, implicit killed $x5, implicit killed $x6, implicit killed $x7, implicit killed $x8, implicit killed $x9, implicit killed $x10, implicit $f1, implicit $f2, implicit $x2, implicit-def $r1
   ; 64BIT-NEXT:   ADJCALLSTACKUP 128, 0, implicit-def dead $r1, implicit $r1
   ; 64BIT-NEXT:   BLR8 implicit $lr8, implicit $rm
@@ -1053,7 +1057,11 @@ define void @call_test_stackarg_float3() {
   ; 32BIT-NEXT:   renamable $r10 = LWZ 0, %stack.0 :: (load (s32) from %stack.0, align 8)
   ; 32BIT-NEXT:   renamable $f2 = LFS 0, killed renamable $r3 :: (dereferenceable load (s32) from @f)
   ; 32BIT-NEXT:   ADJCALLSTACKDOWN 64, 0, implicit-def dead $r1, implicit $r1
-  ; 32BIT-NEXT:   STFS renamable $f2, 60, $r1 :: (store (s32))
+  ; 32BIT-NEXT:   STFD renamable $f1, 0, %stack.1 :: (store (s64) into %stack.1)
+  ; 32BIT-NEXT:   STFS renamable $f2, 60, $r1 :: (store (s32) into stack + 60, basealign 16)
+  ; 32BIT-NEXT:   renamable $r3 = LWZ 4, %stack.1 :: (load (s32) from %stack.1 + 4)
+  ; 32BIT-NEXT:   STW killed renamable $r3, 56, $r1 :: (store (s32) into stack + 56, align 8, basealign 16)
+  ; 32BIT-NEXT:   renamable $r11 = LWZ 0, %stack.1 :: (load (s32) from %stack.1, align 8)
   ; 32BIT-NEXT:   $r3 = LI 1
   ; 32BIT-NEXT:   $r4 = LI 2
   ; 32BIT-NEXT:   $r5 = LI 3
@@ -1061,8 +1069,8 @@ define void @call_test_stackarg_float3() {
   ; 32BIT-NEXT:   $r7 = LI 5
   ; 32BIT-NEXT:   $r8 = LI 6
   ; 32BIT-NEXT:   $r9 = LI 7
-  ; 32BIT-NEXT:   STFD renamable $f1, 52, $r1 :: (store (s64))
-  ; 32BIT-NEXT:   BL_NOP <mcsymbol .test_stackarg_float3[PR]>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit killed $r4, implicit killed $r5, implicit killed $r6, implicit killed $r7, implicit killed $r8, implicit killed $r9, implicit $f1, implicit $r10, implicit $f2, implicit $r2, implicit-def $r1
+  ; 32BIT-NEXT:   STW killed renamable $r11, 52, $r1 :: (store (s32) into stack + 52, basealign 16)
+  ; 32BIT-NEXT:   BL_NOP <mcsymbol .test_stackarg_float3[PR]>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit $r5, implicit $r6, implicit $r7, implicit $r8, implicit $r9, implicit $f1, implicit $r10, implicit $f2, implicit $r2, implicit-def $r1
   ; 32BIT-NEXT:   ADJCALLSTACKUP 64, 0, implicit-def dead $r1, implicit $r1
   ; 32BIT-NEXT:   BLR implicit $lr, implicit $rm
   ;
@@ -1082,7 +1090,7 @@ define void @call_test_stackarg_float3() {
   ; 64BIT-NEXT:   $x7 = LI8 5
   ; 64BIT-NEXT:   $x8 = LI8 6
   ; 64BIT-NEXT:   $x9 = LI8 7
-  ; 64BIT-NEXT:   STFS renamable $f2, 112, $x1 :: (store (s32))
+  ; 64BIT-NEXT:   STFS renamable $f2, 112, $x1 :: (store (s32) into stack + 112, align 16)
   ; 64BIT-NEXT:   BL8_NOP <mcsymbol .test_stackarg_float3[PR]>, csr_ppc64, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit killed $x4, implicit killed $x5, implicit killed $x6, implicit killed $x7, implicit killed $x8, implicit killed $x9, implicit $f1, implicit $x10, implicit $f2, implicit $x2, implicit-def $r1
   ; 64BIT-NEXT:   ADJCALLSTACKUP 120, 0, implicit-def dead $r1, implicit $r1
   ; 64BIT-NEXT:   BLR8 implicit $lr8, implicit $rm
@@ -1225,15 +1233,15 @@ define void @caller_ints_stack() {
   ; 32BIT-NEXT:   renamable $r9 = LBZ 0, killed renamable $r9 :: (dereferenceable load (s8) from @uc1)
   ; 32BIT-NEXT:   renamable $r12 = LWZ 0, killed renamable $r12 :: (dereferenceable load (s32) from @i1)
   ; 32BIT-NEXT:   ADJCALLSTACKDOWN 96, 0, implicit-def dead $r1, implicit $r1
-  ; 32BIT-NEXT:   STW killed renamable $r12, 92, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r9, 88, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r8, 84, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r10, 80, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r7, 76, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r6, 72, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r5, 68, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r4, 64, $r1 :: (store (s32))
-  ; 32BIT-NEXT:   STW killed renamable $r3, 60, $r1 :: (store (s32))
+  ; 32BIT-NEXT:   STW killed renamable $r12, 92, $r1 :: (store (s32) into stack + 92, basealign 16)
+  ; 32BIT-NEXT:   STW killed renamable $r9, 88, $r1 :: (store (s32) into stack + 88, align 8, basealign 16)
+  ; 32BIT-NEXT:   STW killed renamable $r8, 84, $r1 :: (store (s32) into stack + 84, basealign 16)
+  ; 32BIT-NEXT:   STW killed renamable $r10, 80, $r1 :: (store (s32) into stack + 80, align 16)
+  ; 32BIT-NEXT:   STW killed renamable $r7, 76, $r1 :: (store (s32) into stack + 76, basealign 16)
+  ; 32BIT-NEXT:   STW killed renamable $r6, 72, $r1 :: (store (s32) into stack + 72, align 8, basealign 16)
+  ; 32BIT-NEXT:   STW killed renamable $r5, 68, $r1 :: (store (s32) into stack + 68, basealign 16)
+  ; 32BIT-NEXT:   STW killed renamable $r4, 64, $r1 :: (store (s32) into stack + 64, align 16)
+  ; 32BIT-NEXT:   STW killed renamable $r3, 60, $r1 :: (store (s32) into stack + 60, basealign 16)
   ; 32BIT-NEXT:   $r3 = LI 1
   ; 32BIT-NEXT:   $r4 = LI 2
   ; 32BIT-NEXT:   $r5 = LI 3
@@ -1242,7 +1250,7 @@ define void @caller_ints_stack() {
   ; 32BIT-NEXT:   $r8 = LI 6
   ; 32BIT-NEXT:   $r9 = LI 7
   ; 32BIT-NEXT:   $r10 = LI 8
-  ; 32BIT-NEXT:   STW killed renamable $r11, 56, $r1 :: (store (s32))
+  ; 32BIT-NEXT:   STW killed renamable $r11, 56, $r1 :: (store (s32) into stack + 56, align 8, basealign 16)
   ; 32BIT-NEXT:   BL_NOP <mcsymbol .test_ints_stack>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit $r5, implicit $r6, implicit $r7, implicit $r8, implicit $r9, implicit $r10, implicit $r2, implicit-def $r1, implicit-def dead $r3, implicit-def dead $r4
   ; 32BIT-NEXT:   ADJCALLSTACKUP 96, 0, implicit-def dead $r1, implicit $r1
   ; 32BIT-NEXT:   BLR implicit $lr, implicit $rm
@@ -1274,14 +1282,14 @@ define void @caller_ints_stack() {
   ; 64BIT-NEXT:   $x8 = LI8 6
   ; 64BIT-NEXT:   $x9 = LI8 7
   ; 64BIT-NEXT:   $x10 = LI8 8
-  ; 64BIT-NEXT:   STD killed renamable $x27, 168, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD killed renamable $x30, 160, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD killed renamable $x28, 152, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD killed renamable $x31, 144, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD killed renamable $x0, 136, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD killed renamable $x12, 128, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD killed renamable $x11, 120, $x1 :: (store (s64))
-  ; 64BIT-NEXT:   STD killed renamable $x29, 112, $x1 :: (store (s64))
+  ; 64BIT-NEXT:   STD killed renamable $x27, 168, $x1 :: (store (s64) into stack + 168, basealign 16)
+  ; 64BIT-NEXT:   STD killed renamable $x30, 160, $x1 :: (store (s64) into stack + 160, align 16)
+  ; 64BIT-NEXT:   STD killed renamable $x28, 152, $x1 :: (store (s64) into stack + 152, basealign 16)
+  ; 64BIT-NEXT:   STD killed renamable $x31, 144, $x1 :: (store (s64) into stack + 144, align 16)
+  ; 64BIT-NEXT:   STD killed renamable $x0, 136, $x1 :: (store (s64) into stack + 136, basealign 16)
+  ; 64BIT-NEXT:   STD killed renamable $x12, 128, $x1 :: (store (s64) into stack + 128, align 16)
+  ; 64BIT-NEXT:   STD killed renamable $x11, 120, $x1 :: (store (s64) into stack + 120, basealign 16)
+  ; 64BIT-NEXT:   STD killed renamable $x29, 112, $x1 :: (store (s64) into stack + 112, align 16)
   ; 64BIT-NEXT:   BL8_NOP <mcsymbol .test_ints_stack>, csr_ppc64, implicit-def dead $lr8, implicit $rm, implicit $x3, implicit $x4, implicit $x5, implicit $x6, implicit $x7, implicit $x8, implicit $x9, implicit $x10, implicit $x2, implicit-def $r1, implicit-def dead $x3
   ; 64BIT-NEXT:   ADJCALLSTACKUP 176, 0, implicit-def dead $r1, implicit $r1
   ; 64BIT-NEXT:   BLR8 implicit $lr8, implicit $rm
@@ -1333,7 +1341,7 @@ define void @call_test_i1_stack() {
   ; 32BIT-NEXT:   $r8 = LI 6
   ; 32BIT-NEXT:   $r9 = LI 7
   ; 32BIT-NEXT:   $r10 = LI 8
-  ; 32BIT-NEXT:   STW killed renamable $r11, 56, $r1 :: (store (s32))
+  ; 32BIT-NEXT:   STW killed renamable $r11, 56, $r1 :: (store (s32) into stack + 56, align 8, basealign 16)
   ; 32BIT-NEXT:   BL_NOP <mcsymbol .test_i1_stack>, csr_aix32, implicit-def dead $lr, implicit $rm, implicit $r3, implicit $r4, implicit $r5, implicit $r6, implicit $r7, implicit $r8, implicit $r9, implicit $r10, implicit $r2, implicit-def $r1
   ; 32BIT-NEXT:   ADJCALLSTACKUP 60,...
[truncated]

Copy link
Collaborator

@efriedma-quic efriedma-quic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

getStack() is specifically relative to the stack pointer itself, not a FrameIndex, so it's basically only used for constructing call frames. Maybe we should consider renaming it for clarity. For that purpose, the precise alignment of the stack usually doesn't really matter; ABI alignment is good enough.

I guess getStackAlign() is the right alignment here. In general, we don't guarantee the stack pointer has "stack alignment" at any particular point; it's just the largest alloca alignment that doesn't require realigning the stack. But I guess the call frame should have stack alignment on normal targets.

The whole notion of "getStack()" is actually a little dubious, when I think about it: if you have dynamic allocation, the actual offsets can vary. I guess it works out because the call itself is a barrier that prevents any aliasing issues.

@arsenm
Copy link
Contributor

arsenm commented Jun 17, 2025

I guess getStackAlign() is the right alignment here. In general, we don't guarantee the stack pointer has "stack alignment" at any particular point;

There is also getTransientStackAlign which I've never understood

@efriedma-quic
Copy link
Collaborator

efriedma-quic commented Jun 17, 2025

There is also getTransientStackAlign which I've never understood

In addition to the normal stack alignment, where conformance is only required at ABI boundaries, some targets specify the stack pointer register must always contain a value with a certain alignment. For example, on AArch64, if you try to write a value that isn't 16-byte aligned, the instruction faults.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants