[llvm] [SROA] Preserve inherited alignment when rewriting allocas (PR #222967)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 11 16:52:16 PDT 2026
https://github.com/zhouguangyuan0718 updated https://github.com/llvm/llvm-project/pull/222967
>From 8b70582b7c70a26438e353b429c98ca85c1a2370 Mon Sep 17 00:00:00 2001
From: ZhouGuangyuan <zhouguangyuan.xian at gmail.com>
Date: Fri, 11 Sep 2026 23:33:00 +0800
Subject: [PATCH 1/3] [SROA] Respect natural stack alignment when rewriting
allocas
SROA can introduce dynamic stack alignment when rewriting an aggregate alloca as a vector. On SystemZ (`S64`), a five-pointer structure with alignment 8 becomes `<5 x ptr>` with alignment 64, adding an alignment mask and extra stack-frame setup instructions.
Cap the replacement alloca's preferred alignment at the natural stack alignment when one is specified. Preserve any stronger alignment required by the original allocation at the partition offset. Data layouts without a specified natural stack alignment retain their existing behavior.
Add regression coverage for `S64`, `S128`, unspecified natural stack alignment, and explicit alignments above the stack or preferred type alignment.
Validation: all 73 SROA tests pass. The new regression fails before the fix, and the SystemZ reproducer no longer generates the dynamic alignment sequence after the fix.
Fixes #222966
Assisted-by: OpenAI Codex
---
llvm/lib/Transforms/Scalar/SROA.cpp | 19 +++--
.../SROA/struct-to-vector-stack-alignment.ll | 84 +++++++++++++++++++
2 files changed, 98 insertions(+), 5 deletions(-)
create mode 100644 llvm/test/Transforms/SROA/struct-to-vector-stack-alignment.ll
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index c933225c2ad21..eb975064a4b97 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -5581,11 +5581,20 @@ SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS, Partition &P) {
// If we will get at least this much alignment from the type alone, leave
// the alloca's alignment unconstrained.
const bool IsUnconstrained = Alignment <= DL.getABITypeAlign(PartitionTy);
- NewAI = new AllocaInst(
- PartitionTy, AI.getAddressSpace(), nullptr,
- IsUnconstrained ? DL.getPrefTypeAlign(PartitionTy) : Alignment,
- AI.getName() + ".sroa." + Twine(P.begin() - AS.begin()),
- AI.getIterator());
+ Align NewAlignment = Alignment;
+ if (IsUnconstrained) {
+ NewAlignment = DL.getPrefTypeAlign(PartitionTy);
+ // Rewriting an aggregate to a vector can increase its preferred
+ // alignment beyond the target's natural stack alignment. Avoid
+ // introducing stack realignment when the original alloca did not
+ // require it, while preserving any stronger alignment it did require.
+ if (MaybeAlign StackAlign = DL.getStackAlignment())
+ NewAlignment = std::max(Alignment, std::min(NewAlignment, *StackAlign));
+ }
+ NewAI =
+ new AllocaInst(PartitionTy, AI.getAddressSpace(), nullptr, NewAlignment,
+ AI.getName() + ".sroa." + Twine(P.begin() - AS.begin()),
+ AI.getIterator());
// Copy the old AI debug location over to the new one.
NewAI->setDebugLoc(AI.getDebugLoc());
++NumNewAllocas;
diff --git a/llvm/test/Transforms/SROA/struct-to-vector-stack-alignment.ll b/llvm/test/Transforms/SROA/struct-to-vector-stack-alignment.ll
new file mode 100644
index 0000000000000..1a165c19c3873
--- /dev/null
+++ b/llvm/test/Transforms/SROA/struct-to-vector-stack-alignment.ll
@@ -0,0 +1,84 @@
+; RUN: opt -passes='sroa<aggregate-to-vector>' -S %s | FileCheck %s --check-prefixes=COMMON,STACK128
+; RUN: opt -data-layout="e-p:64:64-i64:64-n32:64-S64" -passes='sroa<aggregate-to-vector>' -S %s | FileCheck %s --check-prefixes=COMMON,STACK64
+; RUN: opt -data-layout="e-p:64:64-i64:64-n32:64" -passes='sroa<aggregate-to-vector>' -S %s | FileCheck %s --check-prefixes=COMMON,UNSPECIFIED
+
+; SROA must not introduce alignment beyond the natural stack alignment, but
+; must preserve stronger alignment already required by the original alloca.
+; Without a natural stack alignment, preferred type alignment is still used.
+target datalayout = "e-p:64:64-i64:64-n32:64-S128"
+
+%ptr5 = type { ptr, ptr, ptr, ptr, ptr }
+
+declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1 immarg)
+
+define void @natural_stack_alignment(ptr %src) {
+; COMMON-LABEL: define void @natural_stack_alignment(
+; COMMON-NEXT: entry:
+; STACK128-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 16
+; STACK64-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 8
+; UNSPECIFIED-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
+; COMMON-NEXT: %slot.sroa.0.0.copyload = load volatile <5 x ptr>, ptr %src, align 8
+; STACK128-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 16
+; STACK64-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 8
+; UNSPECIFIED-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
+; COMMON-NEXT: ret void
+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
+}
+
+define void @explicit_above_stack_alignment(ptr %src) {
+; COMMON-LABEL: define void @explicit_above_stack_alignment(
+; COMMON-NEXT: entry:
+; STACK128-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 32
+; STACK64-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 32
+; UNSPECIFIED-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
+; COMMON-NEXT: %slot.sroa.0.0.copyload = load volatile <5 x ptr>, ptr %src, align 8
+; STACK128-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 32
+; STACK64-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 32
+; UNSPECIFIED-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
+; COMMON-NEXT: ret void
+entry:
+ %slot = alloca %ptr5, align 32
+ call void @llvm.memcpy.p0.p0.i64(ptr align 32 %slot, ptr align 8 %src,
+ i64 40, i1 true)
+ ret void
+}
+
+define void @explicit_preferred_alignment(ptr %src) {
+; COMMON-LABEL: define void @explicit_preferred_alignment(
+; COMMON-NEXT: entry:
+; STACK128-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
+; STACK64-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
+; UNSPECIFIED-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
+; COMMON-NEXT: %slot.sroa.0.0.copyload = load volatile <5 x ptr>, ptr %src, align 8
+; STACK128-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
+; STACK64-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
+; UNSPECIFIED-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
+; COMMON-NEXT: ret void
+entry:
+ %slot = alloca %ptr5, align 64
+ call void @llvm.memcpy.p0.p0.i64(ptr align 64 %slot, ptr align 8 %src,
+ i64 40, i1 true)
+ ret void
+}
+
+define void @explicit_above_preferred_alignment(ptr %src) {
+; COMMON-LABEL: define void @explicit_above_preferred_alignment(
+; COMMON-NEXT: entry:
+; STACK128-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 128
+; STACK64-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 128
+; UNSPECIFIED-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 128
+; COMMON-NEXT: %slot.sroa.0.0.copyload = load volatile <5 x ptr>, ptr %src, align 8
+; STACK128-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 128
+; STACK64-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 128
+; UNSPECIFIED-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 128
+; COMMON-NEXT: ret void
+entry:
+ %slot = alloca %ptr5, align 128
+ call void @llvm.memcpy.p0.p0.i64(ptr align 128 %slot, ptr align 8 %src,
+ i64 40, i1 true)
+ ret void
+}
>From 429bc5c6d153b0fd6444c313e423e1e0a669be82 Mon Sep 17 00:00:00 2001
From: ZhouGuangyuan <zhouguangyuan.xian at gmail.com>
Date: Sat, 12 Sep 2026 07:46:32 +0800
Subject: [PATCH 2/3] [SROA] Preserve inherited alignment when rewriting
allocas
---
llvm/lib/Transforms/Scalar/SROA.cpp | 20 ++-----
llvm/test/Transforms/SROA/addrspacecast.ll | 24 ++++-----
llvm/test/Transforms/SROA/alignment.ll | 28 +++++-----
llvm/test/Transforms/SROA/basictest.ll | 20 +++----
.../non-integral-pointer-vector-memset.ll | 6 +--
llvm/test/Transforms/SROA/phi-gep.ll | 2 +-
.../struct-to-vector-fp-store-only-tail.ll | 16 +++---
.../SROA/struct-to-vector-stack-alignment.ll | 47 +++++++++++++---
llvm/test/Transforms/SROA/struct-to-vector.ll | 4 +-
llvm/test/Transforms/SROA/tbaa-struct3.ll | 54 +++++++++----------
llvm/test/Transforms/SROA/vector-promotion.ll | 28 +++++-----
11 files changed, 133 insertions(+), 116 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index eb975064a4b97..0931cdbc2d1f0 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -5578,23 +5578,9 @@ SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS, Partition &P) {
} else {
// Make sure the alignment is compatible with P.beginOffset().
const Align Alignment = commonAlignment(AI.getAlign(), P.beginOffset());
- // If we will get at least this much alignment from the type alone, leave
- // the alloca's alignment unconstrained.
- const bool IsUnconstrained = Alignment <= DL.getABITypeAlign(PartitionTy);
- Align NewAlignment = Alignment;
- if (IsUnconstrained) {
- NewAlignment = DL.getPrefTypeAlign(PartitionTy);
- // Rewriting an aggregate to a vector can increase its preferred
- // alignment beyond the target's natural stack alignment. Avoid
- // introducing stack realignment when the original alloca did not
- // require it, while preserving any stronger alignment it did require.
- if (MaybeAlign StackAlign = DL.getStackAlignment())
- NewAlignment = std::max(Alignment, std::min(NewAlignment, *StackAlign));
- }
- NewAI =
- new AllocaInst(PartitionTy, AI.getAddressSpace(), nullptr, NewAlignment,
- AI.getName() + ".sroa." + Twine(P.begin() - AS.begin()),
- AI.getIterator());
+ NewAI = new AllocaInst(
+ PartitionTy, AI.getAddressSpace(), nullptr, Alignment,
+ AI.getName() + ".sroa." + Twine(P.begin() - AS.begin()), AI.getIterator());
// Copy the old AI debug location over to the new one.
NewAI->setDebugLoc(AI.getDebugLoc());
++NumNewAllocas;
diff --git a/llvm/test/Transforms/SROA/addrspacecast.ll b/llvm/test/Transforms/SROA/addrspacecast.ll
index 74201d56a9783..11673086a3a11 100644
--- a/llvm/test/Transforms/SROA/addrspacecast.ll
+++ b/llvm/test/Transforms/SROA/addrspacecast.ll
@@ -150,10 +150,10 @@ entry:
define i64 @alloca_addrspacecast_bitcast_volatile_store(i64 %X) {
; CHECK-LABEL: @alloca_addrspacecast_bitcast_volatile_store(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i64, align 8
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i64, align 1
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)
-; CHECK-NEXT: store volatile i64 [[X:%.*]], ptr addrspace(1) [[TMP0]], align 8
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_Z:%.*]] = load i64, ptr [[A_SROA_0]], align 8
+; CHECK-NEXT: store volatile i64 [[X:%.*]], ptr addrspace(1) [[TMP0]], align 1
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_Z:%.*]] = load i64, ptr [[A_SROA_0]], align 1
; CHECK-NEXT: ret i64 [[A_SROA_0_0_A_SROA_0_0_Z]]
;
entry:
@@ -195,10 +195,10 @@ L2:
define i64 @alloca_addrspacecast_bitcast_volatile_load(i64 %X) {
; CHECK-LABEL: @alloca_addrspacecast_bitcast_volatile_load(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i64, align 8
-; CHECK-NEXT: store i64 [[X:%.*]], ptr [[A_SROA_0]], align 8
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i64, align 1
+; CHECK-NEXT: store i64 [[X:%.*]], ptr [[A_SROA_0]], align 1
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_Z:%.*]] = load volatile i64, ptr addrspace(1) [[TMP0]], align 8
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_Z:%.*]] = load volatile i64, ptr addrspace(1) [[TMP0]], align 1
; CHECK-NEXT: ret i64 [[A_SROA_0_0_A_SROA_0_0_Z]]
;
entry:
@@ -240,10 +240,10 @@ L2:
define i32 @volatile_memset() {
; CHECK-LABEL: @volatile_memset(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 1
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)
-; CHECK-NEXT: store volatile i32 707406378, ptr addrspace(1) [[TMP0]], align 4
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load i32, ptr [[A_SROA_0]], align 4
+; CHECK-NEXT: store volatile i32 707406378, ptr addrspace(1) [[TMP0]], align 1
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load i32, ptr [[A_SROA_0]], align 1
; CHECK-NEXT: ret i32 [[A_SROA_0_0_A_SROA_0_0_VAL]]
;
entry:
@@ -258,12 +258,12 @@ entry:
define void @volatile_memcpy(ptr %src, ptr %dst) {
; CHECK-LABEL: @volatile_memcpy(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 1
; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load volatile i32, ptr [[SRC:%.*]], align 1, !tbaa [[TBAA0:![0-9]+]]
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)
-; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_COPYLOAD]], ptr addrspace(1) [[TMP0]], align 4, !tbaa [[TBAA0]]
+; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_COPYLOAD]], ptr addrspace(1) [[TMP0]], align 1, !tbaa [[TBAA0]]
; CHECK-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1:%.*]] = load volatile i32, ptr addrspace(1) [[TMP1]], align 4, !tbaa [[TBAA3:![0-9]+]]
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1:%.*]] = load volatile i32, ptr addrspace(1) [[TMP1]], align 1, !tbaa [[TBAA3:![0-9]+]]
; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1]], ptr [[DST:%.*]], align 1, !tbaa [[TBAA3]]
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/SROA/alignment.ll b/llvm/test/Transforms/SROA/alignment.ll
index 952be29095f17..9a5faf9bcc8f6 100644
--- a/llvm/test/Transforms/SROA/alignment.ll
+++ b/llvm/test/Transforms/SROA/alignment.ll
@@ -56,8 +56,8 @@ define void @test2() {
; it preserves the original debuglocation.
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i16, align 2
-; CHECK-NEXT: store volatile i16 0, ptr [[A_SROA_0]], align 2
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i16, align 1
+; CHECK-NEXT: store volatile i16 0, ptr [[A_SROA_0]], align 1
; CHECK-NEXT: [[A_SROA_0_1_GEP2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 1
; CHECK-NEXT: [[A_SROA_0_1_A_SROA_0_2_RESULT:%.*]] = load i8, ptr [[A_SROA_0_1_GEP2_SROA_IDX]], align 1
; CHECK-NEXT: [[A_SROA_0_1_GEP2_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 1
@@ -66,11 +66,11 @@ define void @test2() {
;
; CHECK-DEBUGLOC-LABEL: @test2(
; CHECK-DEBUGLOC-NEXT: entry:
-; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca i16, align 2, !dbg [[DBG28:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca i16, align 1, !dbg [[DBG28:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[A_SROA_0]], [[META23:![0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 8, 16), [[DBG28]])
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META23]], !DIExpression(), [[DBG28]])
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META24:![0-9]+]], !DIExpression(), [[META29:![0-9]+]])
-; CHECK-DEBUGLOC-NEXT: store volatile i16 0, ptr [[A_SROA_0]], align 2, !dbg [[DBG30:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: store volatile i16 0, ptr [[A_SROA_0]], align 1, !dbg [[DBG30:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META25:![0-9]+]], !DIExpression(), [[META31:![0-9]+]])
; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_1_GEP2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 1, !dbg [[DBG32:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_1_A_SROA_0_2_RESULT:%.*]] = load i8, ptr [[A_SROA_0_1_GEP2_SROA_IDX]], align 1, !dbg [[DBG32]]
@@ -212,24 +212,24 @@ define void @test6() {
;
; CHECK-LABEL: @test6(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca double, align 8
-; CHECK-NEXT: [[A_SROA_2:%.*]] = alloca double, align 8
-; CHECK-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 8
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load double, ptr [[A_SROA_0]], align 8
-; CHECK-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_VAL]], ptr [[A_SROA_2]], align 8
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca double, align 1
+; CHECK-NEXT: [[A_SROA_2:%.*]] = alloca double, align 1
+; CHECK-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 1
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load double, ptr [[A_SROA_0]], align 1
+; CHECK-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_VAL]], ptr [[A_SROA_2]], align 1
; CHECK-NEXT: ret void
;
; CHECK-DEBUGLOC-LABEL: @test6(
; CHECK-DEBUGLOC-NEXT: entry:
-; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca double, align 8, !dbg [[DBG78:![0-9]+]]
-; CHECK-DEBUGLOC-NEXT: [[A_SROA_2:%.*]] = alloca double, align 8, !dbg [[DBG78]]
+; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca double, align 1, !dbg [[DBG78:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: [[A_SROA_2:%.*]] = alloca double, align 1, !dbg [[DBG78]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[A_SROA_0]], [[META75:![0-9]+]], !DIExpression(), [[DBG78]])
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META75]], !DIExpression(), [[DBG78]])
-; CHECK-DEBUGLOC-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 8, !dbg [[DBG79:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 1, !dbg [[DBG79:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META76:![0-9]+]], !DIExpression(), [[META80:![0-9]+]])
-; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load double, ptr [[A_SROA_0]], align 8, !dbg [[DBG81:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load double, ptr [[A_SROA_0]], align 1, !dbg [[DBG81:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(double [[A_SROA_0_0_A_SROA_0_0_VAL]], [[META77:![0-9]+]], !DIExpression(), [[DBG81]])
-; CHECK-DEBUGLOC-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_VAL]], ptr [[A_SROA_2]], align 8, !dbg [[DBG82:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_VAL]], ptr [[A_SROA_2]], align 1, !dbg [[DBG82:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG83:![0-9]+]]
;
entry:
diff --git a/llvm/test/Transforms/SROA/basictest.ll b/llvm/test/Transforms/SROA/basictest.ll
index bf3aa251b3dfa..516d36295e139 100644
--- a/llvm/test/Transforms/SROA/basictest.ll
+++ b/llvm/test/Transforms/SROA/basictest.ll
@@ -427,9 +427,9 @@ entry:
define i32 @test6() {
; CHECK-LABEL: @test6(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
-; CHECK-NEXT: store volatile i32 707406378, ptr [[A_SROA_0]], align 4
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load i32, ptr [[A_SROA_0]], align 4
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 1
+; CHECK-NEXT: store volatile i32 707406378, ptr [[A_SROA_0]], align 1
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_VAL:%.*]] = load i32, ptr [[A_SROA_0]], align 1
; CHECK-NEXT: ret i32 [[A_SROA_0_0_A_SROA_0_0_VAL]]
;
entry:
@@ -442,10 +442,10 @@ entry:
define void @test7(ptr %src, ptr %dst) {
; CHECK-LABEL: @test7(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 1
; CHECK-NEXT: [[A_SROA_0_0_COPYLOAD:%.*]] = load volatile i32, ptr [[SRC:%.*]], align 1, !tbaa [[TBAA0]]
-; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_COPYLOAD]], ptr [[A_SROA_0]], align 4, !tbaa [[TBAA0]]
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1:%.*]] = load volatile i32, ptr [[A_SROA_0]], align 4, !tbaa [[TBAA3]]
+; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_COPYLOAD]], ptr [[A_SROA_0]], align 1, !tbaa [[TBAA0]]
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1:%.*]] = load volatile i32, ptr [[A_SROA_0]], align 1, !tbaa [[TBAA3]]
; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1]], ptr [[DST:%.*]], align 1, !tbaa [[TBAA3]]
; CHECK-NEXT: ret void
;
@@ -1328,7 +1328,7 @@ define void @PR15674(ptr %data, ptr %src, i32 %size) {
;
; CHECK-LABEL: @PR15674(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP_SROA_0:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TMP_SROA_0:%.*]] = alloca i32, align 1
; CHECK-NEXT: switch i32 [[SIZE:%.*]], label [[END:%.*]] [
; CHECK-NEXT: i32 4, label [[BB4:%.*]]
; CHECK-NEXT: i32 3, label [[BB3:%.*]]
@@ -1345,7 +1345,7 @@ define void @PR15674(ptr %data, ptr %src, i32 %size) {
; CHECK-NEXT: [[SRC_GEP2:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 2
; CHECK-NEXT: [[SRC_2:%.*]] = load i8, ptr [[SRC_GEP2]], align 1
; CHECK-NEXT: [[TMP_SROA_0_2_TMP_GEP2_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[TMP_SROA_0]], i64 2
-; CHECK-NEXT: store i8 [[SRC_2]], ptr [[TMP_SROA_0_2_TMP_GEP2_SROA_IDX2]], align 2
+; CHECK-NEXT: store i8 [[SRC_2]], ptr [[TMP_SROA_0_2_TMP_GEP2_SROA_IDX2]], align 1
; CHECK-NEXT: br label [[BB2]]
; CHECK: bb2:
; CHECK-NEXT: [[SRC_GEP1:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i32 1
@@ -1355,10 +1355,10 @@ define void @PR15674(ptr %data, ptr %src, i32 %size) {
; CHECK-NEXT: br label [[BB1]]
; CHECK: bb1:
; CHECK-NEXT: [[SRC_0:%.*]] = load i8, ptr [[SRC]], align 1
-; CHECK-NEXT: store i8 [[SRC_0]], ptr [[TMP_SROA_0]], align 4
+; CHECK-NEXT: store i8 [[SRC_0]], ptr [[TMP_SROA_0]], align 1
; CHECK-NEXT: br label [[END]]
; CHECK: end:
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[DATA:%.*]], ptr align 4 [[TMP_SROA_0]], i32 [[SIZE]], i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr [[DATA:%.*]], ptr align 1 [[TMP_SROA_0]], i32 [[SIZE]], i1 false)
; CHECK-NEXT: ret void
;
entry:
diff --git a/llvm/test/Transforms/SROA/non-integral-pointer-vector-memset.ll b/llvm/test/Transforms/SROA/non-integral-pointer-vector-memset.ll
index ae4ed8a794f64..de73c6a6ff271 100644
--- a/llvm/test/Transforms/SROA/non-integral-pointer-vector-memset.ll
+++ b/llvm/test/Transforms/SROA/non-integral-pointer-vector-memset.ll
@@ -8,11 +8,11 @@ declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)
define <2 x ptr addrspace(10)> @vector_memset(
; CHECK-LABEL: define <2 x ptr addrspace(10)> @vector_memset(
; CHECK-SAME: <2 x ptr addrspace(10)> [[V:%.*]], i8 [[BYTE:%.*]]) {
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca <2 x ptr addrspace(10)>, align 16
-; CHECK-NEXT: store <2 x ptr addrspace(10)> [[V]], ptr [[A_SROA_0]], align 16
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca <2 x ptr addrspace(10)>, align 8
+; CHECK-NEXT: store <2 x ptr addrspace(10)> [[V]], ptr [[A_SROA_0]], align 8
; CHECK-NEXT: [[A_SROA_0_8_P_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 8
; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 8 [[A_SROA_0_8_P_SROA_IDX1]], i8 [[BYTE]], i64 8, i1 false)
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_R:%.*]] = load <2 x ptr addrspace(10)>, ptr [[A_SROA_0]], align 16
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_R:%.*]] = load <2 x ptr addrspace(10)>, ptr [[A_SROA_0]], align 8
; CHECK-NEXT: ret <2 x ptr addrspace(10)> [[A_SROA_0_0_A_SROA_0_0_R]]
;
<2 x ptr addrspace(10)> %v, i8 %byte) {
diff --git a/llvm/test/Transforms/SROA/phi-gep.ll b/llvm/test/Transforms/SROA/phi-gep.ll
index 22d69d801c3d7..ddf52d5f69aa2 100644
--- a/llvm/test/Transforms/SROA/phi-gep.ll
+++ b/llvm/test/Transforms/SROA/phi-gep.ll
@@ -435,7 +435,7 @@ end:
define void @unreachable_term(i1 %c1) {
; CHECK-LABEL: @unreachable_term(
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 1
; CHECK-NEXT: unreachable
; CHECK: bb1:
; CHECK-NEXT: br label [[BB1_I:%.*]]
diff --git a/llvm/test/Transforms/SROA/struct-to-vector-fp-store-only-tail.ll b/llvm/test/Transforms/SROA/struct-to-vector-fp-store-only-tail.ll
index d31202a18ef1a..c3a02e48c8ef6 100644
--- a/llvm/test/Transforms/SROA/struct-to-vector-fp-store-only-tail.ll
+++ b/llvm/test/Transforms/SROA/struct-to-vector-fp-store-only-tail.ll
@@ -18,16 +18,16 @@ declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr no
; to run, you'll get a 4-byte store of 0.
define ptr @store_only_fp_tail() {
; NO-CANON-LABEL: define ptr @store_only_fp_tail() {
-; NO-CANON-NEXT: [[DOTSROA_3:%.*]] = alloca { float, float, float }, align 8
-; NO-CANON-NEXT: [[DOTSROA_4:%.*]] = alloca { float, float, float, float, float, float, float, float, float, float, float }, align 8
-; NO-CANON-NEXT: [[DOTSROA_0_SROA_1:%.*]] = alloca { float, float, float }, align 8
-; NO-CANON-NEXT: [[DOTSROA_2:%.*]] = alloca { float, float, float, float, float, float, float, float, float, float, float }, align 8
-; NO-CANON-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[DOTSROA_3]], ptr align 8 [[DOTSROA_0_SROA_1]], i64 12, i1 false)
-; NO-CANON-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[DOTSROA_4]], ptr align 8 [[DOTSROA_2]], i64 44, i1 false)
+; NO-CANON-NEXT: [[DOTSROA_3:%.*]] = alloca { float, float, float }, align 4
+; NO-CANON-NEXT: [[DOTSROA_4:%.*]] = alloca { float, float, float, float, float, float, float, float, float, float, float }, align 4
+; NO-CANON-NEXT: [[DOTSROA_0_SROA_1:%.*]] = alloca { float, float, float }, align 4
+; NO-CANON-NEXT: [[DOTSROA_2:%.*]] = alloca { float, float, float, float, float, float, float, float, float, float, float }, align 4
+; NO-CANON-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DOTSROA_3]], ptr align 4 [[DOTSROA_0_SROA_1]], i64 12, i1 false)
+; NO-CANON-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[DOTSROA_4]], ptr align 4 [[DOTSROA_2]], i64 44, i1 false)
; NO-CANON-NEXT: store float 0.000000e+00, ptr null, align 1
-; NO-CANON-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 getelementptr inbounds (i8, ptr null, i64 4), ptr align 8 [[DOTSROA_3]], i64 12, i1 false)
+; NO-CANON-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 getelementptr inbounds (i8, ptr null, i64 4), ptr align 4 [[DOTSROA_3]], i64 12, i1 false)
; NO-CANON-NEXT: store float 0.000000e+00, ptr getelementptr inbounds (i8, ptr null, i64 16), align 1
-; NO-CANON-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 getelementptr inbounds (i8, ptr null, i64 20), ptr align 8 [[DOTSROA_4]], i64 44, i1 false)
+; NO-CANON-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 getelementptr inbounds (i8, ptr null, i64 20), ptr align 4 [[DOTSROA_4]], i64 44, i1 false)
; NO-CANON-NEXT: ret ptr null
;
; CANON-LABEL: define ptr @store_only_fp_tail() {
diff --git a/llvm/test/Transforms/SROA/struct-to-vector-stack-alignment.ll b/llvm/test/Transforms/SROA/struct-to-vector-stack-alignment.ll
index 1a165c19c3873..3fe112a2e0d17 100644
--- a/llvm/test/Transforms/SROA/struct-to-vector-stack-alignment.ll
+++ b/llvm/test/Transforms/SROA/struct-to-vector-stack-alignment.ll
@@ -1,24 +1,29 @@
-; RUN: opt -passes='sroa<aggregate-to-vector>' -S %s | FileCheck %s --check-prefixes=COMMON,STACK128
-; RUN: opt -data-layout="e-p:64:64-i64:64-n32:64-S64" -passes='sroa<aggregate-to-vector>' -S %s | FileCheck %s --check-prefixes=COMMON,STACK64
-; RUN: opt -data-layout="e-p:64:64-i64:64-n32:64" -passes='sroa<aggregate-to-vector>' -S %s | FileCheck %s --check-prefixes=COMMON,UNSPECIFIED
+; RUN: opt -data-layout="e-p:64:64-i64:64-n32:64-S128" -passes='sroa<aggregate-to-vector>' -S %s | FileCheck %s --check-prefixes=COMMON,INHERIT
+; RUN: opt -data-layout="e-p:64:64-i64:64-n32:64-S128" -passes='sroa<aggregate-to-vector>,infer-alignment' -S %s | FileCheck %s --check-prefixes=COMMON,STACK128
+; RUN: opt -data-layout="e-p:64:64-i64:64-n32:64-S64" -passes='sroa<aggregate-to-vector>' -S %s | FileCheck %s --check-prefixes=COMMON,INHERIT
+; RUN: opt -data-layout="e-p:64:64-i64:64-n32:64-S64" -passes='sroa<aggregate-to-vector>,infer-alignment' -S %s | FileCheck %s --check-prefixes=COMMON,STACK64
+; RUN: opt -data-layout="e-p:64:64-i64:64-n32:64" -passes='sroa<aggregate-to-vector>' -S %s | FileCheck %s --check-prefixes=COMMON,INHERIT
+; RUN: opt -data-layout="e-p:64:64-i64:64-n32:64" -passes='sroa<aggregate-to-vector>,infer-alignment' -S %s | FileCheck %s --check-prefixes=COMMON,UNSPECIFIED
-; SROA must not introduce alignment beyond the natural stack alignment, but
-; must preserve stronger alignment already required by the original alloca.
-; Without a natural stack alignment, preferred type alignment is still used.
+; SROA inherits the original alloca alignment, including at partition offsets.
+; InferAlignment can raise it later when the natural stack alignment permits.
target datalayout = "e-p:64:64-i64:64-n32:64-S128"
%ptr5 = type { ptr, ptr, ptr, ptr, ptr }
+%ptr2 = type { ptr, ptr }
declare void @llvm.memcpy.p0.p0.i64(ptr, ptr, i64, i1 immarg)
define void @natural_stack_alignment(ptr %src) {
; COMMON-LABEL: define void @natural_stack_alignment(
; COMMON-NEXT: entry:
-; STACK128-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 16
+; INHERIT-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 8
+; STACK128-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 8
; STACK64-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 8
; UNSPECIFIED-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
; COMMON-NEXT: %slot.sroa.0.0.copyload = load volatile <5 x ptr>, ptr %src, align 8
-; STACK128-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 16
+; INHERIT-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 8
+; STACK128-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 8
; STACK64-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 8
; UNSPECIFIED-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
; COMMON-NEXT: ret void
@@ -32,10 +37,12 @@ entry:
define void @explicit_above_stack_alignment(ptr %src) {
; COMMON-LABEL: define void @explicit_above_stack_alignment(
; COMMON-NEXT: entry:
+; INHERIT-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 32
; STACK128-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 32
; STACK64-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 32
; UNSPECIFIED-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
; COMMON-NEXT: %slot.sroa.0.0.copyload = load volatile <5 x ptr>, ptr %src, align 8
+; INHERIT-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 32
; STACK128-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 32
; STACK64-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 32
; UNSPECIFIED-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
@@ -50,10 +57,12 @@ entry:
define void @explicit_preferred_alignment(ptr %src) {
; COMMON-LABEL: define void @explicit_preferred_alignment(
; COMMON-NEXT: entry:
+; INHERIT-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
; STACK128-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
; STACK64-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
; UNSPECIFIED-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 64
; COMMON-NEXT: %slot.sroa.0.0.copyload = load volatile <5 x ptr>, ptr %src, align 8
+; INHERIT-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
; STACK128-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
; STACK64-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
; UNSPECIFIED-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 64
@@ -68,10 +77,12 @@ entry:
define void @explicit_above_preferred_alignment(ptr %src) {
; COMMON-LABEL: define void @explicit_above_preferred_alignment(
; COMMON-NEXT: entry:
+; INHERIT-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 128
; STACK128-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 128
; STACK64-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 128
; UNSPECIFIED-NEXT: %slot.sroa.0 = alloca <5 x ptr>, align 128
; COMMON-NEXT: %slot.sroa.0.0.copyload = load volatile <5 x ptr>, ptr %src, align 8
+; INHERIT-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 128
; STACK128-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 128
; STACK64-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 128
; UNSPECIFIED-NEXT: store volatile <5 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 128
@@ -82,3 +93,23 @@ entry:
i64 40, i1 true)
ret void
}
+
+define void @promote_later_within_stack_alignment(ptr %src) {
+; COMMON-LABEL: define void @promote_later_within_stack_alignment(
+; COMMON-NEXT: entry:
+; INHERIT-NEXT: %slot.sroa.0 = alloca <2 x ptr>, align 8
+; STACK128-NEXT: %slot.sroa.0 = alloca <2 x ptr>, align 16
+; STACK64-NEXT: %slot.sroa.0 = alloca <2 x ptr>, align 8
+; UNSPECIFIED-NEXT: %slot.sroa.0 = alloca <2 x ptr>, align 16
+; COMMON-NEXT: %slot.sroa.0.0.copyload = load volatile <2 x ptr>, ptr %src, align 8
+; INHERIT-NEXT: store volatile <2 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 8
+; STACK128-NEXT: store volatile <2 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 16
+; STACK64-NEXT: store volatile <2 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 8
+; UNSPECIFIED-NEXT: store volatile <2 x ptr> %slot.sroa.0.0.copyload, ptr %slot.sroa.0, align 16
+; COMMON-NEXT: ret void
+entry:
+ %slot = alloca %ptr2, align 8
+ call void @llvm.memcpy.p0.p0.i64(ptr align 8 %slot, ptr align 8 %src,
+ i64 16, i1 true)
+ ret void
+}
diff --git a/llvm/test/Transforms/SROA/struct-to-vector.ll b/llvm/test/Transforms/SROA/struct-to-vector.ll
index d308781137100..bd236749d522a 100644
--- a/llvm/test/Transforms/SROA/struct-to-vector.ll
+++ b/llvm/test/Transforms/SROA/struct-to-vector.ll
@@ -401,9 +401,9 @@ define void @struct_i32x3_memcpy_into_alloca(ptr %c) {
; CHECK-LABEL: define void @struct_i32x3_memcpy_into_alloca(
; CHECK-SAME: ptr [[C:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[E_SROA_0:%.*]] = alloca <3 x i32>, align 16
+; CHECK-NEXT: [[E_SROA_0:%.*]] = alloca <3 x i32>, align 4
; CHECK-NEXT: [[E_SROA_0_0_COPYLOAD:%.*]] = load volatile <3 x i32>, ptr [[C]], align 4
-; CHECK-NEXT: store volatile <3 x i32> [[E_SROA_0_0_COPYLOAD]], ptr [[E_SROA_0]], align 16
+; CHECK-NEXT: store volatile <3 x i32> [[E_SROA_0_0_COPYLOAD]], ptr [[E_SROA_0]], align 4
; CHECK-NEXT: ret void
;
entry:
diff --git a/llvm/test/Transforms/SROA/tbaa-struct3.ll b/llvm/test/Transforms/SROA/tbaa-struct3.ll
index 6a0cacc7016f7..d9aca1b6c0df2 100644
--- a/llvm/test/Transforms/SROA/tbaa-struct3.ll
+++ b/llvm/test/Transforms/SROA/tbaa-struct3.ll
@@ -151,21 +151,21 @@ define void @memset(ptr %dst, ptr align 8 %src) {
; CHECK-SAME: ptr [[DST:%.*]], ptr align 8 [[SRC:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [7 x i8], align 1
-; CHECK-NEXT: [[A_SROA_3:%.*]] = alloca i16, align 2
+; CHECK-NEXT: [[A_SROA_3:%.*]] = alloca i16, align 1
; CHECK-NEXT: [[A_SROA_4:%.*]] = alloca [10 x i8], align 1
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_0]], ptr align 8 [[SRC]], i32 7, i1 false)
; CHECK-NEXT: [[A_SROA_3_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 7
; CHECK-NEXT: [[A_SROA_3_0_COPYLOAD:%.*]] = load i16, ptr [[A_SROA_3_0_SRC_SROA_IDX]], align 1
-; CHECK-NEXT: store i16 [[A_SROA_3_0_COPYLOAD]], ptr [[A_SROA_3]], align 2
+; CHECK-NEXT: store i16 [[A_SROA_3_0_COPYLOAD]], ptr [[A_SROA_3]], align 1
; CHECK-NEXT: [[A_SROA_4_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 9
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_4]], ptr align 1 [[A_SROA_4_0_SRC_SROA_IDX]], i32 10, i1 false)
-; CHECK-NEXT: store i16 1, ptr [[A_SROA_3]], align 2
+; CHECK-NEXT: store i16 1, ptr [[A_SROA_3]], align 1
; CHECK-NEXT: [[A_SROA_0_1_A_1_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 1
; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 [[A_SROA_0_1_A_1_SROA_IDX2]], i8 42, i32 6, i1 false)
-; CHECK-NEXT: store i16 10794, ptr [[A_SROA_3]], align 2, !tbaa [[FLOAT_TBAA0]]
+; CHECK-NEXT: store i16 10794, ptr [[A_SROA_3]], align 1, !tbaa [[FLOAT_TBAA0]]
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[DST]], ptr align 1 [[A_SROA_0]], i32 7, i1 true)
; CHECK-NEXT: [[A_SROA_3_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 7
-; CHECK-NEXT: [[A_SROA_3_0_A_SROA_3_0_COPYLOAD1:%.*]] = load volatile i16, ptr [[A_SROA_3]], align 2
+; CHECK-NEXT: [[A_SROA_3_0_A_SROA_3_0_COPYLOAD1:%.*]] = load volatile i16, ptr [[A_SROA_3]], align 1
; CHECK-NEXT: store volatile i16 [[A_SROA_3_0_A_SROA_3_0_COPYLOAD1]], ptr [[A_SROA_3_0_DST_SROA_IDX]], align 1
; CHECK-NEXT: [[A_SROA_4_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 9
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_4_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_4]], i32 10, i1 true)
@@ -235,17 +235,17 @@ define void @slice_store_v2i8_1(ptr %dst, ptr %dst.2, ptr %src) {
; CHECK-SAME: ptr [[DST:%.*]], ptr [[DST_2:%.*]], ptr [[SRC:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [6 x i8], align 1
-; CHECK-NEXT: [[A_SROA_2_SROA_0:%.*]] = alloca <2 x i8>, align 4
+; CHECK-NEXT: [[A_SROA_2_SROA_0:%.*]] = alloca <2 x i8>, align 1
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_0]], ptr align 8 [[SRC]], i32 6, i1 false)
; CHECK-NEXT: [[A_SROA_2_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 6
; CHECK-NEXT: [[A_SROA_2_SROA_0_0_COPYLOAD:%.*]] = load <2 x i8>, ptr [[A_SROA_2_0_SRC_SROA_IDX]], align 2
-; CHECK-NEXT: store <2 x i8> [[A_SROA_2_SROA_0_0_COPYLOAD]], ptr [[A_SROA_2_SROA_0]], align 4
-; CHECK-NEXT: store <2 x i8> bitcast (<1 x i16> splat (i16 123) to <2 x i8>), ptr [[A_SROA_2_SROA_0]], align 4
-; CHECK-NEXT: [[A_SROA_2_SROA_0_0_A_SROA_2_SROA_0_0_A_SROA_2_6_V_4:%.*]] = load <2 x i8>, ptr [[A_SROA_2_SROA_0]], align 4
+; CHECK-NEXT: store <2 x i8> [[A_SROA_2_SROA_0_0_COPYLOAD]], ptr [[A_SROA_2_SROA_0]], align 1
+; CHECK-NEXT: store <2 x i8> bitcast (<1 x i16> splat (i16 123) to <2 x i8>), ptr [[A_SROA_2_SROA_0]], align 1
+; CHECK-NEXT: [[A_SROA_2_SROA_0_0_A_SROA_2_SROA_0_0_A_SROA_2_6_V_4:%.*]] = load <2 x i8>, ptr [[A_SROA_2_SROA_0]], align 1
; CHECK-NEXT: store <2 x i8> [[A_SROA_2_SROA_0_0_A_SROA_2_SROA_0_0_A_SROA_2_6_V_4]], ptr [[DST_2]], align 2
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[DST]], ptr align 1 [[A_SROA_0]], i32 6, i1 true)
; CHECK-NEXT: [[A_SROA_2_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 6
-; CHECK-NEXT: [[A_SROA_2_SROA_0_0_A_SROA_2_SROA_0_0_COPYLOAD1:%.*]] = load volatile <2 x i8>, ptr [[A_SROA_2_SROA_0]], align 4
+; CHECK-NEXT: [[A_SROA_2_SROA_0_0_A_SROA_2_SROA_0_0_COPYLOAD1:%.*]] = load volatile <2 x i8>, ptr [[A_SROA_2_SROA_0]], align 1
; CHECK-NEXT: store volatile <2 x i8> [[A_SROA_2_SROA_0_0_A_SROA_2_SROA_0_0_COPYLOAD1]], ptr [[A_SROA_2_0_DST_SROA_IDX]], align 1
; CHECK-NEXT: ret void
;
@@ -269,21 +269,21 @@ define void @slice_store_v2i8_2(ptr %dst, ptr %dst.2, ptr %src) {
; CHECK-LABEL: define void @slice_store_v2i8_2(
; CHECK-SAME: ptr [[DST:%.*]], ptr [[DST_2:%.*]], ptr [[SRC:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[A_SROA_0_SROA_1:%.*]] = alloca <2 x i8>, align 2
+; CHECK-NEXT: [[A_SROA_0_SROA_1:%.*]] = alloca <2 x i8>, align 1
; CHECK-NEXT: [[A_SROA_0_SROA_4:%.*]] = alloca i8, align 1
; CHECK-NEXT: [[A_SROA_4:%.*]] = alloca [5 x i8], align 1
; CHECK-NEXT: [[A_SROA_0_SROA_1_1_COPYLOAD:%.*]] = load <2 x i8>, ptr [[SRC]], align 8
-; CHECK-NEXT: store <2 x i8> [[A_SROA_0_SROA_1_1_COPYLOAD]], ptr [[A_SROA_0_SROA_1]], align 2
+; CHECK-NEXT: store <2 x i8> [[A_SROA_0_SROA_1_1_COPYLOAD]], ptr [[A_SROA_0_SROA_1]], align 1
; CHECK-NEXT: [[A_SROA_0_SROA_4_1_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 2
; CHECK-NEXT: [[A_SROA_0_SROA_4_1_COPYLOAD:%.*]] = load i8, ptr [[A_SROA_0_SROA_4_1_SRC_SROA_IDX]], align 2
; CHECK-NEXT: store i8 [[A_SROA_0_SROA_4_1_COPYLOAD]], ptr [[A_SROA_0_SROA_4]], align 1
; CHECK-NEXT: [[A_SROA_4_1_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 3
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_4]], ptr align 1 [[A_SROA_4_1_SRC_SROA_IDX]], i32 5, i1 false)
-; CHECK-NEXT: store <2 x i8> zeroinitializer, ptr [[A_SROA_0_SROA_1]], align 2
+; CHECK-NEXT: store <2 x i8> zeroinitializer, ptr [[A_SROA_0_SROA_1]], align 1
; CHECK-NEXT: store i8 0, ptr [[A_SROA_0_SROA_4]], align 1
-; CHECK-NEXT: [[A_SROA_0_SROA_1_0_A_SROA_0_SROA_1_1_A_SROA_0_1_V_4:%.*]] = load <2 x i8>, ptr [[A_SROA_0_SROA_1]], align 2
+; CHECK-NEXT: [[A_SROA_0_SROA_1_0_A_SROA_0_SROA_1_1_A_SROA_0_1_V_4:%.*]] = load <2 x i8>, ptr [[A_SROA_0_SROA_1]], align 1
; CHECK-NEXT: store <2 x i8> [[A_SROA_0_SROA_1_0_A_SROA_0_SROA_1_1_A_SROA_0_1_V_4]], ptr [[DST_2]], align 2
-; CHECK-NEXT: [[A_SROA_0_SROA_1_0_A_SROA_0_SROA_1_1_COPYLOAD3:%.*]] = load volatile <2 x i8>, ptr [[A_SROA_0_SROA_1]], align 2
+; CHECK-NEXT: [[A_SROA_0_SROA_1_0_A_SROA_0_SROA_1_1_COPYLOAD3:%.*]] = load volatile <2 x i8>, ptr [[A_SROA_0_SROA_1]], align 1
; CHECK-NEXT: store volatile <2 x i8> [[A_SROA_0_SROA_1_0_A_SROA_0_SROA_1_1_COPYLOAD3]], ptr [[DST]], align 1
; CHECK-NEXT: [[A_SROA_0_SROA_4_1_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2
; CHECK-NEXT: [[A_SROA_0_SROA_4_0_A_SROA_0_SROA_4_1_COPYLOAD4:%.*]] = load volatile i8, ptr [[A_SROA_0_SROA_4]], align 1
@@ -336,10 +336,10 @@ define i32 @shorten_integer_store_single_field(ptr %dst, ptr %dst.2, ptr %src) {
; CHECK-LABEL: define i32 @shorten_integer_store_single_field(
; CHECK-SAME: ptr [[DST:%.*]], ptr [[DST_2:%.*]], ptr [[SRC:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
-; CHECK-NEXT: store i32 123, ptr [[A_SROA_0]], align 4, !tbaa [[FLOAT_TBAA0]]
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_L:%.*]] = load i32, ptr [[A_SROA_0]], align 4
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_COPYLOAD:%.*]] = load volatile i32, ptr [[A_SROA_0]], align 4
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 2
+; CHECK-NEXT: store i32 123, ptr [[A_SROA_0]], align 2, !tbaa [[FLOAT_TBAA0]]
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_L:%.*]] = load i32, ptr [[A_SROA_0]], align 2
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_COPYLOAD:%.*]] = load volatile i32, ptr [[A_SROA_0]], align 2
; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_A_SROA_0_0_COPYLOAD]], ptr [[DST]], align 1
; CHECK-NEXT: ret i32 [[A_SROA_0_0_A_SROA_0_0_L]]
;
@@ -355,10 +355,10 @@ define i32 @shorten_integer_store_multiple_fields(ptr %dst, ptr %dst.2, ptr %src
; CHECK-LABEL: define i32 @shorten_integer_store_multiple_fields(
; CHECK-SAME: ptr [[DST:%.*]], ptr [[DST_2:%.*]], ptr [[SRC:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
-; CHECK-NEXT: store i32 123, ptr [[A_SROA_0]], align 4, !tbaa [[V2F32_TBAA5]]
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_L:%.*]] = load i32, ptr [[A_SROA_0]], align 4
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_COPYLOAD:%.*]] = load volatile i32, ptr [[A_SROA_0]], align 4
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 2
+; CHECK-NEXT: store i32 123, ptr [[A_SROA_0]], align 2, !tbaa [[V2F32_TBAA5]]
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_L:%.*]] = load i32, ptr [[A_SROA_0]], align 2
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_COPYLOAD:%.*]] = load volatile i32, ptr [[A_SROA_0]], align 2
; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_A_SROA_0_0_COPYLOAD]], ptr [[DST]], align 1
; CHECK-NEXT: ret i32 [[A_SROA_0_0_A_SROA_0_0_L]]
;
@@ -374,10 +374,10 @@ define <2 x i16> @shorten_vector_store_multiple_fields(ptr %dst, ptr %dst.2, ptr
; CHECK-LABEL: define <2 x i16> @shorten_vector_store_multiple_fields(
; CHECK-SAME: ptr [[DST:%.*]], ptr [[DST_2:%.*]], ptr [[SRC:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca <2 x i32>, align 8
-; CHECK-NEXT: store <2 x i32> <i32 1, i32 2>, ptr [[A_SROA_0]], align 8
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_L:%.*]] = load <2 x i16>, ptr [[A_SROA_0]], align 8
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[DST]], ptr align 8 [[A_SROA_0]], i32 4, i1 true)
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca <2 x i32>, align 2
+; CHECK-NEXT: store <2 x i32> <i32 1, i32 2>, ptr [[A_SROA_0]], align 2
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_L:%.*]] = load <2 x i16>, ptr [[A_SROA_0]], align 2
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[DST]], ptr align 2 [[A_SROA_0]], i32 4, i1 true)
; CHECK-NEXT: ret <2 x i16> [[A_SROA_0_0_A_SROA_0_0_L]]
;
entry:
diff --git a/llvm/test/Transforms/SROA/vector-promotion.ll b/llvm/test/Transforms/SROA/vector-promotion.ll
index 19674e24d8e73..e69ea28a17c40 100644
--- a/llvm/test/Transforms/SROA/vector-promotion.ll
+++ b/llvm/test/Transforms/SROA/vector-promotion.ll
@@ -1003,23 +1003,23 @@ entry:
define <4 x ptr> @test15(i32 %a, i32 %b, i32 %c, i32 %d) {
; CHECK-LABEL: @test15(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[X_SROA_0:%.*]] = alloca <4 x ptr>, align 32
-; CHECK-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 32
+; CHECK-NEXT: [[X_SROA_0:%.*]] = alloca <4 x ptr>, align 8
+; CHECK-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 8
; CHECK-NEXT: [[X_SROA_0_4_X_TMP2_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 4
; CHECK-NEXT: store i32 [[B:%.*]], ptr [[X_SROA_0_4_X_TMP2_SROA_IDX1]], align 4
; CHECK-NEXT: [[X_SROA_0_8_X_TMP3_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 8
; CHECK-NEXT: store i32 [[C:%.*]], ptr [[X_SROA_0_8_X_TMP3_SROA_IDX2]], align 8
; CHECK-NEXT: [[X_SROA_0_12_X_TMP4_SROA_IDX3:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 12
; CHECK-NEXT: store i32 [[D:%.*]], ptr [[X_SROA_0_12_X_TMP4_SROA_IDX3]], align 4
-; CHECK-NEXT: [[X_SROA_0_0_X_SROA_0_0_RESULT:%.*]] = load <4 x ptr>, ptr [[X_SROA_0]], align 32
+; CHECK-NEXT: [[X_SROA_0_0_X_SROA_0_0_RESULT:%.*]] = load <4 x ptr>, ptr [[X_SROA_0]], align 8
; CHECK-NEXT: ret <4 x ptr> [[X_SROA_0_0_X_SROA_0_0_RESULT]]
;
; DEBUG-LABEL: @test15(
; DEBUG-NEXT: entry:
-; DEBUG-NEXT: [[X_SROA_0:%.*]] = alloca <4 x ptr>, align 32, !dbg [[DBG400:![0-9]+]]
+; DEBUG-NEXT: [[X_SROA_0:%.*]] = alloca <4 x ptr>, align 8, !dbg [[DBG400:![0-9]+]]
; DEBUG-NEXT: #dbg_value(ptr [[X_SROA_0]], [[META394:![0-9]+]], !DIExpression(), [[DBG400]])
; DEBUG-NEXT: #dbg_value(ptr undef, [[META394]], !DIExpression(), [[DBG400]])
-; DEBUG-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 32, !dbg [[DBG401:![0-9]+]]
+; DEBUG-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 8, !dbg [[DBG401:![0-9]+]]
; DEBUG-NEXT: #dbg_value(ptr undef, [[META395:![0-9]+]], !DIExpression(), [[META402:![0-9]+]])
; DEBUG-NEXT: [[X_SROA_0_4_X_TMP2_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 4, !dbg [[DBG403:![0-9]+]]
; DEBUG-NEXT: store i32 [[B:%.*]], ptr [[X_SROA_0_4_X_TMP2_SROA_IDX1]], align 4, !dbg [[DBG403]]
@@ -1029,7 +1029,7 @@ define <4 x ptr> @test15(i32 %a, i32 %b, i32 %c, i32 %d) {
; DEBUG-NEXT: #dbg_value(ptr undef, [[META397:![0-9]+]], !DIExpression(), [[META406:![0-9]+]])
; DEBUG-NEXT: [[X_SROA_0_12_X_TMP4_SROA_IDX3:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 12, !dbg [[DBG407:![0-9]+]]
; DEBUG-NEXT: store i32 [[D:%.*]], ptr [[X_SROA_0_12_X_TMP4_SROA_IDX3]], align 4, !dbg [[DBG407]]
-; DEBUG-NEXT: [[X_SROA_0_0_X_SROA_0_0_RESULT:%.*]] = load <4 x ptr>, ptr [[X_SROA_0]], align 32, !dbg [[DBG408:![0-9]+]]
+; DEBUG-NEXT: [[X_SROA_0_0_X_SROA_0_0_RESULT:%.*]] = load <4 x ptr>, ptr [[X_SROA_0]], align 8, !dbg [[DBG408:![0-9]+]]
; DEBUG-NEXT: #dbg_value(<4 x ptr> [[X_SROA_0_0_X_SROA_0_0_RESULT]], [[META398:![0-9]+]], !DIExpression(), [[DBG408]])
; DEBUG-NEXT: ret <4 x ptr> [[X_SROA_0_0_X_SROA_0_0_RESULT]], !dbg [[DBG409:![0-9]+]]
;
@@ -1093,33 +1093,33 @@ entry:
define <4 x ptr> @test17(i32 %a, i32 %b, i64 %c, i64 %d) {
; CHECK-LABEL: @test17(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[X_SROA_0:%.*]] = alloca <4 x ptr>, align 32
-; CHECK-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 32
+; CHECK-NEXT: [[X_SROA_0:%.*]] = alloca <4 x ptr>, align 8
+; CHECK-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 8
; CHECK-NEXT: [[X_SROA_0_4_X_TMP2_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 4
; CHECK-NEXT: store i32 [[B:%.*]], ptr [[X_SROA_0_4_X_TMP2_SROA_IDX1]], align 4
; CHECK-NEXT: [[X_SROA_0_16_X_TMP3_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 16
-; CHECK-NEXT: store i64 [[C:%.*]], ptr [[X_SROA_0_16_X_TMP3_SROA_IDX2]], align 16
+; CHECK-NEXT: store i64 [[C:%.*]], ptr [[X_SROA_0_16_X_TMP3_SROA_IDX2]], align 8
; CHECK-NEXT: [[X_SROA_0_24_X_TMP4_SROA_IDX3:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 24
; CHECK-NEXT: store i64 [[D:%.*]], ptr [[X_SROA_0_24_X_TMP4_SROA_IDX3]], align 8
-; CHECK-NEXT: [[X_SROA_0_0_X_SROA_0_0_RESULT:%.*]] = load <4 x ptr>, ptr [[X_SROA_0]], align 32
+; CHECK-NEXT: [[X_SROA_0_0_X_SROA_0_0_RESULT:%.*]] = load <4 x ptr>, ptr [[X_SROA_0]], align 8
; CHECK-NEXT: ret <4 x ptr> [[X_SROA_0_0_X_SROA_0_0_RESULT]]
;
; DEBUG-LABEL: @test17(
; DEBUG-NEXT: entry:
-; DEBUG-NEXT: [[X_SROA_0:%.*]] = alloca <4 x ptr>, align 32, !dbg [[DBG434:![0-9]+]]
+; DEBUG-NEXT: [[X_SROA_0:%.*]] = alloca <4 x ptr>, align 8, !dbg [[DBG434:![0-9]+]]
; DEBUG-NEXT: #dbg_value(ptr [[X_SROA_0]], [[META429:![0-9]+]], !DIExpression(), [[DBG434]])
; DEBUG-NEXT: #dbg_value(ptr undef, [[META429]], !DIExpression(), [[DBG434]])
-; DEBUG-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 32, !dbg [[DBG435:![0-9]+]]
+; DEBUG-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 8, !dbg [[DBG435:![0-9]+]]
; DEBUG-NEXT: #dbg_value(ptr undef, [[META430:![0-9]+]], !DIExpression(), [[META436:![0-9]+]])
; DEBUG-NEXT: [[X_SROA_0_4_X_TMP2_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 4, !dbg [[DBG437:![0-9]+]]
; DEBUG-NEXT: store i32 [[B:%.*]], ptr [[X_SROA_0_4_X_TMP2_SROA_IDX1]], align 4, !dbg [[DBG437]]
; DEBUG-NEXT: #dbg_value(ptr undef, [[META431:![0-9]+]], !DIExpression(), [[META438:![0-9]+]])
; DEBUG-NEXT: [[X_SROA_0_16_X_TMP3_SROA_IDX2:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 16, !dbg [[DBG439:![0-9]+]]
-; DEBUG-NEXT: store i64 [[C:%.*]], ptr [[X_SROA_0_16_X_TMP3_SROA_IDX2]], align 16, !dbg [[DBG439]]
+; DEBUG-NEXT: store i64 [[C:%.*]], ptr [[X_SROA_0_16_X_TMP3_SROA_IDX2]], align 8, !dbg [[DBG439]]
; DEBUG-NEXT: #dbg_value(ptr undef, [[META432:![0-9]+]], !DIExpression(), [[META440:![0-9]+]])
; DEBUG-NEXT: [[X_SROA_0_24_X_TMP4_SROA_IDX3:%.*]] = getelementptr inbounds i8, ptr [[X_SROA_0]], i64 24, !dbg [[DBG441:![0-9]+]]
; DEBUG-NEXT: store i64 [[D:%.*]], ptr [[X_SROA_0_24_X_TMP4_SROA_IDX3]], align 8, !dbg [[DBG441]]
-; DEBUG-NEXT: [[X_SROA_0_0_X_SROA_0_0_RESULT:%.*]] = load <4 x ptr>, ptr [[X_SROA_0]], align 32, !dbg [[DBG442:![0-9]+]]
+; DEBUG-NEXT: [[X_SROA_0_0_X_SROA_0_0_RESULT:%.*]] = load <4 x ptr>, ptr [[X_SROA_0]], align 8, !dbg [[DBG442:![0-9]+]]
; DEBUG-NEXT: #dbg_value(<4 x ptr> [[X_SROA_0_0_X_SROA_0_0_RESULT]], [[META433:![0-9]+]], !DIExpression(), [[DBG442]])
; DEBUG-NEXT: ret <4 x ptr> [[X_SROA_0_0_X_SROA_0_0_RESULT]], !dbg [[DBG443:![0-9]+]]
;
>From a8dbb40c7589eb956cb4e144048074b2a387952a Mon Sep 17 00:00:00 2001
From: ZhouGuangyuan <zhouguangyuan.xian at gmail.com>
Date: Sat, 12 Sep 2026 07:52:02 +0800
Subject: [PATCH 3/3] [SROA] Fix alloca construction formatting
---
llvm/lib/Transforms/Scalar/SROA.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index 0931cdbc2d1f0..68757e2d3ef98 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -5578,9 +5578,10 @@ SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS, Partition &P) {
} else {
// Make sure the alignment is compatible with P.beginOffset().
const Align Alignment = commonAlignment(AI.getAlign(), P.beginOffset());
- NewAI = new AllocaInst(
- PartitionTy, AI.getAddressSpace(), nullptr, Alignment,
- AI.getName() + ".sroa." + Twine(P.begin() - AS.begin()), AI.getIterator());
+ NewAI =
+ new AllocaInst(PartitionTy, AI.getAddressSpace(), nullptr, Alignment,
+ AI.getName() + ".sroa." + Twine(P.begin() - AS.begin()),
+ AI.getIterator());
// Copy the old AI debug location over to the new one.
NewAI->setDebugLoc(AI.getDebugLoc());
++NumNewAllocas;
More information about the llvm-commits
mailing list