[llvm] [SLP][NFC]Add tests with missed vectorization candidates, NFC (PR #218247)

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 23 08:04:12 PDT 2026


https://github.com/alexey-bataev created https://github.com/llvm/llvm-project/pull/218247

None

>From f4f35c010a608ea9dc37bcad972907c17444122a Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev at outlook.com>
Date: Sun, 23 Aug 2026 08:04:00 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
 =?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.7
---
 .../X86/splat-gather-operands.ll              | 336 ++++++++++++++++++
 1 file changed, 336 insertions(+)
 create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/splat-gather-operands.ll

diff --git a/llvm/test/Transforms/SLPVectorizer/X86/splat-gather-operands.ll b/llvm/test/Transforms/SLPVectorizer/X86/splat-gather-operands.ll
new file mode 100644
index 0000000000000..c374ec10f540c
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/splat-gather-operands.ll
@@ -0,0 +1,336 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu -mcpu=skylake-avx512 -S | FileCheck %s
+
+; Splat gather operands of the alternate add/sub tree are vectorized together
+; as a separate subtree and emitted as broadcasts of the vectorized value.
+
+define i32 @test(ptr noalias %pix1, i32 %i_pix1, ptr noalias %pix2, i32 %i_pix2, ptr noalias %R) {
+; CHECK-LABEL: @test(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[IDX_EXT_I:%.*]] = sext i32 [[I_PIX1:%.*]] to i64
+; CHECK-NEXT:    [[IDX_EXT63_I:%.*]] = sext i32 [[I_PIX2:%.*]] to i64
+; CHECK-NEXT:    br label [[LOOP_1247:%.*]]
+; CHECK:       loop.1247:
+; CHECK-NEXT:    [[I1_I64_0:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[NEXTIVLOOP_1247:%.*]], [[LOOP_1247]] ]
+; CHECK-NEXT:    [[I:%.*]] = mul i64 [[I1_I64_0]], [[IDX_EXT_I]]
+; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds i8, ptr [[PIX1:%.*]], i64 [[I]]
+; CHECK-NEXT:    [[LOAD00:%.*]] = load i8, ptr [[GEP]], align 1
+; CHECK-NEXT:    [[I1:%.*]] = mul i64 [[I1_I64_0]], [[IDX_EXT63_I]]
+; CHECK-NEXT:    [[GEP013:%.*]] = getelementptr inbounds i8, ptr [[PIX2:%.*]], i64 [[I1]]
+; CHECK-NEXT:    [[LOAD014:%.*]] = load i8, ptr [[GEP013]], align 1
+; CHECK-NEXT:    [[I2:%.*]] = add i64 [[I]], 4
+; CHECK-NEXT:    [[GEP015:%.*]] = getelementptr inbounds i8, ptr [[PIX1]], i64 [[I2]]
+; CHECK-NEXT:    [[LOAD016:%.*]] = load i8, ptr [[GEP015]], align 1
+; CHECK-NEXT:    [[I3:%.*]] = add i64 [[I1]], 4
+; CHECK-NEXT:    [[GEP017:%.*]] = getelementptr inbounds i8, ptr [[PIX2]], i64 [[I3]]
+; CHECK-NEXT:    [[LOAD018:%.*]] = load i8, ptr [[GEP017]], align 1
+; CHECK-NEXT:    [[I4:%.*]] = add i64 [[I]], 1
+; CHECK-NEXT:    [[GEP019:%.*]] = getelementptr inbounds i8, ptr [[PIX1]], i64 [[I4]]
+; CHECK-NEXT:    [[LOAD020:%.*]] = load i8, ptr [[GEP019]], align 1
+; CHECK-NEXT:    [[I5:%.*]] = add i64 [[I1]], 1
+; CHECK-NEXT:    [[GEP021:%.*]] = getelementptr inbounds i8, ptr [[PIX2]], i64 [[I5]]
+; CHECK-NEXT:    [[LOAD022:%.*]] = load i8, ptr [[GEP021]], align 1
+; CHECK-NEXT:    [[I6:%.*]] = add i64 [[I]], 5
+; CHECK-NEXT:    [[GEP023:%.*]] = getelementptr inbounds i8, ptr [[PIX1]], i64 [[I6]]
+; CHECK-NEXT:    [[LOAD024:%.*]] = load i8, ptr [[GEP023]], align 1
+; CHECK-NEXT:    [[I7:%.*]] = add i64 [[I1]], 5
+; CHECK-NEXT:    [[GEP025:%.*]] = getelementptr inbounds i8, ptr [[PIX2]], i64 [[I7]]
+; CHECK-NEXT:    [[LOAD026:%.*]] = load i8, ptr [[GEP025]], align 1
+; CHECK-NEXT:    [[I8:%.*]] = add i64 [[I]], 2
+; CHECK-NEXT:    [[GEP027:%.*]] = getelementptr inbounds i8, ptr [[PIX1]], i64 [[I8]]
+; CHECK-NEXT:    [[LOAD028:%.*]] = load i8, ptr [[GEP027]], align 1
+; CHECK-NEXT:    [[I9:%.*]] = add i64 [[I1]], 2
+; CHECK-NEXT:    [[GEP029:%.*]] = getelementptr inbounds i8, ptr [[PIX2]], i64 [[I9]]
+; CHECK-NEXT:    [[LOAD030:%.*]] = load i8, ptr [[GEP029]], align 1
+; CHECK-NEXT:    [[I10:%.*]] = add i64 [[I]], 6
+; CHECK-NEXT:    [[GEP031:%.*]] = getelementptr inbounds i8, ptr [[PIX1]], i64 [[I10]]
+; CHECK-NEXT:    [[LOAD032:%.*]] = load i8, ptr [[GEP031]], align 1
+; CHECK-NEXT:    [[I11:%.*]] = add i64 [[I1]], 6
+; CHECK-NEXT:    [[GEP033:%.*]] = getelementptr inbounds i8, ptr [[PIX2]], i64 [[I11]]
+; CHECK-NEXT:    [[LOAD034:%.*]] = load i8, ptr [[GEP033]], align 1
+; CHECK-NEXT:    [[I12:%.*]] = add i64 [[I]], 3
+; CHECK-NEXT:    [[GEP035:%.*]] = getelementptr inbounds i8, ptr [[PIX1]], i64 [[I12]]
+; CHECK-NEXT:    [[LOAD036:%.*]] = load i8, ptr [[GEP035]], align 1
+; CHECK-NEXT:    [[I13:%.*]] = add i64 [[I1]], 3
+; CHECK-NEXT:    [[GEP037:%.*]] = getelementptr inbounds i8, ptr [[PIX2]], i64 [[I13]]
+; CHECK-NEXT:    [[LOAD038:%.*]] = load i8, ptr [[GEP037]], align 1
+; CHECK-NEXT:    [[I14:%.*]] = add i64 [[I]], 7
+; CHECK-NEXT:    [[GEP039:%.*]] = getelementptr inbounds i8, ptr [[PIX1]], i64 [[I14]]
+; CHECK-NEXT:    [[LOAD040:%.*]] = load i8, ptr [[GEP039]], align 1
+; CHECK-NEXT:    [[I15:%.*]] = add i64 [[I1]], 7
+; CHECK-NEXT:    [[GEP041:%.*]] = getelementptr inbounds i8, ptr [[PIX2]], i64 [[I15]]
+; CHECK-NEXT:    [[LOAD042:%.*]] = load i8, ptr [[GEP041]], align 1
+; CHECK-NEXT:    [[I16:%.*]] = zext i8 [[LOAD036]] to i32
+; CHECK-NEXT:    [[I17:%.*]] = zext i8 [[LOAD028]] to i32
+; CHECK-NEXT:    [[I18:%.*]] = zext i8 [[LOAD020]] to i32
+; CHECK-NEXT:    [[I19:%.*]] = zext i8 [[LOAD00]] to i32
+; CHECK-NEXT:    [[I20:%.*]] = zext i8 [[LOAD042]] to i32
+; CHECK-NEXT:    [[I21:%.*]] = zext i8 [[LOAD034]] to i32
+; CHECK-NEXT:    [[I22:%.*]] = zext i8 [[LOAD026]] to i32
+; CHECK-NEXT:    [[I23:%.*]] = zext i8 [[LOAD018]] to i32
+; CHECK-NEXT:    [[I24:%.*]] = zext i8 [[LOAD038]] to i32
+; CHECK-NEXT:    [[I25:%.*]] = zext i8 [[LOAD030]] to i32
+; CHECK-NEXT:    [[I26:%.*]] = zext i8 [[LOAD022]] to i32
+; CHECK-NEXT:    [[I27:%.*]] = zext i8 [[LOAD014]] to i32
+; CHECK-NEXT:    [[I28:%.*]] = zext i8 [[LOAD040]] to i32
+; CHECK-NEXT:    [[I29:%.*]] = zext i8 [[LOAD032]] to i32
+; CHECK-NEXT:    [[I30:%.*]] = zext i8 [[LOAD024]] to i32
+; CHECK-NEXT:    [[I31:%.*]] = zext i8 [[LOAD016]] to i32
+; CHECK-NEXT:    [[I32:%.*]] = shl i32 [[I20]], 16
+; CHECK-NEXT:    [[I33:%.*]] = shl i32 [[I21]], 16
+; CHECK-NEXT:    [[I34:%.*]] = shl i32 [[I22]], 16
+; CHECK-NEXT:    [[I35:%.*]] = shl i32 [[I23]], 16
+; CHECK-NEXT:    [[I36:%.*]] = shl i32 [[I28]], 16
+; CHECK-NEXT:    [[I37:%.*]] = shl i32 [[I29]], 16
+; CHECK-NEXT:    [[I38:%.*]] = shl i32 [[I30]], 16
+; CHECK-NEXT:    [[I39:%.*]] = shl i32 [[I31]], 16
+; CHECK-NEXT:    [[N1:%.*]] = sub i32 [[I36]], [[I24]]
+; CHECK-NEXT:    [[N2:%.*]] = sub i32 [[N1]], [[I32]]
+; CHECK-NEXT:    [[N3:%.*]] = add i32 [[N2]], [[I16]]
+; CHECK-NEXT:    [[N4:%.*]] = sub i32 [[I37]], [[I25]]
+; CHECK-NEXT:    [[N5:%.*]] = sub i32 [[N4]], [[I33]]
+; CHECK-NEXT:    [[N6:%.*]] = add i32 [[N5]], [[I17]]
+; CHECK-NEXT:    [[N7:%.*]] = sub i32 [[I38]], [[I26]]
+; CHECK-NEXT:    [[N8:%.*]] = sub i32 [[N7]], [[I34]]
+; CHECK-NEXT:    [[N9:%.*]] = add i32 [[N8]], [[I18]]
+; CHECK-NEXT:    [[N10:%.*]] = sub i32 [[I39]], [[I27]]
+; CHECK-NEXT:    [[N11:%.*]] = sub i32 [[N10]], [[I35]]
+; CHECK-NEXT:    [[N12:%.*]] = add i32 [[N11]], [[I19]]
+; CHECK-NEXT:    [[GEP043:%.*]] = getelementptr inbounds [16 x [8 x i32]], ptr [[R:%.*]], i64 0, i64 [[I1_I64_0]], i64 0
+; CHECK-NEXT:    [[N151:%.*]] = add i32 [[N12]], [[N9]]
+; CHECK-NEXT:    [[N159:%.*]] = add i32 [[N151]], [[N6]]
+; CHECK-NEXT:    [[N167:%.*]] = add i32 [[N159]], [[N3]]
+; CHECK-NEXT:    store i32 [[N167]], ptr [[GEP043]], align 4
+; CHECK-NEXT:    [[GEP045:%.*]] = getelementptr inbounds [16 x [8 x i32]], ptr [[R]], i64 0, i64 [[I1_I64_0]], i64 2
+; CHECK-NEXT:    [[N156:%.*]] = add i32 [[N12]], [[N9]]
+; CHECK-NEXT:    [[N164:%.*]] = sub i32 [[N156]], [[N6]]
+; CHECK-NEXT:    [[N172:%.*]] = sub i32 [[N164]], [[N3]]
+; CHECK-NEXT:    store i32 [[N172]], ptr [[GEP045]], align 4
+; CHECK-NEXT:    [[GEP063:%.*]] = getelementptr inbounds [16 x [8 x i32]], ptr [[R]], i64 0, i64 [[I1_I64_0]], i64 1
+; CHECK-NEXT:    [[N157:%.*]] = sub i32 [[N12]], [[N9]]
+; CHECK-NEXT:    [[N165:%.*]] = add i32 [[N157]], [[N6]]
+; CHECK-NEXT:    [[N173:%.*]] = sub i32 [[N165]], [[N3]]
+; CHECK-NEXT:    store i32 [[N173]], ptr [[GEP063]], align 4
+; CHECK-NEXT:    [[GEP081:%.*]] = getelementptr inbounds [16 x [8 x i32]], ptr [[R]], i64 0, i64 [[I1_I64_0]], i64 3
+; CHECK-NEXT:    [[N158:%.*]] = sub i32 [[N12]], [[N9]]
+; CHECK-NEXT:    [[N166:%.*]] = sub i32 [[N158]], [[N6]]
+; CHECK-NEXT:    [[N174:%.*]] = add i32 [[N166]], [[N3]]
+; CHECK-NEXT:    store i32 [[N174]], ptr [[GEP081]], align 4
+; CHECK-NEXT:    [[NEXTIVLOOP_1247]] = add nuw nsw i64 [[I1_I64_0]], 1
+; CHECK-NEXT:    [[CONDLOOP_1247:%.*]] = icmp ult i64 [[NEXTIVLOOP_1247]], 16
+; CHECK-NEXT:    br i1 [[CONDLOOP_1247]], label [[LOOP_1247]], label [[AFTERLOOP_1247:%.*]]
+; CHECK:       afterloop.1247:
+; CHECK-NEXT:    ret i32 0
+;
+entry:
+  %idx.ext.i = sext i32 %i_pix1 to i64
+  %idx.ext63.i = sext i32 %i_pix2 to i64
+  br label %loop.1247
+
+loop.1247:
+  %i1.i64.0 = phi i64 [ 0, %entry ], [ %nextivloop.1247, %loop.1247 ]
+  %i = mul i64 %i1.i64.0, %idx.ext.i
+  %gep = getelementptr inbounds i8, ptr %pix1, i64 %i
+  %load00 = load i8, ptr %gep, align 1
+  %i1 = mul i64 %i1.i64.0, %idx.ext63.i
+  %gep013 = getelementptr inbounds i8, ptr %pix2, i64 %i1
+  %load014 = load i8, ptr %gep013, align 1
+  %i2 = add i64 %i, 4
+  %gep015 = getelementptr inbounds i8, ptr %pix1, i64 %i2
+  %load016 = load i8, ptr %gep015, align 1
+  %i3 = add i64 %i1, 4
+  %gep017 = getelementptr inbounds i8, ptr %pix2, i64 %i3
+  %load018 = load i8, ptr %gep017, align 1
+  %i4 = add i64 %i, 1
+  %gep019 = getelementptr inbounds i8, ptr %pix1, i64 %i4
+  %load020 = load i8, ptr %gep019, align 1
+  %i5 = add i64 %i1, 1
+  %gep021 = getelementptr inbounds i8, ptr %pix2, i64 %i5
+  %load022 = load i8, ptr %gep021, align 1
+  %i6 = add i64 %i, 5
+  %gep023 = getelementptr inbounds i8, ptr %pix1, i64 %i6
+  %load024 = load i8, ptr %gep023, align 1
+  %i7 = add i64 %i1, 5
+  %gep025 = getelementptr inbounds i8, ptr %pix2, i64 %i7
+  %load026 = load i8, ptr %gep025, align 1
+  %i8 = add i64 %i, 2
+  %gep027 = getelementptr inbounds i8, ptr %pix1, i64 %i8
+  %load028 = load i8, ptr %gep027, align 1
+  %i9 = add i64 %i1, 2
+  %gep029 = getelementptr inbounds i8, ptr %pix2, i64 %i9
+  %load030 = load i8, ptr %gep029, align 1
+  %i10 = add i64 %i, 6
+  %gep031 = getelementptr inbounds i8, ptr %pix1, i64 %i10
+  %load032 = load i8, ptr %gep031, align 1
+  %i11 = add i64 %i1, 6
+  %gep033 = getelementptr inbounds i8, ptr %pix2, i64 %i11
+  %load034 = load i8, ptr %gep033, align 1
+  %i12 = add i64 %i, 3
+  %gep035 = getelementptr inbounds i8, ptr %pix1, i64 %i12
+  %load036 = load i8, ptr %gep035, align 1
+  %i13 = add i64 %i1, 3
+  %gep037 = getelementptr inbounds i8, ptr %pix2, i64 %i13
+  %load038 = load i8, ptr %gep037, align 1
+  %i14 = add i64 %i, 7
+  %gep039 = getelementptr inbounds i8, ptr %pix1, i64 %i14
+  %load040 = load i8, ptr %gep039, align 1
+  %i15 = add i64 %i1, 7
+  %gep041 = getelementptr inbounds i8, ptr %pix2, i64 %i15
+  %load042 = load i8, ptr %gep041, align 1
+  %i16 = zext i8 %load036 to i32
+  %i17 = zext i8 %load028 to i32
+  %i18 = zext i8 %load020 to i32
+  %i19 = zext i8 %load00 to i32
+  %i20 = zext i8 %load042 to i32
+  %i21 = zext i8 %load034 to i32
+  %i22 = zext i8 %load026 to i32
+  %i23 = zext i8 %load018 to i32
+  %i24 = zext i8 %load038 to i32
+  %i25 = zext i8 %load030 to i32
+  %i26 = zext i8 %load022 to i32
+  %i27 = zext i8 %load014 to i32
+  %i28 = zext i8 %load040 to i32
+  %i29 = zext i8 %load032 to i32
+  %i30 = zext i8 %load024 to i32
+  %i31 = zext i8 %load016 to i32
+  %i32 = shl i32 %i20, 16
+  %i33 = shl i32 %i21, 16
+  %i34 = shl i32 %i22, 16
+  %i35 = shl i32 %i23, 16
+  %i36 = shl i32 %i28, 16
+  %i37 = shl i32 %i29, 16
+  %i38 = shl i32 %i30, 16
+  %i39 = shl i32 %i31, 16
+  %N1 = sub i32 %i36, %i24
+  %N2 = sub i32 %N1, %i32
+  %N3 = add i32 %N2, %i16
+  %N4 = sub i32 %i37, %i25
+  %N5 = sub i32 %N4, %i33
+  %N6 = add i32 %N5, %i17
+  %N7 = sub i32 %i38, %i26
+  %N8 = sub i32 %N7, %i34
+  %N9 = add i32 %N8, %i18
+  %N10 = sub i32 %i39, %i27
+  %N11 = sub i32 %N10, %i35
+  %N12 = add i32 %N11, %i19
+
+  %gep043 = getelementptr inbounds [16 x [8 x i32]], ptr %R, i64 0, i64 %i1.i64.0, i64 0
+  %N151 = add i32 %N12, %N9
+  %N159 = add i32 %N151, %N6
+  %N167 = add i32 %N159, %N3
+  store i32 %N167, ptr %gep043, align 4
+
+  %gep045 = getelementptr inbounds [16 x [8 x i32]], ptr %R, i64 0, i64 %i1.i64.0, i64 2
+  %N156 = add i32 %N12, %N9
+  %N164 = sub i32 %N156, %N6
+  %N172 = sub i32 %N164, %N3
+  store i32 %N172, ptr %gep045, align 4
+
+  %gep063 = getelementptr inbounds [16 x [8 x i32]], ptr %R, i64 0, i64 %i1.i64.0, i64 1
+  %N157 = sub i32 %N12, %N9
+  %N165 = add i32 %N157, %N6
+  %N173 = sub i32 %N165, %N3
+  store i32 %N173, ptr %gep063, align 4
+
+  %gep081 = getelementptr inbounds [16 x [8 x i32]], ptr %R, i64 0, i64 %i1.i64.0, i64 3
+  %N158 = sub i32 %N12, %N9
+  %N166 = sub i32 %N158, %N6
+  %N174 = add i32 %N166, %N3
+  store i32 %N174, ptr %gep081, align 4
+
+  %nextivloop.1247 = add nuw nsw i64 %i1.i64.0, 1
+  %condloop.1247 = icmp ult i64 %nextivloop.1247, 16
+  br i1 %condloop.1247, label %loop.1247, label %afterloop.1247
+
+afterloop.1247:
+  ret i32 0
+}
+
+; The splat scalars' subtree combined with gathered loads vectorization.
+define void @splat_with_gathered_loads(ptr %p, ptr %q, ptr %r) {
+; CHECK-LABEL: @splat_with_gathered_loads(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[G0:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 0
+; CHECK-NEXT:    [[G1:%.*]] = getelementptr i32, ptr [[P]], i64 3
+; CHECK-NEXT:    [[L0:%.*]] = load i32, ptr [[G0]], align 4
+; CHECK-NEXT:    [[L1:%.*]] = load i32, ptr [[G1]], align 4
+; CHECK-NEXT:    [[X:%.*]] = add i32 [[L0]], 1
+; CHECK-NEXT:    [[Y:%.*]] = add i32 [[L1]], 2
+; CHECK-NEXT:    [[R0:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[R1:%.*]] = sub i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[R2:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[R3:%.*]] = sub i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[S0:%.*]] = getelementptr i32, ptr [[R:%.*]], i64 0
+; CHECK-NEXT:    [[S1:%.*]] = getelementptr i32, ptr [[R]], i64 1
+; CHECK-NEXT:    [[S2:%.*]] = getelementptr i32, ptr [[R]], i64 2
+; CHECK-NEXT:    [[S3:%.*]] = getelementptr i32, ptr [[R]], i64 3
+; CHECK-NEXT:    store i32 [[R0]], ptr [[S0]], align 4
+; CHECK-NEXT:    store i32 [[R1]], ptr [[S1]], align 4
+; CHECK-NEXT:    store i32 [[R2]], ptr [[S2]], align 4
+; CHECK-NEXT:    store i32 [[R3]], ptr [[S3]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %g0 = getelementptr i32, ptr %p, i64 0
+  %g1 = getelementptr i32, ptr %p, i64 3
+  %l0 = load i32, ptr %g0, align 4
+  %l1 = load i32, ptr %g1, align 4
+  %x = add i32 %l0, 1
+  %y = add i32 %l1, 2
+  %r0 = add i32 %x, %y
+  %r1 = sub i32 %x, %y
+  %r2 = add i32 %x, %y
+  %r3 = sub i32 %x, %y
+  %s0 = getelementptr i32, ptr %r, i64 0
+  %s1 = getelementptr i32, ptr %r, i64 1
+  %s2 = getelementptr i32, ptr %r, i64 2
+  %s3 = getelementptr i32, ptr %r, i64 3
+  store i32 %r0, ptr %s0, align 4
+  store i32 %r1, ptr %s1, align 4
+  store i32 %r2, ptr %s2, align 4
+  store i32 %r3, ptr %s3, align 4
+  ret void
+}
+
+; The splat scalars form a copyable-compatible bundle: the shl is absorbed as
+; a copyable add (a + a), so the group vectorizes as a single copyable node.
+define void @copyable_splat_scalars(ptr %p, ptr %r) {
+; CHECK-LABEL: @copyable_splat_scalars(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[P:%.*]], align 4
+; CHECK-NEXT:    [[G1:%.*]] = getelementptr i32, ptr [[P]], i64 1
+; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[G1]], align 4
+; CHECK-NEXT:    [[X:%.*]] = add i32 [[A]], [[B]]
+; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[A]], 1
+; CHECK-NEXT:    [[R0:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[R1:%.*]] = sub i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[R2:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[R3:%.*]] = sub i32 [[X]], [[Y]]
+; CHECK-NEXT:    [[S1:%.*]] = getelementptr i32, ptr [[R:%.*]], i64 1
+; CHECK-NEXT:    [[S2:%.*]] = getelementptr i32, ptr [[R]], i64 2
+; CHECK-NEXT:    [[S3:%.*]] = getelementptr i32, ptr [[R]], i64 3
+; CHECK-NEXT:    store i32 [[R0]], ptr [[R]], align 4
+; CHECK-NEXT:    store i32 [[R1]], ptr [[S1]], align 4
+; CHECK-NEXT:    store i32 [[R2]], ptr [[S2]], align 4
+; CHECK-NEXT:    store i32 [[R3]], ptr [[S3]], align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  %a = load i32, ptr %p, align 4
+  %g1 = getelementptr i32, ptr %p, i64 1
+  %b = load i32, ptr %g1, align 4
+  %X = add i32 %a, %b
+  %Y = shl i32 %a, 1
+  %r0 = add i32 %X, %Y
+  %r1 = sub i32 %X, %Y
+  %r2 = add i32 %X, %Y
+  %r3 = sub i32 %X, %Y
+  %s1 = getelementptr i32, ptr %r, i64 1
+  %s2 = getelementptr i32, ptr %r, i64 2
+  %s3 = getelementptr i32, ptr %r, i64 3
+  store i32 %r0, ptr %r, align 4
+  store i32 %r1, ptr %s1, align 4
+  store i32 %r2, ptr %s2, align 4
+  store i32 %r3, ptr %s3, align 4
+  ret void
+}



More information about the llvm-commits mailing list