[llvm] [SROA] Preserve inherited alignment when rewriting allocas (PR #222967)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 11 19:23:39 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/5] [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 c933225c2ad213..eb975064a4b97e 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 00000000000000..1a165c19c38731
--- /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/5] [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 eb975064a4b97e..0931cdbc2d1f0d 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 74201d56a97835..11673086a3a110 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 952be29095f175..9a5faf9bcc8f61 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 bf3aa251b3dfaa..516d36295e1391 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 ae4ed8a794f64c..de73c6a6ff271d 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 22d69d801c3d7d..ddf52d5f69aa22 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 d31202a18ef1a6..c3a02e48c8ef6a 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 1a165c19c38731..3fe112a2e0d170 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 d308781137100c..bd236749d522a1 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 6a0cacc7016f77..d9aca1b6c0df23 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 19674e24d8e730..e69ea28a17c409 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/5] [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 0931cdbc2d1f0d..68757e2d3ef983 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;
>From 1a18bf703b20866b46405c9c028e635aca7f56f7 Mon Sep 17 00:00:00 2001
From: ZhouGuangyuan <zhouguangyuan.xian at gmail.com>
Date: Sat, 12 Sep 2026 10:22:32 +0800
Subject: [PATCH 4/5] [SROA] Run alignment inference in affected IR tests
---
.../sroa/alloca-single-slice.ll | 4 +-
.../assignment-tracking/sroa/memcpy.ll | 10 +-
.../assignment-tracking/sroa/rewrite.ll | 10 +-
.../Generic/assignment-tracking/sroa/store.ll | 10 +-
llvm/test/DebugInfo/sroa-handle-dbg-value.ll | 4 +-
llvm/test/Transforms/SROA/addrspacecast.ll | 38 ++++----
llvm/test/Transforms/SROA/alignment.ll | 94 +++++++++----------
llvm/test/Transforms/SROA/basictest.ll | 88 ++++++++---------
.../non-integral-pointer-vector-memset.ll | 8 +-
llvm/test/Transforms/SROA/phi-gep.ll | 20 ++--
.../struct-to-vector-fp-store-only-tail.ll | 18 ++--
llvm/test/Transforms/SROA/struct-to-vector.ll | 6 +-
llvm/test/Transforms/SROA/tbaa-struct3.ll | 62 ++++++------
llvm/test/Transforms/SROA/vector-promotion.ll | 62 ++++++------
14 files changed, 217 insertions(+), 217 deletions(-)
diff --git a/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/alloca-single-slice.ll b/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/alloca-single-slice.ll
index b12e6b6122a91a..e4522fe4247843 100644
--- a/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/alloca-single-slice.ll
+++ b/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/alloca-single-slice.ll
@@ -1,4 +1,4 @@
-; RUN: opt -passes=sroa,verify -S %s -o - \
+; RUN: opt -passes=sroa,infer-alignment,verify -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="#dbg_"
; Check that single sliced allocas retain their assignment tracking debug info.
@@ -16,7 +16,7 @@
;; | opt -passes=declare-to-assign -S -o -
; CHECK: entry:
-; CHECK-NEXT: %a.sroa.0 = alloca i64, align 8, !DIAssignID ![[ID_1:[0-9]+]]
+; CHECK-NEXT: %a.sroa.0 = alloca i64, align 1, !DIAssignID ![[ID_1:[0-9]+]]
; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR:[0-9]+]], !DIExpression(), ![[ID_1]], ptr %a.sroa.0, !DIExpression(),
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
diff --git a/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/memcpy.ll b/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/memcpy.ll
index ee7e9341ca59a3..f70eadb3a33c94 100644
--- a/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/memcpy.ll
+++ b/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/memcpy.ll
@@ -1,4 +1,4 @@
-; RUN: opt -passes=sroa,verify -S %s -o - \
+; RUN: opt -passes=sroa,infer-alignment,verify -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="#dbg_"
;; Check that the new slices of an alloca and memcpy intructions get dbg.assign
@@ -25,17 +25,17 @@
;; Split alloca.
; CHECK: entry:
-; CHECK-NEXT: %To.sroa.0 = alloca { i32, i32, i32 }, align 8, !DIAssignID ![[ID_1:[0-9]+]]
+; CHECK-NEXT: %To.sroa.0 = alloca { i32, i32, i32 }, align 4, !DIAssignID ![[ID_1:[0-9]+]]
; CHECK-NEXT: #dbg_assign({{.+}} undef, ![[TO:[0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 96), ![[ID_1]], ptr %To.sroa.0, !DIExpression(),
-; CHECK-NEXT: %To.sroa.4 = alloca { i32, i32, i32 }, align 8, !DIAssignID ![[ID_3:[0-9]+]]
+; CHECK-NEXT: %To.sroa.4 = alloca { i32, i32, i32 }, align 4, !DIAssignID ![[ID_3:[0-9]+]]
; CHECK-NEXT: #dbg_assign({{.+}} undef, ![[TO]], !DIExpression(DW_OP_LLVM_fragment, 128, 96), ![[ID_3]], ptr %To.sroa.4, !DIExpression(),
;; Split memcpy.
-; CHECK: call void @llvm.memcpy{{.*}}(ptr align 8 %To.sroa.0, ptr align 4 @From, i64 12, i1 false),{{.*}}!DIAssignID ![[ID_4:[0-9]+]]
+; CHECK: call void @llvm.memcpy{{.*}}(ptr align 4 %To.sroa.0, ptr align 4 @From, i64 12, i1 false),{{.*}}!DIAssignID ![[ID_4:[0-9]+]]
;; This slice has been split and is promoted.
; CHECK: %To.sroa.3.0.copyload = load i32, ptr getelementptr inbounds (i8, ptr @From, i64 12)
-; CHECK: call void @llvm.memcpy{{.*}}(ptr align 8 %To.sroa.4, ptr align 4 getelementptr inbounds (i8, ptr @From, i64 16), i64 12, i1 false){{.*}}!DIAssignID ![[ID_6:[0-9]+]]
+; CHECK: call void @llvm.memcpy{{.*}}(ptr align 4 %To.sroa.4, ptr align 4 getelementptr inbounds (i8, ptr @From, i64 16), i64 12, i1 false){{.*}}!DIAssignID ![[ID_6:[0-9]+]]
;; Intrinsics for the splits above.
; CHECK-NEXT: #dbg_assign({{.+}} undef, ![[TO]], !DIExpression(DW_OP_LLVM_fragment, 0, 96), ![[ID_4]], ptr %To.sroa.0, !DIExpression(),
diff --git a/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/rewrite.ll b/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/rewrite.ll
index 73e954a27375f6..286a1c2cb4dcfa 100644
--- a/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/rewrite.ll
+++ b/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/rewrite.ll
@@ -1,4 +1,4 @@
-; RUN: opt -passes=sroa,verify -S %s -o - \
+; RUN: opt -passes=sroa,infer-alignment,verify -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="#dbg_"
; Check that the new slices of an alloca and memset intructions get dbg.assign
@@ -23,17 +23,17 @@
;; $ clang test.cpp -Xclang -disable-llvm-passes -O2 -g -c -S -emit-llvm -o -
; CHECK: entry:
-; CHECK-NEXT: %S.sroa.0 = alloca { i32, i32, i32 }, align 8, !DIAssignID ![[ID_1:[0-9]+]]
+; CHECK-NEXT: %S.sroa.0 = alloca { i32, i32, i32 }, align 4, !DIAssignID ![[ID_1:[0-9]+]]
; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR:[0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 96), ![[ID_1]], ptr %S.sroa.0, !DIExpression(),
;; The middle slice has been promoted, so the alloca has gone away.
-; CHECK-NEXT: %S.sroa.5 = alloca { i32, i32, i32 }, align 8, !DIAssignID ![[ID_3:[0-9]+]]
+; CHECK-NEXT: %S.sroa.5 = alloca { i32, i32, i32 }, align 4, !DIAssignID ![[ID_3:[0-9]+]]
; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR]], !DIExpression(DW_OP_LLVM_fragment, 128, 96), ![[ID_3]], ptr %S.sroa.5, !DIExpression(),
;; The memset has been sliced up (middle slice removed).
-; CHECK: call void @llvm.memset{{.*}}(ptr align 8 %S.sroa.0, i8 0, i64 12, i1 false), !dbg !{{.+}}, !DIAssignID ![[ID_5:[0-9]+]]
-; CHECK: call void @llvm.memset{{.*}}(ptr align 8 %S.sroa.5, i8 0, i64 12, i1 false), !dbg !{{.+}}, !DIAssignID ![[ID_6:[0-9]+]]
+; CHECK: call void @llvm.memset{{.*}}(ptr align 4 %S.sroa.0, i8 0, i64 12, i1 false), !dbg !{{.+}}, !DIAssignID ![[ID_5:[0-9]+]]
+; CHECK: call void @llvm.memset{{.*}}(ptr align 4 %S.sroa.5, i8 0, i64 12, i1 false), !dbg !{{.+}}, !DIAssignID ![[ID_6:[0-9]+]]
; CHECK-NEXT: #dbg_assign(i8 0, ![[VAR]], !DIExpression(DW_OP_LLVM_fragment, 0, 96), ![[ID_5]], ptr %S.sroa.0, !DIExpression(),
;; Check the middle slice (no memset) gets a correct dbg.assign.
diff --git a/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/store.ll b/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/store.ll
index 5ea3ae47424651..90881ecb95b2e7 100644
--- a/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/store.ll
+++ b/llvm/test/DebugInfo/Generic/assignment-tracking/sroa/store.ll
@@ -1,4 +1,4 @@
-; RUN: opt -passes=sroa,verify -S %s -o - \
+; RUN: opt -passes=sroa,infer-alignment,verify -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="#dbg_"
; Check that the new slices of an alloca and memset intructions get dbg.assign
@@ -26,16 +26,16 @@
;; | opt -passes=declare-to-assign -S -o -
; CHECK: entry:
-; CHECK-NEXT: %S.sroa.0 = alloca { i32, i32, i32 }, align 8, !DIAssignID ![[ID_1:[0-9]+]]
+; CHECK-NEXT: %S.sroa.0 = alloca { i32, i32, i32 }, align 4, !DIAssignID ![[ID_1:[0-9]+]]
; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR:[0-9]+]], !DIExpression(DW_OP_LLVM_fragment, 0, 96), ![[ID_1]], ptr %S.sroa.0, !DIExpression(),
-; CHECK-NEXT: %S.sroa.4 = alloca { i32, i32, i32 }, align 8, !DIAssignID ![[ID_3:[0-9]+]]
+; CHECK-NEXT: %S.sroa.4 = alloca { i32, i32, i32 }, align 4, !DIAssignID ![[ID_3:[0-9]+]]
; CHECK-NEXT: #dbg_assign(i1 undef, ![[VAR]], !DIExpression(DW_OP_LLVM_fragment, 128, 96), ![[ID_3]], ptr %S.sroa.4, !DIExpression(),
;; The memset has been split into [0, 96)[96, 128)[128, 224) bit slices. The
;; memset for the middle slice has been removed.
-; CHECK: call void @llvm.memset{{.*}}(ptr align 8 %S.sroa.0, i8 0, i64 12, i1 false), !dbg !{{.+}}, !DIAssignID ![[ID_4:[0-9]+]]
-; CHECK-NEXT: call void @llvm.memset{{.*}}(ptr align 8 %S.sroa.4, i8 0, i64 12, i1 false), !dbg !{{.+}}, !DIAssignID ![[ID_5:[0-9]+]]
+; CHECK: call void @llvm.memset{{.*}}(ptr align 4 %S.sroa.0, i8 0, i64 12, i1 false), !dbg !{{.+}}, !DIAssignID ![[ID_4:[0-9]+]]
+; CHECK-NEXT: call void @llvm.memset{{.*}}(ptr align 4 %S.sroa.4, i8 0, i64 12, i1 false), !dbg !{{.+}}, !DIAssignID ![[ID_5:[0-9]+]]
; CHECK-NEXT: #dbg_assign(i8 0, ![[VAR]], !DIExpression(DW_OP_LLVM_fragment, 0, 96), ![[ID_4]], ptr %S.sroa.0, !DIExpression(),
;; This is the one we care about most in this test: check that a memset->store
diff --git a/llvm/test/DebugInfo/sroa-handle-dbg-value.ll b/llvm/test/DebugInfo/sroa-handle-dbg-value.ll
index 5a877372fa462f..e3043e4ba3429a 100644
--- a/llvm/test/DebugInfo/sroa-handle-dbg-value.ll
+++ b/llvm/test/DebugInfo/sroa-handle-dbg-value.ll
@@ -1,9 +1,9 @@
; This test was obtained from swift source code and then automatically reducing it via Delta.
; The swift source code was from the test test/DebugInfo/debug_scope_distinct.swift.
-; RUN: opt %s -S -p=sroa -o - | FileCheck %s
+; RUN: opt %s -S -p=sroa,infer-alignment -o - | FileCheck %s
-; CHECK: [[SROA_5_SROA_21:%.*]] = alloca [7 x i8], align 8
+; CHECK: [[SROA_5_SROA_21:%.*]] = alloca [7 x i8], align 1
; CHECK-NEXT: #dbg_value(ptr [[SROA_5_SROA_21]], !59, !DIExpression(DW_OP_deref, DW_OP_LLVM_fragment, 72, 56), [[DBG72:![0-9]+]])
; CHECK: #dbg_value(ptr [[REG1:%[0-9]+]], [[META54:![0-9]+]], !DIExpression(DW_OP_deref), [[DBG78:![0-9]+]])
diff --git a/llvm/test/Transforms/SROA/addrspacecast.ll b/llvm/test/Transforms/SROA/addrspacecast.ll
index 11673086a3a110..543eb2ed23fe46 100644
--- a/llvm/test/Transforms/SROA/addrspacecast.ll
+++ b/llvm/test/Transforms/SROA/addrspacecast.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
-; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
+; RUN: opt < %s -passes='sroa<preserve-cfg>,infer-alignment' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
+; RUN: opt < %s -passes='sroa<modify-cfg>,infer-alignment' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
@@ -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 1
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i64, align 8
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)
-; 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: 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: ret i64 [[A_SROA_0_0_A_SROA_0_0_Z]]
;
entry:
@@ -169,13 +169,13 @@ entry:
define i65 @volatile_store_addrspacecast_slice(i65 %X, i16 %idx) {
; CHECK-LABEL: @volatile_store_addrspacecast_slice(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 4
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 8
; CHECK-NEXT: [[A_SROA_1:%.*]] = alloca [9 x i8], align 8
; CHECK-NEXT: [[A_SROA_1_0_GEPB_SROA_CAST:%.*]] = addrspacecast ptr [[A_SROA_1]] to ptr addrspace(1)
; CHECK-NEXT: store volatile i65 [[X:%.*]], ptr addrspace(1) [[A_SROA_1_0_GEPB_SROA_CAST]], align 8
; CHECK-NEXT: br label [[L2:%.*]]
; CHECK: L2:
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_20_Z:%.*]] = load i65, ptr [[A_SROA_0]], align 4
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_20_Z:%.*]] = load i65, ptr [[A_SROA_0]], align 8
; CHECK-NEXT: ret i65 [[A_SROA_0_0_A_SROA_0_20_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 1
-; CHECK-NEXT: store i64 [[X:%.*]], ptr [[A_SROA_0]], align 1
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i64, align 8
+; CHECK-NEXT: store i64 [[X:%.*]], ptr [[A_SROA_0]], align 8
; 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 1
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_Z:%.*]] = load volatile i64, ptr addrspace(1) [[TMP0]], align 8
; CHECK-NEXT: ret i64 [[A_SROA_0_0_A_SROA_0_0_Z]]
;
entry:
@@ -214,13 +214,13 @@ declare void @llvm.memset.p1.i32(ptr addrspace(1) nocapture, i8, i32, i1) nounwi
define i65 @volatile_load_addrspacecast_slice(i65 %X, i16 %idx) {
; CHECK-LABEL: @volatile_load_addrspacecast_slice(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 4
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 8
; CHECK-NEXT: [[A_SROA_1:%.*]] = alloca [9 x i8], align 8
; CHECK-NEXT: [[A_SROA_1_0_GEPB_SROA_CAST:%.*]] = addrspacecast ptr [[A_SROA_1]] to ptr addrspace(1)
; CHECK-NEXT: store i65 [[X:%.*]], ptr addrspace(1) [[A_SROA_1_0_GEPB_SROA_CAST]], align 8
; CHECK-NEXT: br label [[L2:%.*]]
; CHECK: L2:
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_20_Z:%.*]] = load volatile i65, ptr [[A_SROA_0]], align 4
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_20_Z:%.*]] = load volatile i65, ptr [[A_SROA_0]], align 8
; CHECK-NEXT: ret i65 [[A_SROA_0_0_A_SROA_0_20_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 1
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast ptr [[A_SROA_0]] to ptr addrspace(1)
-; 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: 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: 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 1
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
; 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 1, !tbaa [[TBAA0]]
+; CHECK-NEXT: store volatile i32 [[A_SROA_0_0_COPYLOAD]], ptr addrspace(1) [[TMP0]], align 4, !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 1, !tbaa [[TBAA3:![0-9]+]]
+; 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: store volatile i32 [[A_SROA_0_0_A_SROA_0_0_COPYLOAD1]], ptr [[DST:%.*]], align 1, !tbaa [[TBAA3]]
; CHECK-NEXT: ret void
;
@@ -299,7 +299,7 @@ define void @select_addrspacecast_const_op(i1 %a, i1 %b) {
; CHECK-MODIFY-CFG-LABEL: @select_addrspacecast_const_op(
; CHECK-MODIFY-CFG-NEXT: br i1 [[B:%.*]], label [[DOTCONT:%.*]], label [[DOTELSE:%.*]]
; CHECK-MODIFY-CFG: .else:
-; CHECK-MODIFY-CFG-NEXT: [[COND_ELSE_VAL:%.*]] = load i64, ptr addrspace(1) null, align 8
+; CHECK-MODIFY-CFG-NEXT: [[COND_ELSE_VAL:%.*]] = load i64, ptr addrspace(1) null, align 32768
; CHECK-MODIFY-CFG-NEXT: br label [[DOTCONT]]
; CHECK-MODIFY-CFG: .cont:
; CHECK-MODIFY-CFG-NEXT: [[COND:%.*]] = phi i64 [ undef, [[TMP0:%.*]] ], [ [[COND_ELSE_VAL]], [[DOTELSE]] ]
diff --git a/llvm/test/Transforms/SROA/alignment.ll b/llvm/test/Transforms/SROA/alignment.ll
index 9a5faf9bcc8f61..abfa18e12b03e1 100644
--- a/llvm/test/Transforms/SROA/alignment.ll
+++ b/llvm/test/Transforms/SROA/alignment.ll
@@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
-; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
-; RUN: opt -passes='debugify,function(sroa<preserve-cfg>)' -S < %s | FileCheck %s -check-prefix CHECK-DEBUGLOC
+; RUN: opt < %s -passes='sroa<preserve-cfg>,infer-alignment' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
+; RUN: opt < %s -passes='sroa<modify-cfg>,infer-alignment' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
+; RUN: opt -passes='debugify,function(sroa<preserve-cfg>,infer-alignment)' -S < %s | FileCheck %s -check-prefix CHECK-DEBUGLOC
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
@@ -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 1
-; CHECK-NEXT: store volatile i16 0, ptr [[A_SROA_0]], align 1
+; 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_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 1, !dbg [[DBG28:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca i16, align 2, !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 1, !dbg [[DBG30:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: store volatile i16 0, ptr [[A_SROA_0]], align 2, !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]]
@@ -158,32 +158,32 @@ define void @test5() {
;
; CHECK-LABEL: @test5(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 1
-; CHECK-NEXT: [[A_SROA_3:%.*]] = alloca [9 x i8], align 1
-; CHECK-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 1
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 8
+; CHECK-NEXT: [[A_SROA_3:%.*]] = alloca [9 x i8], align 8
+; CHECK-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 8
; CHECK-NEXT: [[A_SROA_0_7_WEIRD_GEP1_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 7
; CHECK-NEXT: [[A_SROA_0_7_A_SROA_0_7_WEIRD_LOAD1:%.*]] = load volatile i16, ptr [[A_SROA_0_7_WEIRD_GEP1_SROA_IDX1]], align 1
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_D1:%.*]] = load double, ptr [[A_SROA_0]], align 1
-; CHECK-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_D1]], ptr [[A_SROA_3]], align 1
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_D1:%.*]] = load double, ptr [[A_SROA_0]], align 8
+; CHECK-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_D1]], ptr [[A_SROA_3]], align 8
; CHECK-NEXT: [[A_SROA_3_7_WEIRD_GEP2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_3]], i64 7
; CHECK-NEXT: [[A_SROA_3_7_A_SROA_3_16_WEIRD_LOAD2:%.*]] = load volatile i16, ptr [[A_SROA_3_7_WEIRD_GEP2_SROA_IDX]], align 1
; CHECK-NEXT: ret void
;
; CHECK-DEBUGLOC-LABEL: @test5(
; CHECK-DEBUGLOC-NEXT: entry:
-; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 1, !dbg [[DBG63:![0-9]+]]
-; CHECK-DEBUGLOC-NEXT: [[A_SROA_3:%.*]] = alloca [9 x i8], align 1, !dbg [[DBG63]]
+; CHECK-DEBUGLOC-NEXT: [[A_SROA_0:%.*]] = alloca [9 x i8], align 8, !dbg [[DBG63:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: [[A_SROA_3:%.*]] = alloca [9 x i8], align 8, !dbg [[DBG63]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[A_SROA_0]], [[META55:![0-9]+]], !DIExpression(), [[DBG63]])
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META55]], !DIExpression(), [[DBG63]])
-; CHECK-DEBUGLOC-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 1, !dbg [[DBG64:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 8, !dbg [[DBG64:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META56:![0-9]+]], !DIExpression(), [[META65:![0-9]+]])
; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_7_WEIRD_GEP1_SROA_IDX1:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i64 7, !dbg [[DBG66:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_7_A_SROA_0_7_WEIRD_LOAD1:%.*]] = load volatile i16, ptr [[A_SROA_0_7_WEIRD_GEP1_SROA_IDX1]], align 1, !dbg [[DBG66]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(i16 [[A_SROA_0_7_A_SROA_0_7_WEIRD_LOAD1]], [[META57:![0-9]+]], !DIExpression(), [[DBG66]])
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META59:![0-9]+]], !DIExpression(), [[META67:![0-9]+]])
-; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_0_A_SROA_0_0_D1:%.*]] = load double, ptr [[A_SROA_0]], align 1, !dbg [[DBG68:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: [[A_SROA_0_0_A_SROA_0_0_D1:%.*]] = load double, ptr [[A_SROA_0]], align 8, !dbg [[DBG68:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(double [[A_SROA_0_0_A_SROA_0_0_D1]], [[META60:![0-9]+]], !DIExpression(), [[DBG68]])
-; CHECK-DEBUGLOC-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_D1]], ptr [[A_SROA_3]], align 1, !dbg [[DBG69:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: store volatile double [[A_SROA_0_0_A_SROA_0_0_D1]], ptr [[A_SROA_3]], align 8, !dbg [[DBG69:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr undef, [[META61:![0-9]+]], !DIExpression(), [[META70:![0-9]+]])
; CHECK-DEBUGLOC-NEXT: [[A_SROA_3_7_WEIRD_GEP2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_3]], i64 7, !dbg [[DBG71:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: [[A_SROA_3_7_A_SROA_3_16_WEIRD_LOAD2:%.*]] = load volatile i16, ptr [[A_SROA_3_7_WEIRD_GEP2_SROA_IDX]], align 1, !dbg [[DBG71]]
@@ -212,24 +212,24 @@ define void @test6() {
;
; CHECK-LABEL: @test6(
; CHECK-NEXT: entry:
-; 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: [[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: ret void
;
; CHECK-DEBUGLOC-LABEL: @test6(
; CHECK-DEBUGLOC-NEXT: entry:
-; 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: [[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: #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 1, !dbg [[DBG79:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: store volatile double 0.000000e+00, ptr [[A_SROA_0]], align 8, !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 1, !dbg [[DBG81:![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: #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 1, !dbg [[DBG82:![0-9]+]]
+; 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: ret void, !dbg [[DBG83:![0-9]+]]
;
entry:
@@ -292,43 +292,43 @@ entry:
define void @test8() {
; CHECK-LABEL: @test8(
-; CHECK-NEXT: [[PTR:%.*]] = alloca [5 x i32], align 1
+; CHECK-NEXT: [[PTR:%.*]] = alloca [5 x i32], align 4
; CHECK-NEXT: call void @populate(ptr [[PTR]])
; CHECK-NEXT: [[VAL_FCA_0_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 0
-; CHECK-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 1
+; CHECK-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 4
; CHECK-NEXT: [[VAL_FCA_0_INSERT:%.*]] = insertvalue [5 x i32] poison, i32 [[VAL_FCA_0_LOAD]], 0
; CHECK-NEXT: [[VAL_FCA_1_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 1
-; CHECK-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i32, ptr [[VAL_FCA_1_GEP]], align 1
+; CHECK-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i32, ptr [[VAL_FCA_1_GEP]], align 4
; CHECK-NEXT: [[VAL_FCA_1_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_0_INSERT]], i32 [[VAL_FCA_1_LOAD]], 1
; CHECK-NEXT: [[VAL_FCA_2_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 2
-; CHECK-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i32, ptr [[VAL_FCA_2_GEP]], align 1
+; CHECK-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i32, ptr [[VAL_FCA_2_GEP]], align 4
; CHECK-NEXT: [[VAL_FCA_2_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_1_INSERT]], i32 [[VAL_FCA_2_LOAD]], 2
; CHECK-NEXT: [[VAL_FCA_3_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 3
-; CHECK-NEXT: [[VAL_FCA_3_LOAD:%.*]] = load i32, ptr [[VAL_FCA_3_GEP]], align 1
+; CHECK-NEXT: [[VAL_FCA_3_LOAD:%.*]] = load i32, ptr [[VAL_FCA_3_GEP]], align 4
; CHECK-NEXT: [[VAL_FCA_3_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_2_INSERT]], i32 [[VAL_FCA_3_LOAD]], 3
; CHECK-NEXT: [[VAL_FCA_4_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 4
-; CHECK-NEXT: [[VAL_FCA_4_LOAD:%.*]] = load i32, ptr [[VAL_FCA_4_GEP]], align 1
+; CHECK-NEXT: [[VAL_FCA_4_LOAD:%.*]] = load i32, ptr [[VAL_FCA_4_GEP]], align 4
; CHECK-NEXT: [[VAL_FCA_4_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_3_INSERT]], i32 [[VAL_FCA_4_LOAD]], 4
; CHECK-NEXT: ret void
;
; CHECK-DEBUGLOC-LABEL: @test8(
-; CHECK-DEBUGLOC-NEXT: [[PTR:%.*]] = alloca [5 x i32], align 1, !dbg [[DBG102:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: [[PTR:%.*]] = alloca [5 x i32], align 4, !dbg [[DBG102:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[PTR]], [[META99:![0-9]+]], !DIExpression(), [[DBG102]])
; CHECK-DEBUGLOC-NEXT: call void @populate(ptr [[PTR]]), !dbg [[DBG103:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 0, !dbg [[DBG104:![0-9]+]]
-; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 1, !dbg [[DBG104]]
+; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 4, !dbg [[DBG104]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_INSERT:%.*]] = insertvalue [5 x i32] poison, i32 [[VAL_FCA_0_LOAD]], 0, !dbg [[DBG104]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 1, !dbg [[DBG104]]
-; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i32, ptr [[VAL_FCA_1_GEP]], align 1, !dbg [[DBG104]]
+; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i32, ptr [[VAL_FCA_1_GEP]], align 4, !dbg [[DBG104]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_0_INSERT]], i32 [[VAL_FCA_1_LOAD]], 1, !dbg [[DBG104]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 2, !dbg [[DBG104]]
-; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i32, ptr [[VAL_FCA_2_GEP]], align 1, !dbg [[DBG104]]
+; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i32, ptr [[VAL_FCA_2_GEP]], align 4, !dbg [[DBG104]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_1_INSERT]], i32 [[VAL_FCA_2_LOAD]], 2, !dbg [[DBG104]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 3, !dbg [[DBG104]]
-; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_LOAD:%.*]] = load i32, ptr [[VAL_FCA_3_GEP]], align 1, !dbg [[DBG104]]
+; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_LOAD:%.*]] = load i32, ptr [[VAL_FCA_3_GEP]], align 4, !dbg [[DBG104]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_2_INSERT]], i32 [[VAL_FCA_3_LOAD]], 3, !dbg [[DBG104]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_4_GEP:%.*]] = getelementptr inbounds [5 x i32], ptr [[PTR]], i32 0, i32 4, !dbg [[DBG104]]
-; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_4_LOAD:%.*]] = load i32, ptr [[VAL_FCA_4_GEP]], align 1, !dbg [[DBG104]]
+; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_4_LOAD:%.*]] = load i32, ptr [[VAL_FCA_4_GEP]], align 4, !dbg [[DBG104]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_4_INSERT:%.*]] = insertvalue [5 x i32] [[VAL_FCA_3_INSERT]], i32 [[VAL_FCA_4_LOAD]], 4, !dbg [[DBG104]]
; CHECK-DEBUGLOC-NEXT: #dbg_value([5 x i32] [[VAL_FCA_4_INSERT]], [[META100:![0-9]+]], !DIExpression(), [[DBG104]])
; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG105:![0-9]+]]
@@ -390,13 +390,13 @@ define void @test9() {
define void @test10() {
; CHECK-LABEL: @test10(
-; CHECK-NEXT: [[PTR:%.*]] = alloca { i32, i8, i8, { i8, i16 } }, align 2
+; CHECK-NEXT: [[PTR:%.*]] = alloca { i32, i8, i8, { i8, i16 } }, align 4
; CHECK-NEXT: call void @populate(ptr [[PTR]])
; CHECK-NEXT: [[VAL_FCA_0_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 0
-; CHECK-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 2
+; CHECK-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 4
; CHECK-NEXT: [[VAL_FCA_0_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } poison, i32 [[VAL_FCA_0_LOAD]], 0
; CHECK-NEXT: [[VAL_FCA_1_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 1
-; CHECK-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i8, ptr [[VAL_FCA_1_GEP]], align 2
+; CHECK-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i8, ptr [[VAL_FCA_1_GEP]], align 4
; CHECK-NEXT: [[VAL_FCA_1_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_0_INSERT]], i8 [[VAL_FCA_1_LOAD]], 1
; CHECK-NEXT: [[VAL_FCA_2_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 2
; CHECK-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i8, ptr [[VAL_FCA_2_GEP]], align 1
@@ -405,19 +405,19 @@ define void @test10() {
; CHECK-NEXT: [[VAL_FCA_3_0_LOAD:%.*]] = load i8, ptr [[VAL_FCA_3_0_GEP]], align 2
; CHECK-NEXT: [[VAL_FCA_3_0_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_2_INSERT]], i8 [[VAL_FCA_3_0_LOAD]], 3, 0
; CHECK-NEXT: [[VAL_FCA_3_1_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 3, i32 1
-; CHECK-NEXT: [[VAL_FCA_3_1_LOAD:%.*]] = load i16, ptr [[VAL_FCA_3_1_GEP]], align 2
+; CHECK-NEXT: [[VAL_FCA_3_1_LOAD:%.*]] = load i16, ptr [[VAL_FCA_3_1_GEP]], align 4
; CHECK-NEXT: [[VAL_FCA_3_1_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_3_0_INSERT]], i16 [[VAL_FCA_3_1_LOAD]], 3, 1
; CHECK-NEXT: ret void
;
; CHECK-DEBUGLOC-LABEL: @test10(
-; CHECK-DEBUGLOC-NEXT: [[PTR:%.*]] = alloca { i32, i8, i8, { i8, i16 } }, align 2, !dbg [[DBG119:![0-9]+]]
+; CHECK-DEBUGLOC-NEXT: [[PTR:%.*]] = alloca { i32, i8, i8, { i8, i16 } }, align 4, !dbg [[DBG119:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: #dbg_value(ptr [[PTR]], [[META116:![0-9]+]], !DIExpression(), [[DBG119]])
; CHECK-DEBUGLOC-NEXT: call void @populate(ptr [[PTR]]), !dbg [[DBG120:![0-9]+]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 0, !dbg [[DBG121:![0-9]+]]
-; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 2, !dbg [[DBG121]]
+; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_LOAD:%.*]] = load i32, ptr [[VAL_FCA_0_GEP]], align 4, !dbg [[DBG121]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_0_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } poison, i32 [[VAL_FCA_0_LOAD]], 0, !dbg [[DBG121]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 1, !dbg [[DBG121]]
-; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i8, ptr [[VAL_FCA_1_GEP]], align 2, !dbg [[DBG121]]
+; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_LOAD:%.*]] = load i8, ptr [[VAL_FCA_1_GEP]], align 4, !dbg [[DBG121]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_1_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_0_INSERT]], i8 [[VAL_FCA_1_LOAD]], 1, !dbg [[DBG121]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 2, !dbg [[DBG121]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_2_LOAD:%.*]] = load i8, ptr [[VAL_FCA_2_GEP]], align 1, !dbg [[DBG121]]
@@ -426,7 +426,7 @@ define void @test10() {
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_0_LOAD:%.*]] = load i8, ptr [[VAL_FCA_3_0_GEP]], align 2, !dbg [[DBG121]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_0_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_2_INSERT]], i8 [[VAL_FCA_3_0_LOAD]], 3, 0, !dbg [[DBG121]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_1_GEP:%.*]] = getelementptr inbounds { i32, i8, i8, { i8, i16 } }, ptr [[PTR]], i32 0, i32 3, i32 1, !dbg [[DBG121]]
-; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_1_LOAD:%.*]] = load i16, ptr [[VAL_FCA_3_1_GEP]], align 2, !dbg [[DBG121]]
+; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_1_LOAD:%.*]] = load i16, ptr [[VAL_FCA_3_1_GEP]], align 4, !dbg [[DBG121]]
; CHECK-DEBUGLOC-NEXT: [[VAL_FCA_3_1_INSERT:%.*]] = insertvalue { i32, i8, i8, { i8, i16 } } [[VAL_FCA_3_0_INSERT]], i16 [[VAL_FCA_3_1_LOAD]], 3, 1, !dbg [[DBG121]]
; CHECK-DEBUGLOC-NEXT: #dbg_value({ i32, i8, i8, { i8, i16 } } [[VAL_FCA_3_1_INSERT]], [[META117:![0-9]+]], !DIExpression(), [[DBG121]])
; CHECK-DEBUGLOC-NEXT: ret void, !dbg [[DBG122:![0-9]+]]
diff --git a/llvm/test/Transforms/SROA/basictest.ll b/llvm/test/Transforms/SROA/basictest.ll
index 516d36295e1391..f0adf64f4a35bd 100644
--- a/llvm/test/Transforms/SROA/basictest.ll
+++ b/llvm/test/Transforms/SROA/basictest.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
-; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
+; RUN: opt < %s -passes='sroa<preserve-cfg>,infer-alignment' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
+; RUN: opt < %s -passes='sroa<modify-cfg>,infer-alignment' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
@@ -109,13 +109,13 @@ L2:
define i64 @test2_addrspacecast_gep_offset(i64 %X) {
; CHECK-LABEL: @test2_addrspacecast_gep_offset(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [10 x i8], align 1
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [10 x i8], align 8
; CHECK-NEXT: [[A_SROA_0_2_GEPB_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_0]], i16 2
; CHECK-NEXT: [[A_SROA_0_2_GEPB_SROA_CAST:%.*]] = addrspacecast ptr [[A_SROA_0_2_GEPB_SROA_IDX]] to ptr addrspace(1)
; CHECK-NEXT: store i64 [[X:%.*]], ptr addrspace(1) [[A_SROA_0_2_GEPB_SROA_CAST]], align 1
; CHECK-NEXT: br label [[L2:%.*]]
; CHECK: L2:
-; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_30_Z:%.*]] = load i64, ptr [[A_SROA_0]], align 1
+; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_30_Z:%.*]] = load i64, ptr [[A_SROA_0]], align 8
; CHECK-NEXT: ret i64 [[A_SROA_0_0_A_SROA_0_30_Z]]
;
entry:
@@ -136,10 +136,10 @@ define void @test3(ptr %dst, ptr align 8 %src) {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca [42 x i8], align 1
; CHECK-NEXT: [[A_SROA_3:%.*]] = alloca [99 x i8], align 1
-; CHECK-NEXT: [[A_SROA_32:%.*]] = alloca [16 x i8], align 1
+; CHECK-NEXT: [[A_SROA_32:%.*]] = alloca [16 x i8], align 8
; CHECK-NEXT: [[A_SROA_15:%.*]] = alloca [42 x i8], align 1
-; CHECK-NEXT: [[A_SROA_16:%.*]] = alloca [7 x i8], align 1
-; CHECK-NEXT: [[A_SROA_235:%.*]] = alloca [7 x i8], align 1
+; CHECK-NEXT: [[A_SROA_16:%.*]] = alloca [7 x i8], align 4
+; CHECK-NEXT: [[A_SROA_235:%.*]] = alloca [7 x i8], align 4
; CHECK-NEXT: [[A_SROA_31:%.*]] = alloca [85 x i8], align 1
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_0]], ptr align 8 [[SRC:%.*]], i32 42, i1 false), !tbaa [[TBAA0:![0-9]+]]
; CHECK-NEXT: [[A_SROA_2_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 42
@@ -147,47 +147,47 @@ define void @test3(ptr %dst, ptr align 8 %src) {
; CHECK-NEXT: [[A_SROA_3_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 43
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_3]], ptr align 1 [[A_SROA_3_0_SRC_SROA_IDX]], i32 99, i1 false), !tbaa [[TBAA0]]
; CHECK-NEXT: [[A_SROA_32_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 142
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_32]], ptr align 2 [[A_SROA_32_0_SRC_SROA_IDX]], i32 16, i1 false), !tbaa [[TBAA0]]
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[A_SROA_32]], ptr align 2 [[A_SROA_32_0_SRC_SROA_IDX]], i32 16, i1 false), !tbaa [[TBAA0]]
; CHECK-NEXT: [[A_SROA_15_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 158
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_15]], ptr align 2 [[A_SROA_15_0_SRC_SROA_IDX]], i32 42, i1 false), !tbaa [[TBAA0]]
; CHECK-NEXT: [[A_SROA_16_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 200
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_16]], ptr align 8 [[A_SROA_16_0_SRC_SROA_IDX]], i32 7, i1 false), !tbaa [[TBAA0]]
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A_SROA_16]], ptr align 8 [[A_SROA_16_0_SRC_SROA_IDX]], i32 7, i1 false), !tbaa [[TBAA0]]
; CHECK-NEXT: [[A_SROA_23_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 207
; CHECK-NEXT: [[A_SROA_23_0_COPYLOAD:%.*]] = load i8, ptr [[A_SROA_23_0_SRC_SROA_IDX]], align 1, !tbaa [[TBAA0]]
; CHECK-NEXT: [[A_SROA_235_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 208
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_235]], ptr align 8 [[A_SROA_235_0_SRC_SROA_IDX]], i32 7, i1 false), !tbaa [[TBAA0]]
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A_SROA_235]], ptr align 8 [[A_SROA_235_0_SRC_SROA_IDX]], i32 7, i1 false), !tbaa [[TBAA0]]
; CHECK-NEXT: [[A_SROA_31_0_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 215
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_31]], ptr align 1 [[A_SROA_31_0_SRC_SROA_IDX]], i32 85, i1 false), !tbaa [[TBAA0]]
-; CHECK-NEXT: store i8 1, ptr [[A_SROA_32]], align 1, !tbaa [[TBAA3:![0-9]+]]
-; CHECK-NEXT: store i16 1, ptr [[A_SROA_32]], align 1, !tbaa [[TBAA5:![0-9]+]]
-; CHECK-NEXT: store i32 1, ptr [[A_SROA_32]], align 1, !tbaa [[TBAA7:![0-9]+]]
-; CHECK-NEXT: store i64 1, ptr [[A_SROA_32]], align 1, !tbaa [[TBAA9:![0-9]+]]
+; CHECK-NEXT: store i8 1, ptr [[A_SROA_32]], align 8, !tbaa [[TBAA3:![0-9]+]]
+; CHECK-NEXT: store i16 1, ptr [[A_SROA_32]], align 8, !tbaa [[TBAA5:![0-9]+]]
+; CHECK-NEXT: store i32 1, ptr [[A_SROA_32]], align 8, !tbaa [[TBAA7:![0-9]+]]
+; CHECK-NEXT: store i64 1, ptr [[A_SROA_32]], align 8, !tbaa [[TBAA9:![0-9]+]]
; CHECK-NEXT: [[A_SROA_32_1_OVERLAP_2_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 1
; CHECK-NEXT: store i64 2, ptr [[A_SROA_32_1_OVERLAP_2_I8_SROA_IDX]], align 1, !tbaa [[TBAA11:![0-9]+]]
; CHECK-NEXT: [[A_SROA_32_2_OVERLAP_3_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 2
-; CHECK-NEXT: store i64 3, ptr [[A_SROA_32_2_OVERLAP_3_I8_SROA_IDX]], align 1, !tbaa [[TBAA13:![0-9]+]]
+; CHECK-NEXT: store i64 3, ptr [[A_SROA_32_2_OVERLAP_3_I8_SROA_IDX]], align 2, !tbaa [[TBAA13:![0-9]+]]
; CHECK-NEXT: [[A_SROA_32_3_OVERLAP_4_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 3
; CHECK-NEXT: store i64 4, ptr [[A_SROA_32_3_OVERLAP_4_I8_SROA_IDX]], align 1, !tbaa [[TBAA15:![0-9]+]]
; CHECK-NEXT: [[A_SROA_32_4_OVERLAP_5_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 4
-; CHECK-NEXT: store i64 5, ptr [[A_SROA_32_4_OVERLAP_5_I8_SROA_IDX]], align 1, !tbaa [[TBAA17:![0-9]+]]
+; CHECK-NEXT: store i64 5, ptr [[A_SROA_32_4_OVERLAP_5_I8_SROA_IDX]], align 4, !tbaa [[TBAA17:![0-9]+]]
; CHECK-NEXT: [[A_SROA_32_5_OVERLAP_6_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 5
; CHECK-NEXT: store i64 6, ptr [[A_SROA_32_5_OVERLAP_6_I8_SROA_IDX]], align 1, !tbaa [[TBAA19:![0-9]+]]
; CHECK-NEXT: [[A_SROA_32_6_OVERLAP_7_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 6
-; CHECK-NEXT: store i64 7, ptr [[A_SROA_32_6_OVERLAP_7_I8_SROA_IDX]], align 1, !tbaa [[TBAA21:![0-9]+]]
+; CHECK-NEXT: store i64 7, ptr [[A_SROA_32_6_OVERLAP_7_I8_SROA_IDX]], align 2, !tbaa [[TBAA21:![0-9]+]]
; CHECK-NEXT: [[A_SROA_32_7_OVERLAP_8_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 7
; CHECK-NEXT: store i64 8, ptr [[A_SROA_32_7_OVERLAP_8_I8_SROA_IDX]], align 1, !tbaa [[TBAA23:![0-9]+]]
; CHECK-NEXT: [[A_SROA_32_8_OVERLAP_9_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_32]], i64 8
-; CHECK-NEXT: store i64 9, ptr [[A_SROA_32_8_OVERLAP_9_I8_SROA_IDX]], align 1, !tbaa [[TBAA25:![0-9]+]]
-; CHECK-NEXT: store i8 1, ptr [[A_SROA_16]], align 1, !tbaa [[TBAA27:![0-9]+]]
-; CHECK-NEXT: store i16 1, ptr [[A_SROA_16]], align 1, !tbaa [[TBAA29:![0-9]+]]
-; CHECK-NEXT: store i32 1, ptr [[A_SROA_16]], align 1, !tbaa [[TBAA31:![0-9]+]]
+; CHECK-NEXT: store i64 9, ptr [[A_SROA_32_8_OVERLAP_9_I8_SROA_IDX]], align 8, !tbaa [[TBAA25:![0-9]+]]
+; CHECK-NEXT: store i8 1, ptr [[A_SROA_16]], align 4, !tbaa [[TBAA27:![0-9]+]]
+; CHECK-NEXT: store i16 1, ptr [[A_SROA_16]], align 4, !tbaa [[TBAA29:![0-9]+]]
+; CHECK-NEXT: store i32 1, ptr [[A_SROA_16]], align 4, !tbaa [[TBAA31:![0-9]+]]
; CHECK-NEXT: [[A_SROA_16_1_OVERLAP2_1_1_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_16]], i64 1
; CHECK-NEXT: store i32 2, ptr [[A_SROA_16_1_OVERLAP2_1_1_I8_SROA_IDX]], align 1, !tbaa [[TBAA33:![0-9]+]]
; CHECK-NEXT: [[A_SROA_16_2_OVERLAP2_1_2_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_16]], i64 2
-; CHECK-NEXT: store i32 3, ptr [[A_SROA_16_2_OVERLAP2_1_2_I8_SROA_IDX]], align 1, !tbaa [[TBAA35:![0-9]+]]
+; CHECK-NEXT: store i32 3, ptr [[A_SROA_16_2_OVERLAP2_1_2_I8_SROA_IDX]], align 2, !tbaa [[TBAA35:![0-9]+]]
; CHECK-NEXT: [[A_SROA_16_3_OVERLAP2_1_3_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_16]], i64 3
; CHECK-NEXT: store i32 4, ptr [[A_SROA_16_3_OVERLAP2_1_3_I8_SROA_IDX]], align 1, !tbaa [[TBAA37:![0-9]+]]
-; CHECK-NEXT: store i32 1, ptr [[A_SROA_235]], align 1, !tbaa [[TBAA39:![0-9]+]]
+; CHECK-NEXT: store i32 1, ptr [[A_SROA_235]], align 4, !tbaa [[TBAA39:![0-9]+]]
; CHECK-NEXT: [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX11:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 1
; CHECK-NEXT: store i8 1, ptr [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX11]], align 1, !tbaa [[TBAA41:![0-9]+]]
; CHECK-NEXT: [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX10:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 1
@@ -195,20 +195,20 @@ define void @test3(ptr %dst, ptr align 8 %src) {
; CHECK-NEXT: [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 1
; CHECK-NEXT: store i32 1, ptr [[A_SROA_235_1_OVERLAP2_2_1_I8_SROA_IDX]], align 1, !tbaa [[TBAA45:![0-9]+]]
; CHECK-NEXT: [[A_SROA_235_2_OVERLAP2_2_2_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 2
-; CHECK-NEXT: store i32 3, ptr [[A_SROA_235_2_OVERLAP2_2_2_I8_SROA_IDX]], align 1, !tbaa [[TBAA47:![0-9]+]]
+; CHECK-NEXT: store i32 3, ptr [[A_SROA_235_2_OVERLAP2_2_2_I8_SROA_IDX]], align 2, !tbaa [[TBAA47:![0-9]+]]
; CHECK-NEXT: [[A_SROA_235_3_OVERLAP2_2_3_I8_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 3
; CHECK-NEXT: store i32 4, ptr [[A_SROA_235_3_OVERLAP2_2_3_I8_SROA_IDX]], align 1, !tbaa [[TBAA49:![0-9]+]]
; CHECK-NEXT: [[A_SROA_15_197_OVERLAP2_PREFIX_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_15]], i64 39
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_15_197_OVERLAP2_PREFIX_SROA_IDX]], ptr align 1 [[SRC]], i32 3, i1 false), !tbaa [[TBAA51:![0-9]+]]
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_15_197_OVERLAP2_PREFIX_SROA_IDX]], ptr align 8 [[SRC]], i32 3, i1 false), !tbaa [[TBAA51:![0-9]+]]
; CHECK-NEXT: [[A_SROA_16_197_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 3
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_16]], ptr align 1 [[A_SROA_16_197_SRC_SROA_IDX]], i32 5, i1 false), !tbaa [[TBAA51]]
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[A_SROA_16]], ptr align 1 [[A_SROA_16_197_SRC_SROA_IDX]], i32 5, i1 false), !tbaa [[TBAA51]]
; CHECK-NEXT: [[A_SROA_16_2_OVERLAP2_1_2_I8_SROA_IDX12:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_16]], i64 2
-; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 [[A_SROA_16_2_OVERLAP2_1_2_I8_SROA_IDX12]], i8 42, i32 5, i1 false), !tbaa [[TBAA53:![0-9]+]]
-; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 1 [[A_SROA_235]], i8 42, i32 2, i1 false), !tbaa [[TBAA53]]
+; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 2 [[A_SROA_16_2_OVERLAP2_1_2_I8_SROA_IDX12]], i8 42, i32 5, i1 false), !tbaa [[TBAA53:![0-9]+]]
+; CHECK-NEXT: call void @llvm.memset.p0.i32(ptr align 4 [[A_SROA_235]], i8 42, i32 2, i1 false), !tbaa [[TBAA53]]
; CHECK-NEXT: [[A_SROA_235_209_OVERLAP2_2_1_I8_SROA_IDX8:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 1
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_235_209_OVERLAP2_2_1_I8_SROA_IDX8]], ptr align 1 [[SRC]], i32 5, i1 false), !tbaa [[TBAA55:![0-9]+]]
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_235_209_OVERLAP2_2_1_I8_SROA_IDX8]], ptr align 8 [[SRC]], i32 5, i1 false), !tbaa [[TBAA55:![0-9]+]]
; CHECK-NEXT: [[A_SROA_235_210_OVERLAP2_2_2_I8_SROA_IDX9:%.*]] = getelementptr inbounds i8, ptr [[A_SROA_235]], i64 2
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_235_210_OVERLAP2_2_2_I8_SROA_IDX9]], ptr align 1 [[SRC]], i32 5, i1 false), !tbaa [[TBAA57:![0-9]+]]
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 2 [[A_SROA_235_210_OVERLAP2_2_2_I8_SROA_IDX9]], ptr align 8 [[SRC]], i32 5, i1 false), !tbaa [[TBAA57:![0-9]+]]
; CHECK-NEXT: [[A_SROA_31_210_SRC_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[SRC]], i64 5
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_31]], ptr align 1 [[A_SROA_31_210_SRC_SROA_IDX]], i32 3, i1 false), !tbaa [[TBAA57]]
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[DST:%.*]], ptr align 1 [[A_SROA_0]], i32 42, i1 false), !tbaa [[TBAA59:![0-9]+]]
@@ -217,15 +217,15 @@ define void @test3(ptr %dst, ptr align 8 %src) {
; CHECK-NEXT: [[A_SROA_3_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 43
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_3_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_3]], i32 99, i1 false), !tbaa [[TBAA59]]
; CHECK-NEXT: [[A_SROA_32_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 142
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_32_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_32]], i32 16, i1 false), !tbaa [[TBAA59]]
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_32_0_DST_SROA_IDX]], ptr align 8 [[A_SROA_32]], i32 16, i1 false), !tbaa [[TBAA59]]
; CHECK-NEXT: [[A_SROA_15_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 158
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_15_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_15]], i32 42, i1 false), !tbaa [[TBAA59]]
; CHECK-NEXT: [[A_SROA_16_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 200
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_16_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_16]], i32 7, i1 false), !tbaa [[TBAA59]]
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_16_0_DST_SROA_IDX]], ptr align 4 [[A_SROA_16]], i32 7, i1 false), !tbaa [[TBAA59]]
; CHECK-NEXT: [[A_SROA_23_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 207
; CHECK-NEXT: store i8 42, ptr [[A_SROA_23_0_DST_SROA_IDX]], align 1, !tbaa [[TBAA59]]
; CHECK-NEXT: [[A_SROA_235_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 208
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_235_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_235]], i32 7, i1 false), !tbaa [[TBAA59]]
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_235_0_DST_SROA_IDX]], ptr align 4 [[A_SROA_235]], i32 7, i1 false), !tbaa [[TBAA59]]
; CHECK-NEXT: [[A_SROA_31_0_DST_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 215
; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[A_SROA_31_0_DST_SROA_IDX]], ptr align 1 [[A_SROA_31]], i32 85, i1 false), !tbaa [[TBAA59]]
; CHECK-NEXT: ret void
@@ -427,9 +427,9 @@ entry:
define i32 @test6() {
; CHECK-LABEL: @test6(
; CHECK-NEXT: entry:
-; 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: [[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: 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 1
+; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i32, align 4
; 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 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_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_A_SROA_0_0_COPYLOAD1]], ptr [[DST:%.*]], align 1, !tbaa [[TBAA3]]
; CHECK-NEXT: ret void
;
@@ -1521,7 +1521,7 @@ define void @PR16651.2(<2 x float> %val, i1 %c1) {
; CHECK-MODIFY-CFG-NEXT: [[TV1_SROA_0_0_VEC_EXTRACT:%.*]] = extractelement <2 x float> [[VAL:%.*]], i64 0
; CHECK-MODIFY-CFG-NEXT: br i1 [[C1:%.*]], label [[ENTRY_THEN:%.*]], label [[ENTRY_CONT:%.*]]
; CHECK-MODIFY-CFG: entry.then:
-; CHECK-MODIFY-CFG-NEXT: [[COND105_I_I_THEN_VAL:%.*]] = load float, ptr null, align 8
+; CHECK-MODIFY-CFG-NEXT: [[COND105_I_I_THEN_VAL:%.*]] = load float, ptr null, align 4294967296
; CHECK-MODIFY-CFG-NEXT: br label [[ENTRY_CONT]]
; CHECK-MODIFY-CFG: entry.cont:
; CHECK-MODIFY-CFG-NEXT: [[COND105_I_I:%.*]] = phi float [ [[COND105_I_I_THEN_VAL]], [[ENTRY_THEN]] ], [ [[TV1_SROA_0_0_VEC_EXTRACT]], [[ENTRY:%.*]] ]
@@ -1967,8 +1967,8 @@ bb7:
define i32 @load_atomic_volatile_past_end() {
; CHECK-LABEL: @load_atomic_volatile_past_end(
-; CHECK-NEXT: [[A:%.*]] = alloca i1, align 1
-; CHECK-NEXT: [[A_0_V:%.*]] = load atomic volatile i32, ptr [[A]] seq_cst, align 1
+; CHECK-NEXT: [[A:%.*]] = alloca i1, align 4
+; CHECK-NEXT: [[A_0_V:%.*]] = load atomic volatile i32, ptr [[A]] seq_cst, align 4
; CHECK-NEXT: ret i32 [[A_0_V]]
;
%a = alloca i1, align 1
@@ -1978,8 +1978,8 @@ define i32 @load_atomic_volatile_past_end() {
define i32 @load_volatile_past_end() {
; CHECK-LABEL: @load_volatile_past_end(
-; CHECK-NEXT: [[A:%.*]] = alloca i1, align 1
-; CHECK-NEXT: [[A_0_V:%.*]] = load volatile i32, ptr [[A]], align 1
+; CHECK-NEXT: [[A:%.*]] = alloca i1, align 4
+; CHECK-NEXT: [[A_0_V:%.*]] = load volatile i32, ptr [[A]], align 4
; CHECK-NEXT: ret i32 [[A_0_V]]
;
%a = alloca i1, align 1
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 de73c6a6ff271d..1a96e165a61bef 100644
--- a/llvm/test/Transforms/SROA/non-integral-pointer-vector-memset.ll
+++ b/llvm/test/Transforms/SROA/non-integral-pointer-vector-memset.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
-; RUN: opt -passes=sroa -S %s | FileCheck %s
+; RUN: opt -passes=sroa,infer-alignment -S %s | FileCheck %s
target datalayout = "e-ni:10"
@@ -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 8
-; CHECK-NEXT: store <2 x ptr addrspace(10)> [[V]], ptr [[A_SROA_0]], align 8
+; 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_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 8
+; 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: 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 ddf52d5f69aa22..d665b2282bc14e 100644
--- a/llvm/test/Transforms/SROA/phi-gep.ll
+++ b/llvm/test/Transforms/SROA/phi-gep.ll
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals
-; RUN: opt -S -passes='sroa<preserve-cfg>' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
-; RUN: opt -S -passes='sroa<modify-cfg>' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
+; RUN: opt -S -passes='sroa<preserve-cfg>,infer-alignment' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
+; RUN: opt -S -passes='sroa<modify-cfg>,infer-alignment' < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
%pair = type { i32, i32 }
@@ -568,8 +568,8 @@ define i64 @test_phi_idx_mem2reg_not_const(i1 %arg, i64 %idx) {
; CHECK-NEXT: bb:
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [2 x i64], align 8
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i64, ptr [[ALLOCA]], i64 1
-; CHECK-NEXT: store i64 2, ptr [[ALLOCA]], align 4
-; CHECK-NEXT: store i64 3, ptr [[GEP1]], align 4
+; CHECK-NEXT: store i64 2, ptr [[ALLOCA]], align 8
+; CHECK-NEXT: store i64 3, ptr [[GEP1]], align 8
; CHECK-NEXT: br i1 [[ARG:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
; CHECK-NEXT: br label [[END:%.*]]
@@ -578,7 +578,7 @@ define i64 @test_phi_idx_mem2reg_not_const(i1 %arg, i64 %idx) {
; CHECK: end:
; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ 0, [[BB1]] ], [ [[IDX:%.*]], [[BB2]] ]
; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr inbounds i64, ptr [[ALLOCA]], i64 [[PHI]]
-; CHECK-NEXT: [[LOAD:%.*]] = load i64, ptr [[GETELEMENTPTR]], align 4
+; CHECK-NEXT: [[LOAD:%.*]] = load i64, ptr [[GETELEMENTPTR]], align 8
; CHECK-NEXT: ret i64 [[LOAD]]
;
bb:
@@ -606,8 +606,8 @@ define i64 @test_phi_mem2reg_pointer_op_is_non_const_gep(i1 %arg, i64 %idx) {
; CHECK-NEXT: bb:
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [2 x i64], align 8
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i64, ptr [[ALLOCA]], i64 1
-; CHECK-NEXT: store i64 2, ptr [[ALLOCA]], align 4
-; CHECK-NEXT: store i64 3, ptr [[GEP1]], align 4
+; CHECK-NEXT: store i64 2, ptr [[ALLOCA]], align 8
+; CHECK-NEXT: store i64 3, ptr [[GEP1]], align 8
; CHECK-NEXT: br i1 [[ARG:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
; CHECK: bb1:
; CHECK-NEXT: br label [[END:%.*]]
@@ -617,7 +617,7 @@ define i64 @test_phi_mem2reg_pointer_op_is_non_const_gep(i1 %arg, i64 %idx) {
; CHECK-NEXT: [[PHI:%.*]] = phi i64 [ 0, [[BB1]] ], [ 1, [[BB2]] ]
; CHECK-NEXT: [[GETELEMENTPTR:%.*]] = getelementptr inbounds i64, ptr [[ALLOCA]], i64 [[IDX:%.*]]
; CHECK-NEXT: [[GETELEMENTPTR2:%.*]] = getelementptr inbounds i64, ptr [[GETELEMENTPTR]], i64 [[PHI]]
-; CHECK-NEXT: [[LOAD:%.*]] = load i64, ptr [[GETELEMENTPTR]], align 4
+; CHECK-NEXT: [[LOAD:%.*]] = load i64, ptr [[GETELEMENTPTR]], align 8
; CHECK-NEXT: ret i64 [[LOAD]]
;
bb:
@@ -674,11 +674,11 @@ define i32 @test_phi_mem2reg_alloca_not_in_entry_block(i1 %arg) {
; CHECK-LABEL: @test_phi_mem2reg_alloca_not_in_entry_block(
; CHECK-NEXT: bb:
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i64, align 8
-; CHECK-NEXT: store i64 123, ptr [[ALLOCA]], align 4
+; CHECK-NEXT: store i64 123, ptr [[ALLOCA]], align 8
; CHECK-NEXT: br label [[BB2:%.*]]
; CHECK: bb2:
; CHECK-NEXT: [[ALLOCA2:%.*]] = alloca i64, align 8
-; CHECK-NEXT: store i64 124, ptr [[ALLOCA]], align 4
+; CHECK-NEXT: store i64 124, ptr [[ALLOCA]], align 8
; CHECK-NEXT: br i1 [[ARG:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
; CHECK: bb3:
; CHECK-NEXT: br label [[BB4]]
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 c3a02e48c8ef6a..de870f7a0f6dcf 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
@@ -1,6 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
-; RUN: opt -passes=sroa -S %s | FileCheck %s --check-prefixes=NO-CANON
-; RUN: opt -passes='sroa<aggregate-to-vector>' -S %s | FileCheck %s --check-prefixes=CANON
+; RUN: opt -passes=sroa,infer-alignment -S %s | FileCheck %s --check-prefixes=NO-CANON
+; RUN: opt -passes='sroa<aggregate-to-vector>,infer-alignment' -S %s | FileCheck %s --check-prefixes=CANON
%class.aiMatrix4x4t = type { float, float, float, float, float, float, float, float, float, float, float, float, float, float, float, float }
@@ -24,17 +24,17 @@ define ptr @store_only_fp_tail() {
; 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 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 4 [[DOTSROA_4]], i64 44, i1 false)
+; NO-CANON-NEXT: store float 0.000000e+00, ptr null, align 4294967296
+; NO-CANON-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 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 16
+; NO-CANON-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 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() {
; CANON-NEXT: [[DST_SROA_0_0_VEC_INSERT:%.*]] = insertelement <4 x float> undef, float 0.000000e+00, i64 0
-; CANON-NEXT: store <4 x float> [[DST_SROA_0_0_VEC_INSERT]], ptr null, align 1
-; CANON-NEXT: store float 0.000000e+00, ptr getelementptr inbounds (i8, ptr null, i64 16), align 1
-; CANON-NEXT: store <11 x float> undef, ptr getelementptr inbounds (i8, ptr null, i64 20), align 1
+; CANON-NEXT: store <4 x float> [[DST_SROA_0_0_VEC_INSERT]], ptr null, align 4294967296
+; CANON-NEXT: store float 0.000000e+00, ptr getelementptr inbounds (i8, ptr null, i64 16), align 16
+; CANON-NEXT: store <11 x float> undef, ptr getelementptr inbounds (i8, ptr null, i64 20), align 4
; CANON-NEXT: ret ptr null
;
%dst = alloca %class.aiMatrix4x4t, align 4
diff --git a/llvm/test/Transforms/SROA/struct-to-vector.ll b/llvm/test/Transforms/SROA/struct-to-vector.ll
index bd236749d522a1..a5e912d51e9a05 100644
--- a/llvm/test/Transforms/SROA/struct-to-vector.ll
+++ b/llvm/test/Transforms/SROA/struct-to-vector.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
-; RUN: opt -passes='sroa<aggregate-to-vector>,gvn,instcombine,simplifycfg' -S %s | FileCheck %s
+; RUN: opt -passes='sroa<aggregate-to-vector>,infer-alignment,gvn,instcombine,simplifycfg' -S %s | FileCheck %s
%struct.myint4 = type { i32, i32, i32, i32 }
define dso_local void @foo_flat(ptr noundef %x, i64 %y.coerce0, i64 %y.coerce1, i32 noundef %cond) {
@@ -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 4
+; CHECK-NEXT: [[E_SROA_0:%.*]] = alloca <3 x i32>, align 16
; 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 4
+; CHECK-NEXT: store volatile <3 x i32> [[E_SROA_0_0_COPYLOAD]], ptr [[E_SROA_0]], align 16
; CHECK-NEXT: ret void
;
entry:
diff --git a/llvm/test/Transforms/SROA/tbaa-struct3.ll b/llvm/test/Transforms/SROA/tbaa-struct3.ll
index d9aca1b6c0df23..606cd40a99a4b9 100644
--- a/llvm/test/Transforms/SROA/tbaa-struct3.ll
+++ b/llvm/test/Transforms/SROA/tbaa-struct3.ll
@@ -1,5 +1,5 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
-; RUN: opt -p sroa -S %s | FileCheck %s
+; RUN: opt -p sroa,infer-alignment -S %s | FileCheck %s
target datalayout = "e-p:64:64:64-p1:16:16:16-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
@@ -73,11 +73,11 @@ define void @load_store_transfer_split_struct_tbaa_2_i31(ptr dereferenceable(24)
; CHECK-LABEL: define void @load_store_transfer_split_struct_tbaa_2_i31(
; CHECK-SAME: ptr dereferenceable(24) [[RES:%.*]], i31 [[A:%.*]], i31 [[B:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
-; CHECK-NEXT: [[TMP:%.*]] = alloca { i31, i31 }, align 4
-; CHECK-NEXT: store i31 [[A]], ptr [[TMP]], align 4
+; CHECK-NEXT: [[TMP:%.*]] = alloca { i31, i31 }, align 8
+; CHECK-NEXT: store i31 [[A]], ptr [[TMP]], align 8
; CHECK-NEXT: [[TMP_4_TMP_4_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[TMP]], i64 4
; CHECK-NEXT: store i31 [[B]], ptr [[TMP_4_TMP_4_SROA_IDX]], align 4
-; CHECK-NEXT: [[TMP_0_L1:%.*]] = load i62, ptr [[TMP]], align 4, !tbaa.struct [[TBAA_STRUCT4:![0-9]+]]
+; CHECK-NEXT: [[TMP_0_L1:%.*]] = load i62, ptr [[TMP]], align 8, !tbaa.struct [[TBAA_STRUCT4:![0-9]+]]
; CHECK-NEXT: store i62 [[TMP_0_L1]], ptr [[RES]], align 4, !tbaa.struct [[TBAA_STRUCT4]]
; CHECK-NEXT: ret void
;
@@ -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 1
+; CHECK-NEXT: [[A_SROA_3:%.*]] = alloca i16, align 2
; 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 1
+; CHECK-NEXT: store i16 [[A_SROA_3_0_COPYLOAD]], ptr [[A_SROA_3]], align 2
; 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 1
+; CHECK-NEXT: store i16 1, ptr [[A_SROA_3]], align 2
; 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 1, !tbaa [[FLOAT_TBAA0]]
+; CHECK-NEXT: store i16 10794, ptr [[A_SROA_3]], align 2, !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 1
+; CHECK-NEXT: [[A_SROA_3_0_A_SROA_3_0_COPYLOAD1:%.*]] = load volatile i16, ptr [[A_SROA_3]], align 2
; 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 1
+; CHECK-NEXT: [[A_SROA_2_SROA_0:%.*]] = alloca <2 x i8>, align 2
; 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 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_COPYLOAD]], ptr [[A_SROA_2_SROA_0]], align 2
+; CHECK-NEXT: store <2 x i8> bitcast (<1 x i16> splat (i16 123) to <2 x i8>), ptr [[A_SROA_2_SROA_0]], align 2
+; 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 2
; 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 1
+; 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 2
; 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 1
+; CHECK-NEXT: [[A_SROA_0_SROA_1:%.*]] = alloca <2 x i8>, align 2
; 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 1
+; CHECK-NEXT: store <2 x i8> [[A_SROA_0_SROA_1_1_COPYLOAD]], ptr [[A_SROA_0_SROA_1]], align 2
; 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 1
+; CHECK-NEXT: store <2 x i8> zeroinitializer, ptr [[A_SROA_0_SROA_1]], align 2
; 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 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: 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 1
+; 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: 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 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: [[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: 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 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: [[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: 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 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: [[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: 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 e69ea28a17c409..df9a1d5de5416a 100644
--- a/llvm/test/Transforms/SROA/vector-promotion.ll
+++ b/llvm/test/Transforms/SROA/vector-promotion.ll
@@ -1,7 +1,7 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes='sroa<preserve-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
-; RUN: opt < %s -passes='sroa<modify-cfg>' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
-; RUN: opt < %s -passes=debugify,sroa -S | FileCheck %s --check-prefix=DEBUG
+; RUN: opt < %s -passes='sroa<preserve-cfg>,infer-alignment' -S | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
+; RUN: opt < %s -passes='sroa<modify-cfg>,infer-alignment' -S | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
+; RUN: opt < %s -passes=debugify,sroa,infer-alignment -S | FileCheck %s --check-prefix=DEBUG
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n8:16:32:64"
%S1 = type { i64, [42 x float] }
@@ -364,7 +364,7 @@ define i64 @test6(<4 x i64> %x, <4 x i64> %y, i64 %n) {
; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds { <4 x i64>, <4 x i64> }, ptr [[TMP]], i32 0, i32 1
; CHECK-NEXT: store <4 x i64> [[Y:%.*]], ptr [[P1]], align 32
; CHECK-NEXT: [[ADDR:%.*]] = getelementptr inbounds { <4 x i64>, <4 x i64> }, ptr [[TMP]], i32 0, i32 0, i64 [[N:%.*]]
-; CHECK-NEXT: [[RES:%.*]] = load i64, ptr [[ADDR]], align 4
+; CHECK-NEXT: [[RES:%.*]] = load i64, ptr [[ADDR]], align 8
; CHECK-NEXT: ret i64 [[RES]]
;
; DEBUG-LABEL: @test6(
@@ -378,7 +378,7 @@ define i64 @test6(<4 x i64> %x, <4 x i64> %y, i64 %n) {
; DEBUG-NEXT: store <4 x i64> [[Y:%.*]], ptr [[P1]], align 32, !dbg [[DBG172:![0-9]+]]
; DEBUG-NEXT: [[ADDR:%.*]] = getelementptr inbounds { <4 x i64>, <4 x i64> }, ptr [[TMP]], i32 0, i32 0, i64 [[N:%.*]], !dbg [[DBG173:![0-9]+]]
; DEBUG-NEXT: #dbg_value(ptr [[ADDR]], [[META166:![0-9]+]], !DIExpression(), [[DBG173]])
-; DEBUG-NEXT: [[RES:%.*]] = load i64, ptr [[ADDR]], align 4, !dbg [[DBG174:![0-9]+]]
+; DEBUG-NEXT: [[RES:%.*]] = load i64, ptr [[ADDR]], align 8, !dbg [[DBG174:![0-9]+]]
; DEBUG-NEXT: #dbg_value(i64 [[RES]], [[META167:![0-9]+]], !DIExpression(), [[DBG174]])
; DEBUG-NEXT: ret i64 [[RES]], !dbg [[DBG175:![0-9]+]]
;
@@ -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 8
-; CHECK-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 8
+; 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_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 8
+; CHECK-NEXT: [[X_SROA_0_0_X_SROA_0_0_RESULT:%.*]] = load <4 x ptr>, ptr [[X_SROA_0]], align 32
; 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 8, !dbg [[DBG400:![0-9]+]]
+; DEBUG-NEXT: [[X_SROA_0:%.*]] = alloca <4 x ptr>, align 32, !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 8, !dbg [[DBG401:![0-9]+]]
+; DEBUG-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 32, !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 8, !dbg [[DBG408:![0-9]+]]
+; 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: #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 8
-; CHECK-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 8
+; 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_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 8
+; CHECK-NEXT: store i64 [[C:%.*]], ptr [[X_SROA_0_16_X_TMP3_SROA_IDX2]], align 16
; 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 8
+; CHECK-NEXT: [[X_SROA_0_0_X_SROA_0_0_RESULT:%.*]] = load <4 x ptr>, ptr [[X_SROA_0]], align 32
; 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 8, !dbg [[DBG434:![0-9]+]]
+; DEBUG-NEXT: [[X_SROA_0:%.*]] = alloca <4 x ptr>, align 32, !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 8, !dbg [[DBG435:![0-9]+]]
+; DEBUG-NEXT: store i32 [[A:%.*]], ptr [[X_SROA_0]], align 32, !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 8, !dbg [[DBG439]]
+; DEBUG-NEXT: store i64 [[C:%.*]], ptr [[X_SROA_0_16_X_TMP3_SROA_IDX2]], align 16, !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 8, !dbg [[DBG442:![0-9]+]]
+; 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: #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]+]]
;
@@ -1208,17 +1208,17 @@ define void @swap-7bytes(ptr %x, ptr %y) {
define void @swap-16bytes(ptr %x, ptr %y) {
; CHECK-LABEL: @swap-16bytes(
; CHECK-NEXT: [[TMP:%.*]] = alloca [2 x i64], align 8
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[TMP]], ptr [[X:%.*]], i64 16, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP]], ptr [[X:%.*]], i64 16, i1 false)
; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[X]], ptr [[Y:%.*]], i64 16, i1 false)
-; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[Y]], ptr [[TMP]], i64 16, i1 false)
+; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[Y]], ptr align 8 [[TMP]], i64 16, i1 false)
; CHECK-NEXT: ret void
;
; DEBUG-LABEL: @swap-16bytes(
; DEBUG-NEXT: [[TMP:%.*]] = alloca [2 x i64], align 8, !dbg [[DBG472:![0-9]+]]
; DEBUG-NEXT: #dbg_value(ptr [[TMP]], [[META471:![0-9]+]], !DIExpression(), [[DBG472]])
-; DEBUG-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[TMP]], ptr [[X:%.*]], i64 16, i1 false), !dbg [[DBG473:![0-9]+]]
+; DEBUG-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[TMP]], ptr [[X:%.*]], i64 16, i1 false), !dbg [[DBG473:![0-9]+]]
; DEBUG-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr [[X]], ptr [[Y:%.*]], i64 16, i1 false), !dbg [[DBG474:![0-9]+]]
-; DEBUG-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[Y]], ptr [[TMP]], i64 16, i1 false), !dbg [[DBG475:![0-9]+]]
+; DEBUG-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr [[Y]], ptr align 8 [[TMP]], i64 16, i1 false), !dbg [[DBG475:![0-9]+]]
; DEBUG-NEXT: ret void, !dbg [[DBG476:![0-9]+]]
;
%tmp = alloca [2 x i64]
@@ -1373,30 +1373,30 @@ define <4 x i32> @ptrLoadStoreTysAS3(ptr %init, i32 %val2) {
define <4 x ptr> @ptrLoadStoreTysPtr(ptr %init, i64 %val2) {
; CHECK-LABEL: @ptrLoadStoreTysPtr(
; CHECK-NEXT: [[VAL0:%.*]] = load ptr, ptr [[INIT:%.*]], align 8
-; CHECK-NEXT: [[OBJ:%.*]] = alloca <4 x ptr>, align 16
-; CHECK-NEXT: store <4 x ptr> splat (ptr null), ptr [[OBJ]], align 16
-; CHECK-NEXT: store ptr [[VAL0]], ptr [[OBJ]], align 16
+; CHECK-NEXT: [[OBJ:%.*]] = alloca <4 x ptr>, align 32
+; CHECK-NEXT: store <4 x ptr> splat (ptr null), ptr [[OBJ]], align 32
+; CHECK-NEXT: store ptr [[VAL0]], ptr [[OBJ]], align 32
; CHECK-NEXT: [[OBJ_8_PTR2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[OBJ]], i64 8
; CHECK-NEXT: store i64 [[VAL2:%.*]], ptr [[OBJ_8_PTR2_SROA_IDX]], align 8
; CHECK-NEXT: [[OBJ_12_PTR3_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[OBJ]], i64 12
; CHECK-NEXT: store i64 131072, ptr [[OBJ_12_PTR3_SROA_IDX]], align 4
-; CHECK-NEXT: [[OBJ_0_SROAVAL:%.*]] = load <4 x ptr>, ptr [[OBJ]], align 16
+; CHECK-NEXT: [[OBJ_0_SROAVAL:%.*]] = load <4 x ptr>, ptr [[OBJ]], align 32
; CHECK-NEXT: ret <4 x ptr> [[OBJ_0_SROAVAL]]
;
; DEBUG-LABEL: @ptrLoadStoreTysPtr(
; DEBUG-NEXT: [[VAL0:%.*]] = load ptr, ptr [[INIT:%.*]], align 8, !dbg [[DBG541:![0-9]+]]
; DEBUG-NEXT: #dbg_value(ptr [[VAL0]], [[META536:![0-9]+]], !DIExpression(), [[DBG541]])
-; DEBUG-NEXT: [[OBJ:%.*]] = alloca <4 x ptr>, align 16, !dbg [[DBG542:![0-9]+]]
+; DEBUG-NEXT: [[OBJ:%.*]] = alloca <4 x ptr>, align 32, !dbg [[DBG542:![0-9]+]]
; DEBUG-NEXT: #dbg_value(ptr [[OBJ]], [[META537:![0-9]+]], !DIExpression(), [[DBG542]])
-; DEBUG-NEXT: store <4 x ptr> splat (ptr null), ptr [[OBJ]], align 16, !dbg [[DBG543:![0-9]+]]
-; DEBUG-NEXT: store ptr [[VAL0]], ptr [[OBJ]], align 16, !dbg [[DBG544:![0-9]+]]
+; DEBUG-NEXT: store <4 x ptr> splat (ptr null), ptr [[OBJ]], align 32, !dbg [[DBG543:![0-9]+]]
+; DEBUG-NEXT: store ptr [[VAL0]], ptr [[OBJ]], align 32, !dbg [[DBG544:![0-9]+]]
; DEBUG-NEXT: #dbg_value(ptr undef, [[META538:![0-9]+]], !DIExpression(), [[META545:![0-9]+]])
; DEBUG-NEXT: [[OBJ_8_PTR2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[OBJ]], i64 8, !dbg [[DBG546:![0-9]+]]
; DEBUG-NEXT: store i64 [[VAL2:%.*]], ptr [[OBJ_8_PTR2_SROA_IDX]], align 8, !dbg [[DBG546]]
; DEBUG-NEXT: #dbg_value(ptr undef, [[META539:![0-9]+]], !DIExpression(), [[META547:![0-9]+]])
; DEBUG-NEXT: [[OBJ_12_PTR3_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[OBJ]], i64 12, !dbg [[DBG548:![0-9]+]]
; DEBUG-NEXT: store i64 131072, ptr [[OBJ_12_PTR3_SROA_IDX]], align 4, !dbg [[DBG548]]
-; DEBUG-NEXT: [[OBJ_0_SROAVAL:%.*]] = load <4 x ptr>, ptr [[OBJ]], align 16, !dbg [[DBG549:![0-9]+]]
+; DEBUG-NEXT: [[OBJ_0_SROAVAL:%.*]] = load <4 x ptr>, ptr [[OBJ]], align 32, !dbg [[DBG549:![0-9]+]]
; DEBUG-NEXT: #dbg_value(<4 x ptr> [[OBJ_0_SROAVAL]], [[META540:![0-9]+]], !DIExpression(), [[DBG549]])
; DEBUG-NEXT: ret <4 x ptr> [[OBJ_0_SROAVAL]], !dbg [[DBG550:![0-9]+]]
;
>From 436b7373dafe4c47239f72c2b498f7fe92106cca Mon Sep 17 00:00:00 2001
From: ZhouGuangyuan <zhouguangyuan.xian at gmail.com>
Date: Sat, 12 Sep 2026 10:22:33 +0800
Subject: [PATCH 5/5] [NVPTX] Infer alignment after late SROA
---
llvm/include/llvm/InitializePasses.h | 1 +
llvm/include/llvm/Transforms/Scalar.h | 3 ++
llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp | 2 +
llvm/lib/Transforms/Scalar/InferAlignment.cpp | 39 +++++++++++++++++++
llvm/lib/Transforms/Scalar/Scalar.cpp | 1 +
llvm/test/CodeGen/NVPTX/vector-loads.ll | 4 +-
6 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 1ba2f67d27e5d3..5f4243d46d2207 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -142,6 +142,7 @@ initializeImmutableModuleSummaryIndexWrapperPassPass(PassRegistry &);
LLVM_ABI void initializeImplicitNullChecksLegacyPass(PassRegistry &);
LLVM_ABI void initializeIndirectBrExpandLegacyPassPass(PassRegistry &);
LLVM_ABI void initializeInferAddressSpacesPass(PassRegistry &);
+LLVM_ABI void initializeInferAlignmentLegacyPassPass(PassRegistry &);
LLVM_ABI void initializeInlineAsmPreparePass(PassRegistry &);
LLVM_ABI void initializeInstSimplifyLegacyPassPass(PassRegistry &);
LLVM_ABI void initializeInstructionCombiningPassPass(PassRegistry &);
diff --git a/llvm/include/llvm/Transforms/Scalar.h b/llvm/include/llvm/Transforms/Scalar.h
index 24a127b1ffb170..57b72df5649b95 100644
--- a/llvm/include/llvm/Transforms/Scalar.h
+++ b/llvm/include/llvm/Transforms/Scalar.h
@@ -157,6 +157,9 @@ LLVM_ABI FunctionPass *
createInferAddressSpacesPass(unsigned AddressSpace = ~0u);
LLVM_ABI extern char &InferAddressSpacesID;
+// Infer alignment for loads, stores, and other memory operations.
+LLVM_ABI FunctionPass *createInferAlignmentLegacyPass();
+
//===----------------------------------------------------------------------===//
//
// PartiallyInlineLibCalls - Tries to inline the fast path of library
diff --git a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp
index f4987a8dbfbba8..cc6c5739f3f8de 100644
--- a/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXTargetMachine.cpp
@@ -314,6 +314,8 @@ void NVPTXPassConfig::addIRPasses() {
addPass(createLoadStoreVectorizerPass());
addPass(createSROAPass(/*PreserveCFG=*/true,
/*AggregateToVector=*/true));
+ // SROA preserves inherited alignment; infer alignment for the new accesses.
+ addPass(createInferAlignmentLegacyPass());
addPass(createNVPTXTagInvariantLoadsPass());
if (!DisableNVPTXIRPeephole)
addPass(createNVPTXIRPeepholePass());
diff --git a/llvm/lib/Transforms/Scalar/InferAlignment.cpp b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
index 57a1119c2bfa90..8761f5e3863fb3 100644
--- a/llvm/lib/Transforms/Scalar/InferAlignment.cpp
+++ b/llvm/lib/Transforms/Scalar/InferAlignment.cpp
@@ -21,6 +21,8 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PatternMatch.h"
+#include "llvm/InitializePasses.h"
+#include "llvm/Pass.h"
#include "llvm/Support/KnownBits.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
@@ -196,3 +198,40 @@ PreservedAnalyses InferAlignmentPass::run(Function &F,
// Changes to alignment shouldn't invalidated analyses.
return PreservedAnalyses::all();
}
+
+namespace {
+class InferAlignmentLegacyPass : public FunctionPass {
+public:
+ static char ID;
+
+ InferAlignmentLegacyPass() : FunctionPass(ID) {
+ initializeInferAlignmentLegacyPassPass(*PassRegistry::getPassRegistry());
+ }
+
+ bool runOnFunction(Function &F) override {
+ if (skipFunction(F))
+ return false;
+ auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
+ auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+ return inferAlignment(F, AC, DT);
+ }
+
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<AssumptionCacheTracker>();
+ AU.addRequired<DominatorTreeWrapperPass>();
+ AU.setPreservesCFG();
+ }
+};
+} // namespace
+
+char InferAlignmentLegacyPass::ID = 0;
+INITIALIZE_PASS_BEGIN(InferAlignmentLegacyPass, "infer-alignment",
+ "Infer alignment", false, false)
+INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+INITIALIZE_PASS_END(InferAlignmentLegacyPass, "infer-alignment",
+ "Infer alignment", false, false)
+
+FunctionPass *llvm::createInferAlignmentLegacyPass() {
+ return new InferAlignmentLegacyPass();
+}
diff --git a/llvm/lib/Transforms/Scalar/Scalar.cpp b/llvm/lib/Transforms/Scalar/Scalar.cpp
index 7a954047c05f37..53737b009f8117 100644
--- a/llvm/lib/Transforms/Scalar/Scalar.cpp
+++ b/llvm/lib/Transforms/Scalar/Scalar.cpp
@@ -27,6 +27,7 @@ void llvm::initializeScalarOpts(PassRegistry &Registry) {
initializeEarlyCSEMemSSALegacyPassPass(Registry);
initializeFlattenCFGLegacyPassPass(Registry);
initializeInferAddressSpacesPass(Registry);
+ initializeInferAlignmentLegacyPassPass(Registry);
initializeInstSimplifyLegacyPassPass(Registry);
initializeLegacyLICMPassPass(Registry);
initializeLoopDataPrefetchLegacyPassPass(Registry);
diff --git a/llvm/test/CodeGen/NVPTX/vector-loads.ll b/llvm/test/CodeGen/NVPTX/vector-loads.ll
index 1ae6f6bcd748f0..a1d69be43fa423 100644
--- a/llvm/test/CodeGen/NVPTX/vector-loads.ll
+++ b/llvm/test/CodeGen/NVPTX/vector-loads.ll
@@ -228,7 +228,7 @@ define void @extv8f16_global_a16(ptr addrspace(1) noalias readonly align 16 %dst
ret void
}
-define void @extv8f16_global_a4(ptr addrspace(1) noalias readonly align 16 %dst, ptr addrspace(1) noalias readonly align 16 %src) #0 {
+define void @extv8f16_global_a4(ptr addrspace(1) noalias readonly align 16 %dst, ptr addrspace(1) noalias readonly align 4 %src) #0 {
; CHECK-LABEL: extv8f16_global_a4(
; CHECK: {
; CHECK-NEXT: .reg .b16 %rs<9>;
@@ -292,7 +292,7 @@ define void @extv8f16_generic_a16(ptr noalias readonly align 16 %dst, ptr noalia
ret void
}
-define void @extv8f16_generic_a4(ptr noalias readonly align 16 %dst, ptr noalias readonly align 16 %src) #0 {
+define void @extv8f16_generic_a4(ptr noalias readonly align 16 %dst, ptr noalias readonly align 4 %src) #0 {
; CHECK-LABEL: extv8f16_generic_a4(
; CHECK: {
; CHECK-NEXT: .reg .b16 %rs<9>;
More information about the llvm-commits
mailing list