[llvm] [NFC][SROA] Pre-commit test for vector-load-split (PR #199156)

Syadus Sefat via llvm-commits llvm-commits at lists.llvm.org
Fri May 22 14:34:02 PDT 2026


https://github.com/mssefat updated https://github.com/llvm/llvm-project/pull/199156

>From 7bb8a6b6f64c3fee4680ff0663e42774636c8c0a Mon Sep 17 00:00:00 2001
From: mssefat <syadus.sefat at gmail.com>
Date: Thu, 21 May 2026 13:51:52 -0500
Subject: [PATCH] [NFC][SROA] Pre-commit test for vector-load-split

---
 .../test/Transforms/SROA/vector-load-split.ll | 523 ++++++++++++++++++
 1 file changed, 523 insertions(+)
 create mode 100644 llvm/test/Transforms/SROA/vector-load-split.ll

diff --git a/llvm/test/Transforms/SROA/vector-load-split.ll b/llvm/test/Transforms/SROA/vector-load-split.ll
new file mode 100644
index 0000000000000..4b53671737c6a
--- /dev/null
+++ b/llvm/test/Transforms/SROA/vector-load-split.ll
@@ -0,0 +1,523 @@
+; RUN: opt -passes='sroa,simplifycfg' -S < %s | FileCheck %s --check-prefixes=SROA
+; RUN: opt -passes='sroa,simplifycfg,instcombine' -S < %s | FileCheck %s --check-prefixes=COMBINED
+
+%struct.S = type { ptr, i64, i32, i32, i64, i64 }
+%desc = type { ptr, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64, i64 }
+
+define double @descriptor_copy_vector_load(ptr %data, ptr %dst) {
+; SROA-LABEL: define double @descriptor_copy_vector_load(
+; SROA-SAME: ptr [[DATA:%.*]], ptr [[DST:%.*]]) {
+; SROA-NEXT:  [[ENTRY:.*:]]
+; SROA-NEXT:    [[SRC_DESC:%.*]] = alloca [[DESC:%.*]], align 8, addrspace(5)
+; SROA-NEXT:    [[TMP_DESC:%.*]] = alloca [[DESC]], align 8, addrspace(5)
+; SROA-NEXT:    [[SRC_DESC_CAST:%.*]] = addrspacecast ptr addrspace(5) [[SRC_DESC]] to ptr
+; SROA-NEXT:    [[TMP_DESC_CAST:%.*]] = addrspacecast ptr addrspace(5) [[TMP_DESC]] to ptr
+; SROA-NEXT:    store ptr [[DATA]], ptr addrspace(5) [[SRC_DESC]], align 8
+; SROA-NEXT:    [[SRC_LB0:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SRC_DESC]], i32 24
+; SROA-NEXT:    store i64 1, ptr addrspace(5) [[SRC_LB0]], align 8
+; SROA-NEXT:    [[SRC_STRIDE0:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SRC_DESC]], i32 40
+; SROA-NEXT:    store i64 8, ptr addrspace(5) [[SRC_STRIDE0]], align 8
+; SROA-NEXT:    [[ARGS_SROA_0_0_VEC_INSERT:%.*]] = insertelement <2 x ptr> {{.*}}, ptr [[SRC_DESC_CAST]], i32 0
+; SROA-NEXT:    [[ARGS_SROA_0_8_VEC_INSERT:%.*]] = insertelement <2 x ptr> [[ARGS_SROA_0_0_VEC_INSERT]], ptr [[TMP_DESC_CAST]], i32 1
+; SROA-NEXT:    [[TMP_PTR:%.*]] = extractelement <2 x ptr> [[ARGS_SROA_0_8_VEC_INSERT]], i32 1
+; SROA-NEXT:    [[SRC_PTR:%.*]] = extractelement <2 x ptr> [[ARGS_SROA_0_8_VEC_INSERT]], i32 0
+; SROA-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(96) [[TMP_PTR]], ptr noundef nonnull align 8 dereferenceable(96) [[SRC_PTR]], i32 96, i1 false)
+; SROA-NEXT:    [[TMP_BASE:%.*]] = load ptr, ptr [[TMP_PTR]], align 8
+; SROA-NEXT:    [[TMP_LB0_P:%.*]] = getelementptr inbounds i8, ptr [[TMP_PTR]], i64 24
+; SROA-NEXT:    [[TMP_LB0:%.*]] = load i64, ptr [[TMP_LB0_P]], align 8
+; SROA-NEXT:    [[TMP_STRIDE0_P:%.*]] = getelementptr inbounds i8, ptr [[TMP_PTR]], i64 40
+; SROA-NEXT:    [[TMP_STRIDE0:%.*]] = load i64, ptr [[TMP_STRIDE0_P]], align 8
+; SROA-NEXT:    [[IDX:%.*]] = sub nsw i64 4, [[TMP_LB0]]
+; SROA-NEXT:    [[OFFSET:%.*]] = mul nuw nsw i64 [[TMP_STRIDE0]], [[IDX]]
+; SROA-NEXT:    [[ELT_PTR:%.*]] = getelementptr i8, ptr [[TMP_BASE]], i64 [[OFFSET]]
+; SROA-NEXT:    [[RETVAL:%.*]] = load double, ptr [[ELT_PTR]], align 8
+; SROA-NEXT:    store double 0.000000e+00, ptr [[DST]], align 8
+; SROA-NEXT:    ret double [[RETVAL]]
+;
+; COMBINED-LABEL: define double @descriptor_copy_vector_load(
+; COMBINED-SAME: ptr [[DATA:%.*]], ptr [[DST:%.*]]) {
+; COMBINED-NEXT:  [[ENTRY:.*:]]
+; COMBINED-NEXT:    [[SRC_DESC:%.*]] = alloca [[DESC:%.*]], align 8, addrspace(5)
+; COMBINED-NEXT:    [[TMP_DESC:%.*]] = alloca [[DESC]], align 8, addrspace(5)
+; COMBINED-NEXT:    [[SRC_DESC_CAST:%.*]] = addrspacecast ptr addrspace(5) [[SRC_DESC]] to ptr
+; COMBINED-NEXT:    [[TMP_DESC_CAST:%.*]] = addrspacecast ptr addrspace(5) [[TMP_DESC]] to ptr
+; COMBINED-NEXT:    store ptr [[DATA]], ptr addrspace(5) [[SRC_DESC]], align 8
+; COMBINED-NEXT:    [[SRC_LB0:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SRC_DESC]], i64 24
+; COMBINED-NEXT:    store i64 1, ptr addrspace(5) [[SRC_LB0]], align 8
+; COMBINED-NEXT:    [[SRC_STRIDE0:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SRC_DESC]], i64 40
+; COMBINED-NEXT:    store i64 8, ptr addrspace(5) [[SRC_STRIDE0]], align 8
+; COMBINED-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(96) [[TMP_DESC_CAST]], ptr noundef nonnull align 8 dereferenceable(96) [[SRC_DESC_CAST]], i32 96, i1 false)
+; COMBINED-NEXT:    [[TMP_BASE:%.*]] = load ptr, ptr [[TMP_DESC_CAST]], align 8
+; COMBINED-NEXT:    [[TMP_LB0_P:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP_DESC_CAST]], i64 24
+; COMBINED-NEXT:    [[TMP_LB0:%.*]] = load i64, ptr [[TMP_LB0_P]], align 8
+; COMBINED-NEXT:    [[TMP_STRIDE0_P:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP_DESC_CAST]], i64 40
+; COMBINED-NEXT:    [[TMP_STRIDE0:%.*]] = load i64, ptr [[TMP_STRIDE0_P]], align 8
+; COMBINED-NEXT:    [[IDX:%.*]] = sub nsw i64 4, [[TMP_LB0]]
+; COMBINED-NEXT:    [[OFFSET:%.*]] = mul nuw nsw i64 [[TMP_STRIDE0]], [[IDX]]
+; COMBINED-NEXT:    [[ELT_PTR:%.*]] = getelementptr i8, ptr [[TMP_BASE]], i64 [[OFFSET]]
+; COMBINED-NEXT:    [[RETVAL:%.*]] = load double, ptr [[ELT_PTR]], align 8
+; COMBINED-NEXT:    store double 0.000000e+00, ptr [[DST]], align 8
+; COMBINED-NEXT:    ret double [[RETVAL]]
+;
+entry:
+  %src.desc = alloca %desc, align 8, addrspace(5)
+  %tmp.desc = alloca %desc, align 8, addrspace(5)
+  %args = alloca { ptr, ptr }, align 8, addrspace(5)
+  %src.desc.cast = addrspacecast ptr addrspace(5) %src.desc to ptr
+  %tmp.desc.cast = addrspacecast ptr addrspace(5) %tmp.desc to ptr
+
+  store ptr %data, ptr addrspace(5) %src.desc, align 8
+  %src.lb0 = getelementptr inbounds i8, ptr addrspace(5) %src.desc, i32 24
+  store i64 1, ptr addrspace(5) %src.lb0, align 8
+  %src.stride0 = getelementptr inbounds i8, ptr addrspace(5) %src.desc, i32 40
+  store i64 8, ptr addrspace(5) %src.stride0, align 8
+
+  store ptr %src.desc.cast, ptr addrspace(5) %args, align 8
+  %arg1 = getelementptr inbounds i8, ptr addrspace(5) %args, i32 8
+  store ptr %tmp.desc.cast, ptr addrspace(5) %arg1, align 8
+
+  %pair = load <2 x ptr>, ptr addrspace(5) %args, align 8
+  %tmp.ptr = extractelement <2 x ptr> %pair, i32 1
+  %src.ptr = extractelement <2 x ptr> %pair, i32 0
+  call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(96) %tmp.ptr, ptr noundef nonnull align 8 dereferenceable(96) %src.ptr, i32 96, i1 false)
+
+  %tmp.base = load ptr, ptr %tmp.ptr, align 8
+  %tmp.lb0.p = getelementptr inbounds i8, ptr %tmp.ptr, i64 24
+  %tmp.lb0 = load i64, ptr %tmp.lb0.p, align 8
+  %tmp.stride0.p = getelementptr inbounds i8, ptr %tmp.ptr, i64 40
+  %tmp.stride0 = load i64, ptr %tmp.stride0.p, align 8
+  %idx = sub nsw i64 4, %tmp.lb0
+  %offset = mul nuw nsw i64 %tmp.stride0, %idx
+  %elt.ptr = getelementptr i8, ptr %tmp.base, i64 %offset
+  %retval = load double, ptr %elt.ptr, align 8
+
+  store double 0.000000e+00, ptr %dst, align 8
+  ret double %retval
+}
+
+define double @descriptor_copy_scalar_load(ptr %data, ptr %dst) {
+; SROA-LABEL: define double @descriptor_copy_scalar_load(
+; SROA-SAME: ptr [[DATA:%.*]], ptr [[DST:%.*]]) {
+; SROA-NEXT:  [[ENTRY:.*:]]
+; SROA-NEXT:    [[SRC_DESC_SROA_2:%.*]] = alloca { i64, i64 }, align 8, addrspace(5)
+; SROA-NEXT:    [[SRC_DESC_SROA_8:%.*]] = alloca { i64, i64, i64, i64, i64, i64 }, align 8, addrspace(5)
+; SROA-NEXT:    [[TMP_DESC_SROA_2:%.*]] = alloca { i64, i64 }, align 8, addrspace(5)
+; SROA-NEXT:    [[TMP_DESC_SROA_4:%.*]] = alloca { i64, i64, i64, i64, i64, i64 }, align 8, addrspace(5)
+; SROA-NEXT:    [[TMP_DESC_SROA_2_0_TMP_DESC_CAST_SROA_CAST:%.*]] = addrspacecast ptr addrspace(5) [[TMP_DESC_SROA_2]] to ptr
+; SROA-NEXT:    [[SRC_DESC_SROA_2_8_SRC_DESC_CAST_SROA_CAST:%.*]] = addrspacecast ptr addrspace(5) [[SRC_DESC_SROA_2]] to ptr
+; SROA-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[TMP_DESC_SROA_2_0_TMP_DESC_CAST_SROA_CAST]], ptr align 8 [[SRC_DESC_SROA_2_8_SRC_DESC_CAST_SROA_CAST]], i32 16, i1 false)
+; SROA-NEXT:    [[TMP_DESC_SROA_4_0_TMP_DESC_CAST_SROA_CAST:%.*]] = addrspacecast ptr addrspace(5) [[TMP_DESC_SROA_4]] to ptr
+; SROA-NEXT:    [[SRC_DESC_SROA_8_48_SRC_DESC_CAST_SROA_CAST:%.*]] = addrspacecast ptr addrspace(5) [[SRC_DESC_SROA_8]] to ptr
+; SROA-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[TMP_DESC_SROA_4_0_TMP_DESC_CAST_SROA_CAST]], ptr align 8 [[SRC_DESC_SROA_8_48_SRC_DESC_CAST_SROA_CAST]], i32 48, i1 false)
+; SROA-NEXT:    [[IDX:%.*]] = sub nsw i64 4, 1
+; SROA-NEXT:    [[OFFSET:%.*]] = mul nuw nsw i64 8, [[IDX]]
+; SROA-NEXT:    [[ELT_PTR:%.*]] = getelementptr i8, ptr [[DATA]], i64 [[OFFSET]]
+; SROA-NEXT:    [[RETVAL:%.*]] = load double, ptr [[ELT_PTR]], align 8
+; SROA-NEXT:    store double 0.000000e+00, ptr [[DST]], align 8
+; SROA-NEXT:    ret double [[RETVAL]]
+;
+; COMBINED-LABEL: define double @descriptor_copy_scalar_load(
+; COMBINED-SAME: ptr [[DATA:%.*]], ptr [[DST:%.*]]) {
+; COMBINED-NEXT:  [[ENTRY:.*:]]
+; COMBINED-NEXT:    [[ELT_PTR:%.*]] = getelementptr i8, ptr [[DATA]], i64 24
+; COMBINED-NEXT:    [[RETVAL:%.*]] = load double, ptr [[ELT_PTR]], align 8
+; COMBINED-NEXT:    store double 0.000000e+00, ptr [[DST]], align 8
+; COMBINED-NEXT:    ret double [[RETVAL]]
+;
+entry:
+  %src.desc = alloca %desc, align 8, addrspace(5)
+  %tmp.desc = alloca %desc, align 8, addrspace(5)
+  %args = alloca { ptr, ptr }, align 8, addrspace(5)
+  %src.desc.cast = addrspacecast ptr addrspace(5) %src.desc to ptr
+  %tmp.desc.cast = addrspacecast ptr addrspace(5) %tmp.desc to ptr
+
+  store ptr %data, ptr addrspace(5) %src.desc, align 8
+  %src.lb0 = getelementptr inbounds i8, ptr addrspace(5) %src.desc, i32 24
+  store i64 1, ptr addrspace(5) %src.lb0, align 8
+  %src.stride0 = getelementptr inbounds i8, ptr addrspace(5) %src.desc, i32 40
+  store i64 8, ptr addrspace(5) %src.stride0, align 8
+
+  store ptr %src.desc.cast, ptr addrspace(5) %args, align 8
+  %arg1 = getelementptr inbounds i8, ptr addrspace(5) %args, i32 8
+  store ptr %tmp.desc.cast, ptr addrspace(5) %arg1, align 8
+
+  %src.ptr = load ptr, ptr addrspace(5) %args, align 8
+  %tmp.ptr = load ptr, ptr addrspace(5) %arg1, align 8
+  call void @llvm.memcpy.p0.p0.i32(ptr noundef nonnull align 8 dereferenceable(96) %tmp.ptr, ptr noundef nonnull align 8 dereferenceable(96) %src.ptr, i32 96, i1 false)
+
+  %tmp.base = load ptr, ptr %tmp.ptr, align 8
+  %tmp.lb0.p = getelementptr inbounds i8, ptr %tmp.ptr, i64 24
+  %tmp.lb0 = load i64, ptr %tmp.lb0.p, align 8
+  %tmp.stride0.p = getelementptr inbounds i8, ptr %tmp.ptr, i64 40
+  %tmp.stride0 = load i64, ptr %tmp.stride0.p, align 8
+  %idx = sub nsw i64 4, %tmp.lb0
+  %offset = mul nuw nsw i64 %tmp.stride0, %idx
+  %elt.ptr = getelementptr i8, ptr %tmp.base, i64 %offset
+  %retval = load double, ptr %elt.ptr, align 8
+
+  store double 0.000000e+00, ptr %dst, align 8
+  ret double %retval
+}
+
+define void @split_all_lanes_select_same_alloca(float %v0, float %v1, float %v2, float %v3, i1 %cond, ptr addrspace(1) %out) {
+; SROA-LABEL: define void @split_all_lanes_select_same_alloca(
+; SROA-SAME: float [[V0:%.*]], float [[V1:%.*]], float [[V2:%.*]], float [[V3:%.*]], i1 [[COND:%.*]], ptr addrspace(1) [[OUT:%.*]]) {
+; SROA-NEXT:  [[ENTRY:.*:]]
+; SROA-NEXT:    [[SLOT_SROA_0:%.*]] = alloca <4 x float>, align 16, addrspace(5)
+; SROA-NEXT:    store float [[V0]], ptr addrspace(5) [[SLOT_SROA_0]], align 16
+; SROA-NEXT:    [[SLOT_SROA_0_4_GEP_SROA_IDX8:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 4
+; SROA-NEXT:    [[SLOT_SROA_0_4_GEP1_SROA_IDX9:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 4
+; SROA-NEXT:    [[PTR_SROA_SEL:%.*]] = select i1 [[COND]], ptr addrspace(5) [[SLOT_SROA_0_4_GEP_SROA_IDX8]], ptr addrspace(5) [[SLOT_SROA_0_4_GEP1_SROA_IDX9]]
+; SROA-NEXT:    store float [[V1]], ptr addrspace(5) [[PTR_SROA_SEL]], align 4
+; SROA-NEXT:    [[SLOT_SROA_0_8_GEP2_SROA_IDX10:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 8
+; SROA-NEXT:    [[SLOT_SROA_0_8_GEP3_SROA_IDX11:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 8
+; SROA-NEXT:    [[PTR_SROA_SEL4:%.*]] = select i1 [[COND]], ptr addrspace(5) [[SLOT_SROA_0_8_GEP2_SROA_IDX10]], ptr addrspace(5) [[SLOT_SROA_0_8_GEP3_SROA_IDX11]]
+; SROA-NEXT:    store float [[V2]], ptr addrspace(5) [[PTR_SROA_SEL4]], align 4
+; SROA-NEXT:    [[SLOT_SROA_0_12_GEP5_SROA_IDX12:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 12
+; SROA-NEXT:    [[SLOT_SROA_0_12_GEP6_SROA_IDX13:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 12
+; SROA-NEXT:    [[PTR_SROA_SEL7:%.*]] = select i1 [[COND]], ptr addrspace(5) [[SLOT_SROA_0_12_GEP5_SROA_IDX12]], ptr addrspace(5) [[SLOT_SROA_0_12_GEP6_SROA_IDX13]]
+; SROA-NEXT:    store float [[V3]], ptr addrspace(5) [[PTR_SROA_SEL7]], align 4
+; SROA-NEXT:    [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC:%.*]] = load <4 x float>, ptr addrspace(5) [[SLOT_SROA_0]], align 16
+; SROA-NEXT:    [[E0:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i32 0
+; SROA-NEXT:    [[E1:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i32 1
+; SROA-NEXT:    [[E2:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i32 2
+; SROA-NEXT:    [[E3:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i32 3
+; SROA-NEXT:    [[SUM01:%.*]] = fadd float [[E0]], [[E1]]
+; SROA-NEXT:    [[SUM23:%.*]] = fadd float [[E2]], [[E3]]
+; SROA-NEXT:    [[SUM:%.*]] = fadd float [[SUM01]], [[SUM23]]
+; SROA-NEXT:    store float [[SUM]], ptr addrspace(1) [[OUT]], align 4
+; SROA-NEXT:    ret void
+;
+; COMBINED-LABEL: define void @split_all_lanes_select_same_alloca(
+; COMBINED-SAME: float [[V0:%.*]], float [[V1:%.*]], float [[V2:%.*]], float [[V3:%.*]], i1 [[COND:%.*]], ptr addrspace(1) [[OUT:%.*]]) {
+; COMBINED-NEXT:  [[ENTRY:.*:]]
+; COMBINED-NEXT:    [[SLOT_SROA_0:%.*]] = alloca <4 x float>, align 16, addrspace(5)
+; COMBINED-NEXT:    store float [[V0]], ptr addrspace(5) [[SLOT_SROA_0]], align 16
+; COMBINED-NEXT:    [[PTR_SROA_SEL:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 4
+; COMBINED-NEXT:    store float [[V1]], ptr addrspace(5) [[PTR_SROA_SEL]], align 4
+; COMBINED-NEXT:    [[PTR_SROA_SEL4:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 8
+; COMBINED-NEXT:    store float [[V2]], ptr addrspace(5) [[PTR_SROA_SEL4]], align 4
+; COMBINED-NEXT:    [[PTR_SROA_SEL7:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 12
+; COMBINED-NEXT:    store float [[V3]], ptr addrspace(5) [[PTR_SROA_SEL7]], align 4
+; COMBINED-NEXT:    [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC:%.*]] = load <4 x float>, ptr addrspace(5) [[SLOT_SROA_0]], align 16
+; COMBINED-NEXT:    [[E0:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i64 0
+; COMBINED-NEXT:    [[E1:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i64 1
+; COMBINED-NEXT:    [[E2:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i64 2
+; COMBINED-NEXT:    [[E3:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i64 3
+; COMBINED-NEXT:    [[SUM01:%.*]] = fadd float [[E0]], [[E1]]
+; COMBINED-NEXT:    [[SUM23:%.*]] = fadd float [[E2]], [[E3]]
+; COMBINED-NEXT:    [[SUM:%.*]] = fadd float [[SUM01]], [[SUM23]]
+; COMBINED-NEXT:    store float [[SUM]], ptr addrspace(1) [[OUT]], align 4
+; COMBINED-NEXT:    ret void
+;
+entry:
+  %slot = alloca [4 x float], align 16, addrspace(5)
+
+  %ptr = select i1 %cond, ptr addrspace(5) %slot, ptr addrspace(5) %slot
+  store float %v0, ptr addrspace(5) %ptr, align 16
+  %p1 = getelementptr inbounds float, ptr addrspace(5) %ptr, i32 1
+  store float %v1, ptr addrspace(5) %p1, align 4
+  %p2 = getelementptr inbounds float, ptr addrspace(5) %ptr, i32 2
+  store float %v2, ptr addrspace(5) %p2, align 4
+  %p3 = getelementptr inbounds float, ptr addrspace(5) %ptr, i32 3
+  store float %v3, ptr addrspace(5) %p3, align 4
+
+  %vec = load <4 x float>, ptr addrspace(5) %slot, align 16
+  %e0 = extractelement <4 x float> %vec, i32 0
+  %e1 = extractelement <4 x float> %vec, i32 1
+  %e2 = extractelement <4 x float> %vec, i32 2
+  %e3 = extractelement <4 x float> %vec, i32 3
+
+  %sum01 = fadd float %e0, %e1
+  %sum23 = fadd float %e2, %e3
+  %sum   = fadd float %sum01, %sum23
+  store float %sum, ptr addrspace(1) %out, align 4
+  ret void
+}
+
+define void @split_all_lanes_phi_same_alloca(float %v0, float %v1, float %v2, float %v3, i1 %cond, ptr addrspace(1) %out) {
+; SROA-LABEL: define void @split_all_lanes_phi_same_alloca(
+; SROA-SAME: float [[V0:%.*]], float [[V1:%.*]], float [[V2:%.*]], float [[V3:%.*]], i1 [[COND:%.*]], ptr addrspace(1) [[OUT:%.*]]) {
+; SROA-NEXT:  [[ENTRY:.*:]]
+; SROA-NEXT:    [[SLOT_SROA_0:%.*]] = alloca <4 x float>, align 16, addrspace(5)
+; SROA-NEXT:    [[SLOT_SROA_0_4_GEP_SROA_IDX8:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 4
+; SROA-NEXT:    [[SLOT_SROA_0_4_GEP1_SROA_IDX9:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 4
+; SROA-NEXT:    [[SLOT_SROA_0_8_GEP3_SROA_IDX10:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 8
+; SROA-NEXT:    [[SLOT_SROA_0_8_GEP4_SROA_IDX11:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 8
+; SROA-NEXT:    [[SLOT_SROA_0_12_GEP6_SROA_IDX12:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 12
+; SROA-NEXT:    [[SLOT_SROA_0_12_GEP7_SROA_IDX13:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 12
+; SROA-NEXT:    [[SLOT_SROA_0_4_GEP_SROA_IDX8_SLOT_SROA_0_4_GEP1_SROA_IDX9:%.*]] = select i1 [[COND]], ptr addrspace(5) [[SLOT_SROA_0_4_GEP_SROA_IDX8]], ptr addrspace(5) [[SLOT_SROA_0_4_GEP1_SROA_IDX9]]
+; SROA-NEXT:    [[SLOT_SROA_0_8_GEP3_SROA_IDX10_SLOT_SROA_0_8_GEP4_SROA_IDX11:%.*]] = select i1 [[COND]], ptr addrspace(5) [[SLOT_SROA_0_8_GEP3_SROA_IDX10]], ptr addrspace(5) [[SLOT_SROA_0_8_GEP4_SROA_IDX11]]
+; SROA-NEXT:    [[SLOT_SROA_0_12_GEP6_SROA_IDX12_SLOT_SROA_0_12_GEP7_SROA_IDX13:%.*]] = select i1 [[COND]], ptr addrspace(5) [[SLOT_SROA_0_12_GEP6_SROA_IDX12]], ptr addrspace(5) [[SLOT_SROA_0_12_GEP7_SROA_IDX13]]
+; SROA-NEXT:    store float [[V0]], ptr addrspace(5) [[SLOT_SROA_0]], align 16
+; SROA-NEXT:    store float [[V1]], ptr addrspace(5) [[SLOT_SROA_0_4_GEP_SROA_IDX8_SLOT_SROA_0_4_GEP1_SROA_IDX9]], align 4
+; SROA-NEXT:    store float [[V2]], ptr addrspace(5) [[SLOT_SROA_0_8_GEP3_SROA_IDX10_SLOT_SROA_0_8_GEP4_SROA_IDX11]], align 4
+; SROA-NEXT:    store float [[V3]], ptr addrspace(5) [[SLOT_SROA_0_12_GEP6_SROA_IDX12_SLOT_SROA_0_12_GEP7_SROA_IDX13]], align 4
+; SROA-NEXT:    [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC:%.*]] = load <4 x float>, ptr addrspace(5) [[SLOT_SROA_0]], align 16
+; SROA-NEXT:    [[E0:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i32 0
+; SROA-NEXT:    [[E1:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i32 1
+; SROA-NEXT:    [[E2:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i32 2
+; SROA-NEXT:    [[E3:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i32 3
+; SROA-NEXT:    [[SUM01:%.*]] = fadd float [[E0]], [[E1]]
+; SROA-NEXT:    [[SUM23:%.*]] = fadd float [[E2]], [[E3]]
+; SROA-NEXT:    [[SUM:%.*]] = fadd float [[SUM01]], [[SUM23]]
+; SROA-NEXT:    store float [[SUM]], ptr addrspace(1) [[OUT]], align 4
+; SROA-NEXT:    ret void
+;
+; COMBINED-LABEL: define void @split_all_lanes_phi_same_alloca(
+; COMBINED-SAME: float [[V0:%.*]], float [[V1:%.*]], float [[V2:%.*]], float [[V3:%.*]], i1 [[COND:%.*]], ptr addrspace(1) [[OUT:%.*]]) {
+; COMBINED-NEXT:  [[ENTRY:.*:]]
+; COMBINED-NEXT:    [[SLOT_SROA_0:%.*]] = alloca <4 x float>, align 16, addrspace(5)
+; COMBINED-NEXT:    [[SLOT_SROA_0_4_GEP_SROA_IDX8_SLOT_SROA_0_4_GEP1_SROA_IDX9:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 4
+; COMBINED-NEXT:    [[SLOT_SROA_0_8_GEP3_SROA_IDX10_SLOT_SROA_0_8_GEP4_SROA_IDX11:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 8
+; COMBINED-NEXT:    [[SLOT_SROA_0_12_GEP6_SROA_IDX12_SLOT_SROA_0_12_GEP7_SROA_IDX13:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT_SROA_0]], i64 12
+; COMBINED-NEXT:    store float [[V0]], ptr addrspace(5) [[SLOT_SROA_0]], align 16
+; COMBINED-NEXT:    store float [[V1]], ptr addrspace(5) [[SLOT_SROA_0_4_GEP_SROA_IDX8_SLOT_SROA_0_4_GEP1_SROA_IDX9]], align 4
+; COMBINED-NEXT:    store float [[V2]], ptr addrspace(5) [[SLOT_SROA_0_8_GEP3_SROA_IDX10_SLOT_SROA_0_8_GEP4_SROA_IDX11]], align 4
+; COMBINED-NEXT:    store float [[V3]], ptr addrspace(5) [[SLOT_SROA_0_12_GEP6_SROA_IDX12_SLOT_SROA_0_12_GEP7_SROA_IDX13]], align 4
+; COMBINED-NEXT:    [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC:%.*]] = load <4 x float>, ptr addrspace(5) [[SLOT_SROA_0]], align 16
+; COMBINED-NEXT:    [[E0:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i64 0
+; COMBINED-NEXT:    [[E1:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i64 1
+; COMBINED-NEXT:    [[E2:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i64 2
+; COMBINED-NEXT:    [[E3:%.*]] = extractelement <4 x float> [[SLOT_SROA_0_0_SLOT_SROA_0_0_VEC]], i64 3
+; COMBINED-NEXT:    [[SUM01:%.*]] = fadd float [[E0]], [[E1]]
+; COMBINED-NEXT:    [[SUM23:%.*]] = fadd float [[E2]], [[E3]]
+; COMBINED-NEXT:    [[SUM:%.*]] = fadd float [[SUM01]], [[SUM23]]
+; COMBINED-NEXT:    store float [[SUM]], ptr addrspace(1) [[OUT]], align 4
+; COMBINED-NEXT:    ret void
+;
+entry:
+  %slot = alloca [4 x float], align 16, addrspace(5)
+  br i1 %cond, label %left, label %right
+
+left:
+  br label %merge
+
+right:
+  br label %merge
+
+merge:
+  %ptr = phi ptr addrspace(5) [ %slot, %left ], [ %slot, %right ]
+  store float %v0, ptr addrspace(5) %ptr, align 16
+  %p1 = getelementptr inbounds float, ptr addrspace(5) %ptr, i32 1
+  store float %v1, ptr addrspace(5) %p1, align 4
+  %p2 = getelementptr inbounds float, ptr addrspace(5) %ptr, i32 2
+  store float %v2, ptr addrspace(5) %p2, align 4
+  %p3 = getelementptr inbounds float, ptr addrspace(5) %ptr, i32 3
+  store float %v3, ptr addrspace(5) %p3, align 4
+
+  %vec = load <4 x float>, ptr addrspace(5) %slot, align 16
+  %e0 = extractelement <4 x float> %vec, i32 0
+  %e1 = extractelement <4 x float> %vec, i32 1
+  %e2 = extractelement <4 x float> %vec, i32 2
+  %e3 = extractelement <4 x float> %vec, i32 3
+
+  %sum01 = fadd float %e0, %e1
+  %sum23 = fadd float %e2, %e3
+  %sum   = fadd float %sum01, %sum23
+  store float %sum, ptr addrspace(1) %out, align 4
+  ret void
+}
+
+define float @no_split_pointer_store() {
+; SROA-LABEL: define float @no_split_pointer_store() {
+; SROA-NEXT:  [[ENTRY:.*:]]
+; SROA-NEXT:    [[SLOT:%.*]] = alloca [4 x float], align 16, addrspace(5)
+; SROA-NEXT:    [[GEP0:%.*]] = getelementptr inbounds float, ptr addrspace(5) [[SLOT]], i32 0
+; SROA-NEXT:    [[OTHER:%.*]] = getelementptr inbounds float, ptr addrspace(5) [[SLOT]], i32 1
+; SROA-NEXT:    store ptr addrspace(5) [[OTHER]], ptr addrspace(5) [[GEP0]], align 8
+; SROA-NEXT:    [[VEC:%.*]] = load <4 x float>, ptr addrspace(5) [[SLOT]], align 16
+; SROA-NEXT:    [[E0:%.*]] = extractelement <4 x float> [[VEC]], i32 0
+; SROA-NEXT:    ret float [[E0]]
+;
+; COMBINED-LABEL: define float @no_split_pointer_store() {
+; COMBINED-NEXT:  [[ENTRY:.*:]]
+; COMBINED-NEXT:    [[SLOT:%.*]] = alloca [4 x float], align 16, addrspace(5)
+; COMBINED-NEXT:    [[OTHER:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT]], i64 4
+; COMBINED-NEXT:    store ptr addrspace(5) [[OTHER]], ptr addrspace(5) [[SLOT]], align 8
+; COMBINED-NEXT:    [[VEC:%.*]] = load <4 x float>, ptr addrspace(5) [[SLOT]], align 16
+; COMBINED-NEXT:    [[E0:%.*]] = extractelement <4 x float> [[VEC]], i64 0
+; COMBINED-NEXT:    ret float [[E0]]
+;
+entry:
+  %slot  = alloca [4 x float], align 16, addrspace(5)
+  %gep0  = getelementptr inbounds float, ptr addrspace(5) %slot, i32 0
+  %other = getelementptr inbounds float, ptr addrspace(5) %slot, i32 1
+  store ptr addrspace(5) %other, ptr addrspace(5) %gep0
+  %vec = load <4 x float>, ptr addrspace(5) %slot, align 16
+  %e0  = extractelement <4 x float> %vec, i32 0
+  ret float %e0
+}
+
+define float @no_split_escaped_alloca() {
+; SROA-LABEL: define float @no_split_escaped_alloca() {
+; SROA-NEXT:  [[ENTRY:.*:]]
+; SROA-NEXT:    [[SLOT:%.*]] = alloca <4 x float>, align 16
+; SROA-NEXT:    call void @escape(ptr [[SLOT]])
+; SROA-NEXT:    store <2 x float> <float 1.000000e+00, float 2.000000e+00>, ptr [[SLOT]], align 16
+; SROA-NEXT:    [[VEC:%.*]] = load <4 x float>, ptr [[SLOT]], align 16
+; SROA-NEXT:    [[E0:%.*]] = extractelement <4 x float> [[VEC]], i32 0
+; SROA-NEXT:    ret float [[E0]]
+;
+; COMBINED-LABEL: define float @no_split_escaped_alloca() {
+; COMBINED-NEXT:  [[ENTRY:.*:]]
+; COMBINED-NEXT:    [[SLOT:%.*]] = alloca <4 x float>, align 16
+; COMBINED-NEXT:    call void @escape(ptr nonnull [[SLOT]])
+; COMBINED-NEXT:    store <2 x float> <float 1.000000e+00, float 2.000000e+00>, ptr [[SLOT]], align 16
+; COMBINED-NEXT:    [[VEC:%.*]] = load <4 x float>, ptr [[SLOT]], align 16
+; COMBINED-NEXT:    [[E0:%.*]] = extractelement <4 x float> [[VEC]], i64 0
+; COMBINED-NEXT:    ret float [[E0]]
+;
+entry:
+  %slot = alloca <4 x float>, align 16
+  call void @escape(ptr %slot)
+  store <2 x float> <float 1.0, float 2.0>, ptr %slot, align 16
+  %vec = load <4 x float>, ptr %slot, align 16
+  %e0 = extractelement <4 x float> %vec, i32 0
+  ret float %e0
+}
+
+define void @no_split_phi_diff_allocas(  float %v0, float %v1, float %v2, float %v3, i1 %cond, ptr addrspace(1) %out) {
+; SROA-LABEL: define void @no_split_phi_diff_allocas(
+; SROA-SAME: float [[V0:%.*]], float [[V1:%.*]], float [[V2:%.*]], float [[V3:%.*]], i1 [[COND:%.*]], ptr addrspace(1) [[OUT:%.*]]) {
+; SROA-NEXT:  [[ENTRY:.*:]]
+; SROA-NEXT:    [[SLOT1:%.*]] = alloca [4 x float], align 16, addrspace(5)
+; SROA-NEXT:    [[SLOT2:%.*]] = alloca [4 x float], align 16, addrspace(5)
+; SROA-NEXT:    br i1 [[COND]], label %[[LEFT:.*]], label %[[RIGHT:.*]]
+; SROA:       [[LEFT]]:
+; SROA-NEXT:    store float [[V0]], ptr addrspace(5) [[SLOT1]], align 16
+; SROA-NEXT:    [[SLOT1_4_S1P1_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT1]], i64 4
+; SROA-NEXT:    store float [[V1]], ptr addrspace(5) [[SLOT1_4_S1P1_SROA_IDX]], align 4
+; SROA-NEXT:    [[SLOT1_8_S1P2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT1]], i64 8
+; SROA-NEXT:    store float [[V2]], ptr addrspace(5) [[SLOT1_8_S1P2_SROA_IDX]], align 8
+; SROA-NEXT:    [[SLOT1_12_S1P3_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT1]], i64 12
+; SROA-NEXT:    store float [[V3]], ptr addrspace(5) [[SLOT1_12_S1P3_SROA_IDX]], align 4
+; SROA-NEXT:    br label %[[MERGE:.*]]
+; SROA:       [[RIGHT]]:
+; SROA-NEXT:    store float [[V0]], ptr addrspace(5) [[SLOT2]], align 16
+; SROA-NEXT:    [[SLOT2_4_S2P1_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT2]], i64 4
+; SROA-NEXT:    store float [[V1]], ptr addrspace(5) [[SLOT2_4_S2P1_SROA_IDX]], align 4
+; SROA-NEXT:    [[SLOT2_8_S2P2_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT2]], i64 8
+; SROA-NEXT:    store float [[V2]], ptr addrspace(5) [[SLOT2_8_S2P2_SROA_IDX]], align 8
+; SROA-NEXT:    [[SLOT2_12_S2P3_SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(5) [[SLOT2]], i64 12
+; SROA-NEXT:    store float [[V3]], ptr addrspace(5) [[SLOT2_12_S2P3_SROA_IDX]], align 4
+; SROA-NEXT:    br label %[[MERGE]]
+; SROA:       [[MERGE]]:
+; SROA-NEXT:    [[PTR:%.*]] = phi ptr addrspace(5) [ [[SLOT1]], %[[LEFT]] ], [ [[SLOT2]], %[[RIGHT]] ]
+; SROA-NEXT:    [[VEC:%.*]] = load <4 x float>, ptr addrspace(5) [[PTR]], align 16
+; SROA-NEXT:    [[F0:%.*]] = extractelement <4 x float> [[VEC]], i32 0
+; SROA-NEXT:    [[F1:%.*]] = extractelement <4 x float> [[VEC]], i32 1
+; SROA-NEXT:    [[F2:%.*]] = extractelement <4 x float> [[VEC]], i32 2
+; SROA-NEXT:    [[F3:%.*]] = extractelement <4 x float> [[VEC]], i32 3
+; SROA-NEXT:    [[SUM01:%.*]] = fadd float [[F0]], [[F1]]
+; SROA-NEXT:    [[SUM23:%.*]] = fadd float [[F2]], [[F3]]
+; SROA-NEXT:    [[SUM:%.*]] = fadd float [[SUM01]], [[SUM23]]
+; SROA-NEXT:    store float [[SUM]], ptr addrspace(1) [[OUT]], align 4
+; SROA-NEXT:    ret void
+;
+; COMBINED-LABEL: define void @no_split_phi_diff_allocas(
+; COMBINED-SAME: float [[V0:%.*]], float [[V1:%.*]], float [[V2:%.*]], float [[V3:%.*]], i1 [[COND:%.*]], ptr addrspace(1) [[OUT:%.*]]) {
+; COMBINED-NEXT:  [[ENTRY:.*:]]
+; COMBINED-NEXT:    [[SLOT1:%.*]] = alloca [4 x float], align 16, addrspace(5)
+; COMBINED-NEXT:    [[SLOT2:%.*]] = alloca [4 x float], align 16, addrspace(5)
+; COMBINED-NEXT:    br i1 [[COND]], label %[[LEFT:.*]], label %[[RIGHT:.*]]
+; COMBINED:       [[LEFT]]:
+; COMBINED-NEXT:    store float [[V0]], ptr addrspace(5) [[SLOT1]], align 16
+; COMBINED-NEXT:    [[SLOT1_4_S1P1_SROA_IDX:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT1]], i64 4
+; COMBINED-NEXT:    store float [[V1]], ptr addrspace(5) [[SLOT1_4_S1P1_SROA_IDX]], align 4
+; COMBINED-NEXT:    [[SLOT1_8_S1P2_SROA_IDX:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT1]], i64 8
+; COMBINED-NEXT:    store float [[V2]], ptr addrspace(5) [[SLOT1_8_S1P2_SROA_IDX]], align 8
+; COMBINED-NEXT:    [[SLOT1_12_S1P3_SROA_IDX:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT1]], i64 12
+; COMBINED-NEXT:    store float [[V3]], ptr addrspace(5) [[SLOT1_12_S1P3_SROA_IDX]], align 4
+; COMBINED-NEXT:    br label %[[MERGE:.*]]
+; COMBINED:       [[RIGHT]]:
+; COMBINED-NEXT:    store float [[V0]], ptr addrspace(5) [[SLOT2]], align 16
+; COMBINED-NEXT:    [[SLOT2_4_S2P1_SROA_IDX:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT2]], i64 4
+; COMBINED-NEXT:    store float [[V1]], ptr addrspace(5) [[SLOT2_4_S2P1_SROA_IDX]], align 4
+; COMBINED-NEXT:    [[SLOT2_8_S2P2_SROA_IDX:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT2]], i64 8
+; COMBINED-NEXT:    store float [[V2]], ptr addrspace(5) [[SLOT2_8_S2P2_SROA_IDX]], align 8
+; COMBINED-NEXT:    [[SLOT2_12_S2P3_SROA_IDX:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) [[SLOT2]], i64 12
+; COMBINED-NEXT:    store float [[V3]], ptr addrspace(5) [[SLOT2_12_S2P3_SROA_IDX]], align 4
+; COMBINED-NEXT:    br label %[[MERGE]]
+; COMBINED:       [[MERGE]]:
+; COMBINED-NEXT:    [[PTR:%.*]] = phi ptr addrspace(5) [ [[SLOT1]], %[[LEFT]] ], [ [[SLOT2]], %[[RIGHT]] ]
+; COMBINED-NEXT:    [[VEC:%.*]] = load <4 x float>, ptr addrspace(5) [[PTR]], align 16
+; COMBINED-NEXT:    [[F0:%.*]] = extractelement <4 x float> [[VEC]], i64 0
+; COMBINED-NEXT:    [[F1:%.*]] = extractelement <4 x float> [[VEC]], i64 1
+; COMBINED-NEXT:    [[F2:%.*]] = extractelement <4 x float> [[VEC]], i64 2
+; COMBINED-NEXT:    [[F3:%.*]] = extractelement <4 x float> [[VEC]], i64 3
+; COMBINED-NEXT:    [[SUM01:%.*]] = fadd float [[F0]], [[F1]]
+; COMBINED-NEXT:    [[SUM23:%.*]] = fadd float [[F2]], [[F3]]
+; COMBINED-NEXT:    [[SUM:%.*]] = fadd float [[SUM01]], [[SUM23]]
+; COMBINED-NEXT:    store float [[SUM]], ptr addrspace(1) [[OUT]], align 4
+; COMBINED-NEXT:    ret void
+;
+entry:
+  %slot1 = alloca [4 x float], align 16, addrspace(5)
+  %slot2 = alloca [4 x float], align 16, addrspace(5)
+  br i1 %cond, label %left, label %right
+
+left:
+  store float %v0, ptr addrspace(5) %slot1, align 16
+  %s1p1 = getelementptr inbounds float, ptr addrspace(5) %slot1, i32 1
+  store float %v1, ptr addrspace(5) %s1p1, align 4
+  %s1p2 = getelementptr inbounds float, ptr addrspace(5) %slot1, i32 2
+  store float %v2, ptr addrspace(5) %s1p2, align 4
+  %s1p3 = getelementptr inbounds float, ptr addrspace(5) %slot1, i32 3
+  store float %v3, ptr addrspace(5) %s1p3, align 4
+  br label %merge
+
+right:
+  store float %v0, ptr addrspace(5) %slot2, align 16
+  %s2p1 = getelementptr inbounds float, ptr addrspace(5) %slot2, i32 1
+  store float %v1, ptr addrspace(5) %s2p1, align 4
+  %s2p2 = getelementptr inbounds float, ptr addrspace(5) %slot2, i32 2
+  store float %v2, ptr addrspace(5) %s2p2, align 8
+  %s2p3 = getelementptr inbounds float, ptr addrspace(5) %slot2, i32 3
+  store float %v3, ptr addrspace(5) %s2p3, align 4
+  br label %merge
+
+merge:
+  %ptr = phi ptr addrspace(5) [ %slot1, %left ], [ %slot2, %right ]
+  %vec = load <4 x float>, ptr addrspace(5) %ptr, align 16
+  %f0 = extractelement <4 x float> %vec, i32 0
+  %f1 = extractelement <4 x float> %vec, i32 1
+  %f2 = extractelement <4 x float> %vec, i32 2
+  %f3 = extractelement <4 x float> %vec, i32 3
+
+  %sum01 = fadd float %f0, %f1
+  %sum23 = fadd float %f2, %f3
+  %sum   = fadd float %sum01, %sum23
+  store float %sum, ptr addrspace(1) %out, align 4
+  ret void
+}
+
+define float @no_split_scalable_vector_store(<vscale x 4 x float> %sv) {
+; SROA-LABEL: define float @no_split_scalable_vector_store(
+; SROA-SAME: <vscale x 4 x float> [[SV:%.*]]) {
+; SROA-NEXT:  [[ENTRY:.*:]]
+; SROA-NEXT:    [[SLOT:%.*]] = alloca <4 x float>, align 16
+; SROA-NEXT:    store <vscale x 4 x float> [[SV]], ptr [[SLOT]], align 16
+; SROA-NEXT:    [[VEC:%.*]] = load <4 x float>, ptr [[SLOT]], align 16
+; SROA-NEXT:    [[E0:%.*]] = extractelement <4 x float> [[VEC]], i32 0
+; SROA-NEXT:    ret float [[E0]]
+;
+; COMBINED-LABEL: define float @no_split_scalable_vector_store(
+; COMBINED-SAME: <vscale x 4 x float> [[SV:%.*]]) {
+; COMBINED-NEXT:  [[ENTRY:.*:]]
+; COMBINED-NEXT:    [[SLOT:%.*]] = alloca <4 x float>, align 16
+; COMBINED-NEXT:    store <vscale x 4 x float> [[SV]], ptr [[SLOT]], align 16
+; COMBINED-NEXT:    [[VEC:%.*]] = load <4 x float>, ptr [[SLOT]], align 16
+; COMBINED-NEXT:    [[E0:%.*]] = extractelement <4 x float> [[VEC]], i64 0
+; COMBINED-NEXT:    ret float [[E0]]
+;
+entry:
+  %slot = alloca <4 x float>, align 16
+  store <vscale x 4 x float> %sv, ptr %slot, align 16
+  %vec = load <4 x float>, ptr %slot, align 16
+  %e0 = extractelement <4 x float> %vec, i32 0
+  ret float %e0
+}
+
+declare void @escape(ptr)
+declare void @llvm.memcpy.p0.p0.i32(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i32, i1 immarg)



More information about the llvm-commits mailing list