[SROA] Aggregate-to-vector rewriting introduces stack realignment despite DataLayout S64
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
SROA can increase an alloca's alignment beyond the natural stack alignment specified by the data layout. On SystemZ, a five-pointer structure allocated with alignment 8 becomes `<5 x ptr>` with alignment 64, introducing dynamic alignment of the stack allocation.
Reproduced on LLVM 24.0.0git (`1952c705fad0`), targeting `s390x-unknown-linux-gnu`.
## Reproducer
Save as `repro.ll`:
```llvm
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64-S64"
target triple = "s390x-unknown-linux-gnu"
%ptr5 = type { ptr, ptr, ptr, ptr, ptr }
declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1 immarg)
define void @spill_ptr5(ptr %src) {
entry:
%slot = alloca %ptr5, align 8
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %slot, ptr align 8 %src,
i64 40, i1 true)
ret void
}
```
```sh
opt -passes='sroa' -S repro.ll -o sroa.ll
llc repro.ll -o before.s
llc sroa.ll -o after.s
```
SROA changes:
```llvm
%slot = alloca %ptr5, align 8
```
to:
```llvm
%slot.sroa.0 = alloca <5 x ptr>, align 64
%slot.sroa.0.0.copyload = load volatile <5 x ptr>, ptr %src, align 8
store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
```
The original input generates a fixed stack frame. After SROA, SystemZ code generation includes:
```asm
lgr %r1, %r15
aghi %r1, -120
la %r3, 216(%r1)
nill %r3, 65472
lgr %r15, %r1
```
The `nill` clears the low six bits of the allocation address, dynamically aligning it to 64 bytes.
## Cause and expected behavior
SystemZ's [native data layout](https://github.com/llvm/llvm-project/blob/1952c705fad0187fc0c6fbd1460dbd56d56c8087/llvm/lib/TargetParser/TargetDataLayout.cpp#L366-L408) specifies `S64`. The [LangRef](https://github.com/llvm/llvm-project/blob/1952c705fad0187fc0c6fbd1460dbd56d56c8087/llvm/docs/LangRef.md#L3523-L3528) describes this as a limit on stack-variable alignment promotion to avoid dynamic stack realignment.
In [SROA::rewritePartition](https://github.com/llvm/llvm-project/blob/1952c705fad0187fc0c6fbd1460dbd56d56c8087/llvm/lib/Transforms/Scalar/SROA.cpp#L5579-L5588), the replacement alloca takes `DL.getPrefTypeAlign(PartitionTy)` when the existing alignment is no greater than the replacement type's ABI alignment. For `<5 x ptr>`, this selects 64 bytes without consulting `DL.getStackAlignment()`.
Cap the preferred alignment at the natural stack alignment, while preserving any stronger alignment required by the original allocation. This keeps the replacement at alignment 8 in this example and avoids the dynamic alignment sequence.
Assisted-by: OpenAI Codex
Contributor guide
Research direction
Start in llvm/lib/Transforms/Scalar/SROA.cpp at SROA::rewritePartition and compare the replacement alignment with DataLayout's stack alignment. Run the supplied opt and llc commands for the SystemZ reproducer. Done means the replacement remains aligned to 8 in this case while preserving stronger original alignment and avoiding the dynamic stack realignment sequence.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100