[llvm] [SLP][NFC]Add extra tests with missing vectorization, NFC (PR #228792)

Alexey Bataev via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 3 17:25:01 PDT 2026


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

None

>From 919f1936b685cc9e4fbf8432d3c1fcf99a310abd Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev at outlook.com>
Date: Sat, 3 Oct 2026 17:24:48 -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/absorbed-lane-undef-bitwidth.ll       |  75 ++++++++++++
 .../X86/wide-load-absorbed-lane.ll            |  36 ++++++
 .../absorbed-lane-shuffled-operand.ll         | 108 ++++++++++++++++++
 .../SLPVectorizer/volatile-loads-reduction.ll |  65 +++++++++++
 4 files changed, 284 insertions(+)
 create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/absorbed-lane-undef-bitwidth.ll
 create mode 100644 llvm/test/Transforms/SLPVectorizer/absorbed-lane-shuffled-operand.ll
 create mode 100644 llvm/test/Transforms/SLPVectorizer/volatile-loads-reduction.ll

diff --git a/llvm/test/Transforms/SLPVectorizer/X86/absorbed-lane-undef-bitwidth.ll b/llvm/test/Transforms/SLPVectorizer/X86/absorbed-lane-undef-bitwidth.ll
new file mode 100644
index 0000000000000..dce65afe6fe8e
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/absorbed-lane-undef-bitwidth.ll
@@ -0,0 +1,75 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
+
+declare i32 @get_size(i32 noundef)
+
+; The undef lane of the other operand of the lane with the absorbing zero of the
+; and does not prevent the bit width reduction.
+define void @swap_bytes(ptr noalias writeonly %out, i32 %t) {
+; CHECK-LABEL: define void @swap_bytes(
+; CHECK-SAME: ptr noalias writeonly [[OUT:%.*]], i32 [[T:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[CALL:%.*]] = call i32 @get_size(i32 noundef [[T]])
+; CHECK-NEXT:    [[TMP0:%.*]] = trunc i32 [[CALL]] to i16
+; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i16> <i16 poison, i16 0>, i16 [[TMP0]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <2 x i16> [[TMP1]], <2 x i16> <i16 -255, i16 poison>, <2 x i32> <i32 2, i32 0>
+; CHECK-NEXT:    [[TMP3:%.*]] = sub <2 x i16> [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = shufflevector <2 x i16> [[TMP3]], <2 x i16> poison, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+; CHECK-NEXT:    [[TMP5:%.*]] = and <8 x i16> [[TMP4]], <i16 -1, i16 1, i16 253, i16 3, i16 251, i16 5, i16 249, i16 7>
+; CHECK-NEXT:    [[TMP10:%.*]] = shufflevector <8 x i16> [[TMP4]], <8 x i16> <i16 -1, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison>, <8 x i32> <i32 8, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0>
+; CHECK-NEXT:    [[TMP11:%.*]] = and <8 x i16> <i16 0, i16 254, i16 2, i16 252, i16 4, i16 250, i16 6, i16 248>, [[TMP10]]
+; CHECK-NEXT:    [[TMP12:%.*]] = or disjoint <8 x i16> [[TMP5]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = trunc <8 x i16> [[TMP12]] to <8 x i8>
+; CHECK-NEXT:    store <8 x i8> [[TMP13]], ptr [[OUT]], align 1
+; CHECK-NEXT:    ret void
+;
+entry:
+  %call = call i32 @get_size(i32 noundef %t)
+  %sub = add i32 %call, 255
+  %not = sub i32 0, %call
+  %conv = trunc i32 %sub to i8
+  store i8 %conv, ptr %out, align 1
+  %and.1 = and i32 %not, 1
+  %sub2.1 = and i32 %sub, 254
+  %or.1 = or disjoint i32 %and.1, %sub2.1
+  %conv.1 = trunc nuw i32 %or.1 to i8
+  %p.1 = getelementptr inbounds nuw i8, ptr %out, i64 1
+  store i8 %conv.1, ptr %p.1, align 1
+  %and.2 = and i32 %not, 2
+  %sub2.2 = and i32 %sub, 253
+  %or.2 = or disjoint i32 %and.2, %sub2.2
+  %conv.2 = trunc nuw i32 %or.2 to i8
+  %p.2 = getelementptr inbounds nuw i8, ptr %out, i64 2
+  store i8 %conv.2, ptr %p.2, align 1
+  %and.3 = and i32 %not, 3
+  %sub2.3 = and i32 %sub, 252
+  %or.3 = or disjoint i32 %and.3, %sub2.3
+  %conv.3 = trunc nuw i32 %or.3 to i8
+  %p.3 = getelementptr inbounds nuw i8, ptr %out, i64 3
+  store i8 %conv.3, ptr %p.3, align 1
+  %and.4 = and i32 %not, 4
+  %sub2.4 = and i32 %sub, 251
+  %or.4 = or disjoint i32 %and.4, %sub2.4
+  %conv.4 = trunc nuw i32 %or.4 to i8
+  %p.4 = getelementptr inbounds nuw i8, ptr %out, i64 4
+  store i8 %conv.4, ptr %p.4, align 1
+  %and.5 = and i32 %not, 5
+  %sub2.5 = and i32 %sub, 250
+  %or.5 = or disjoint i32 %and.5, %sub2.5
+  %conv.5 = trunc nuw i32 %or.5 to i8
+  %p.5 = getelementptr inbounds nuw i8, ptr %out, i64 5
+  store i8 %conv.5, ptr %p.5, align 1
+  %and.6 = and i32 %not, 6
+  %sub2.6 = and i32 %sub, 249
+  %or.6 = or disjoint i32 %and.6, %sub2.6
+  %conv.6 = trunc nuw i32 %or.6 to i8
+  %p.6 = getelementptr inbounds nuw i8, ptr %out, i64 6
+  store i8 %conv.6, ptr %p.6, align 1
+  %and.7 = and i32 %not, 7
+  %sub2.7 = and i32 %sub, 248
+  %or.7 = or disjoint i32 %and.7, %sub2.7
+  %conv.7 = trunc nuw i32 %or.7 to i8
+  %p.7 = getelementptr inbounds nuw i8, ptr %out, i64 7
+  store i8 %conv.7, ptr %p.7, align 1
+  ret void
+}
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/wide-load-absorbed-lane.ll b/llvm/test/Transforms/SLPVectorizer/X86/wide-load-absorbed-lane.ll
index 76e4547588392..b77ae7ee40cd2 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/wide-load-absorbed-lane.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/wide-load-absorbed-lane.ll
@@ -399,3 +399,39 @@ entry:
   store i32 %m3, ptr getelementptr inbounds nuw (i8, ptr @out, i64 12), align 4
   ret void
 }
+
+; The or of the absorbing all-ones lane must not keep the disjoint flag: the
+; other operand of the lane is not known to be zero.
+define void @or_disjoint_absorbed_first(i32 noundef %x) {
+; CHECK-LABEL: define void @or_disjoint_absorbed_first(
+; CHECK-SAME: i32 noundef [[X:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    store i32 -1, ptr @out, align 16
+; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x i32>, ptr getelementptr inbounds nuw (i8, ptr @in, i64 4), align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i32> poison, i32 [[X]], i64 0
+; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <2 x i32> zeroinitializer
+; CHECK-NEXT:    [[TMP3:%.*]] = add <2 x i32> [[TMP0]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = or disjoint <2 x i32> [[TMP3]], <i32 256, i32 512>
+; CHECK-NEXT:    store <2 x i32> [[TMP4]], ptr getelementptr inbounds nuw (i8, ptr @out, i64 4), align 4
+; CHECK-NEXT:    [[L3:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @in, i64 12), align 4
+; CHECK-NEXT:    [[A3:%.*]] = add i32 [[L3]], [[X]]
+; CHECK-NEXT:    [[M3:%.*]] = or disjoint i32 [[A3]], 1024
+; CHECK-NEXT:    store i32 [[M3]], ptr getelementptr inbounds nuw (i8, ptr @out, i64 12), align 4
+; CHECK-NEXT:    ret void
+;
+entry:
+  store i32 -1, ptr @out, align 16
+  %l1 = load i32, ptr getelementptr inbounds nuw (i8, ptr @in, i64 4), align 4
+  %a1 = add i32 %l1, %x
+  %m1 = or disjoint i32 %a1, 256
+  store i32 %m1, ptr getelementptr inbounds nuw (i8, ptr @out, i64 4), align 4
+  %l2 = load i32, ptr getelementptr inbounds nuw (i8, ptr @in, i64 8), align 4
+  %a2 = add i32 %l2, %x
+  %m2 = or disjoint i32 %a2, 512
+  store i32 %m2, ptr getelementptr inbounds nuw (i8, ptr @out, i64 8), align 4
+  %l3 = load i32, ptr getelementptr inbounds nuw (i8, ptr @in, i64 12), align 4
+  %a3 = add i32 %l3, %x
+  %m3 = or disjoint i32 %a3, 1024
+  store i32 %m3, ptr getelementptr inbounds nuw (i8, ptr @out, i64 12), align 4
+  ret void
+}
diff --git a/llvm/test/Transforms/SLPVectorizer/absorbed-lane-shuffled-operand.ll b/llvm/test/Transforms/SLPVectorizer/absorbed-lane-shuffled-operand.ll
new file mode 100644
index 0000000000000..afd7133d65d14
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/absorbed-lane-shuffled-operand.ll
@@ -0,0 +1,108 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=slp-vectorizer -S | FileCheck %s
+
+declare i32 @get_size(i32 noundef)
+
+; The lane with the absorbing zero of the and uses undef as the other operand.
+; The operand is a shuffle of the vectorized values, which makes the lane
+; poison, so the operand is frozen.
+define i32 @swap_bytes(ptr %params, ptr %out) {
+; CHECK-LABEL: define i32 @swap_bytes(
+; CHECK-SAME: ptr [[PARAMS:%.*]], ptr [[OUT:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[OP:%.*]] = getelementptr inbounds nuw i8, ptr [[PARAMS]], i64 8
+; CHECK-NEXT:    [[TY:%.*]] = load ptr, ptr [[OP]], align 8
+; CHECK-NEXT:    [[TYPE:%.*]] = getelementptr inbounds nuw i8, ptr [[TY]], i64 4
+; CHECK-NEXT:    [[T:%.*]] = load i32, ptr [[TYPE]], align 4
+; CHECK-NEXT:    [[CALL:%.*]] = call i32 @get_size(i32 noundef [[T]])
+; CHECK-NEXT:    [[PRIV:%.*]] = getelementptr inbounds nuw i8, ptr [[OUT]], i64 16
+; CHECK-NEXT:    [[P_1:%.*]] = getelementptr inbounds nuw i8, ptr [[OUT]], i64 17
+; CHECK-NEXT:    [[P_2:%.*]] = getelementptr inbounds nuw i8, ptr [[OUT]], i64 18
+; CHECK-NEXT:    [[P_3:%.*]] = getelementptr inbounds nuw i8, ptr [[OUT]], i64 19
+; CHECK-NEXT:    [[P_4:%.*]] = getelementptr inbounds nuw i8, ptr [[OUT]], i64 20
+; CHECK-NEXT:    [[P_5:%.*]] = getelementptr inbounds nuw i8, ptr [[OUT]], i64 21
+; CHECK-NEXT:    [[P_6:%.*]] = getelementptr inbounds nuw i8, ptr [[OUT]], i64 22
+; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <2 x i32> <i32 poison, i32 0>, i32 [[CALL]], i64 0
+; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i32> <i32 -255, i32 poison>, i32 [[CALL]], i64 1
+; CHECK-NEXT:    [[TMP2:%.*]] = sub <2 x i32> [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[TMP3:%.*]] = shufflevector <2 x i32> [[TMP2]], <2 x i32> poison, <8 x i32> <i32 0, i32 1, i32 0, i32 1, i32 0, i32 1, i32 0, i32 1>
+; CHECK-NEXT:    [[TMP4:%.*]] = and <8 x i32> [[TMP3]], <i32 -1, i32 1, i32 253, i32 3, i32 251, i32 5, i32 249, i32 7>
+; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <8 x i32> <i32 -1, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>, <8 x i32> [[TMP3]], <8 x i32> <i32 0, i32 8, i32 9, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT:    [[TMP6:%.*]] = shufflevector <8 x i32> [[TMP5]], <8 x i32> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 1, i32 2, i32 1, i32 2, i32 1>
+; CHECK-NEXT:    [[TMP8:%.*]] = and <8 x i32> <i32 0, i32 254, i32 2, i32 252, i32 4, i32 250, i32 6, i32 248>, [[TMP6]]
+; CHECK-NEXT:    [[TMP9:%.*]] = or disjoint <8 x i32> [[TMP4]], [[TMP8]]
+; CHECK-NEXT:    [[TMP10:%.*]] = trunc <8 x i32> [[TMP9]] to <8 x i8>
+; CHECK-NEXT:    [[TMP11:%.*]] = extractelement <8 x i8> [[TMP10]], i64 0
+; CHECK-NEXT:    store i8 [[TMP11]], ptr [[PRIV]], align 1
+; CHECK-NEXT:    [[TMP12:%.*]] = extractelement <8 x i8> [[TMP10]], i64 1
+; CHECK-NEXT:    store i8 [[TMP12]], ptr [[P_1]], align 1
+; CHECK-NEXT:    [[TMP13:%.*]] = extractelement <8 x i8> [[TMP10]], i64 2
+; CHECK-NEXT:    store i8 [[TMP13]], ptr [[P_2]], align 1
+; CHECK-NEXT:    [[TMP14:%.*]] = extractelement <8 x i8> [[TMP10]], i64 3
+; CHECK-NEXT:    store i8 [[TMP14]], ptr [[P_3]], align 1
+; CHECK-NEXT:    [[TMP15:%.*]] = extractelement <8 x i8> [[TMP10]], i64 4
+; CHECK-NEXT:    store i8 [[TMP15]], ptr [[P_4]], align 1
+; CHECK-NEXT:    [[TMP16:%.*]] = extractelement <8 x i8> [[TMP10]], i64 5
+; CHECK-NEXT:    store i8 [[TMP16]], ptr [[P_5]], align 1
+; CHECK-NEXT:    [[TMP17:%.*]] = extractelement <8 x i8> [[TMP10]], i64 6
+; CHECK-NEXT:    store i8 [[TMP17]], ptr [[P_6]], align 1
+; CHECK-NEXT:    [[P_7:%.*]] = getelementptr inbounds nuw i8, ptr [[OUT]], i64 23
+; CHECK-NEXT:    [[TMP18:%.*]] = extractelement <8 x i8> [[TMP10]], i64 7
+; CHECK-NEXT:    store i8 [[TMP18]], ptr [[P_7]], align 1
+; CHECK-NEXT:    ret i32 0
+;
+entry:
+  %op = getelementptr inbounds nuw i8, ptr %params, i64 8
+  %ty = load ptr, ptr %op, align 8
+  %type = getelementptr inbounds nuw i8, ptr %ty, i64 4
+  %t = load i32, ptr %type, align 4
+  %call = call i32 @get_size(i32 noundef %t)
+  %sub = add i32 %call, 255
+  %not = sub i32 0, %call
+  %priv = getelementptr inbounds nuw i8, ptr %out, i64 16
+  %conv = trunc i32 %sub to i8
+  store i8 %conv, ptr %priv, align 1
+  %and.1 = and i32 %not, 1
+  %sub2.1 = and i32 %sub, 254
+  %or.1 = or disjoint i32 %and.1, %sub2.1
+  %conv.1 = trunc nuw i32 %or.1 to i8
+  %p.1 = getelementptr inbounds nuw i8, ptr %out, i64 17
+  store i8 %conv.1, ptr %p.1, align 1
+  %and.2 = and i32 %not, 2
+  %sub2.2 = and i32 %sub, 253
+  %or.2 = or disjoint i32 %and.2, %sub2.2
+  %conv.2 = trunc nuw i32 %or.2 to i8
+  %p.2 = getelementptr inbounds nuw i8, ptr %out, i64 18
+  store i8 %conv.2, ptr %p.2, align 1
+  %and.3 = and i32 %not, 3
+  %sub2.3 = and i32 %sub, 252
+  %or.3 = or disjoint i32 %and.3, %sub2.3
+  %conv.3 = trunc nuw i32 %or.3 to i8
+  %p.3 = getelementptr inbounds nuw i8, ptr %out, i64 19
+  store i8 %conv.3, ptr %p.3, align 1
+  %and.4 = and i32 %not, 4
+  %sub2.4 = and i32 %sub, 251
+  %or.4 = or disjoint i32 %and.4, %sub2.4
+  %conv.4 = trunc nuw i32 %or.4 to i8
+  %p.4 = getelementptr inbounds nuw i8, ptr %out, i64 20
+  store i8 %conv.4, ptr %p.4, align 1
+  %and.5 = and i32 %not, 5
+  %sub2.5 = and i32 %sub, 250
+  %or.5 = or disjoint i32 %and.5, %sub2.5
+  %conv.5 = trunc nuw i32 %or.5 to i8
+  %p.5 = getelementptr inbounds nuw i8, ptr %out, i64 21
+  store i8 %conv.5, ptr %p.5, align 1
+  %and.6 = and i32 %not, 6
+  %sub2.6 = and i32 %sub, 249
+  %or.6 = or disjoint i32 %and.6, %sub2.6
+  %conv.6 = trunc nuw i32 %or.6 to i8
+  %p.6 = getelementptr inbounds nuw i8, ptr %out, i64 22
+  store i8 %conv.6, ptr %p.6, align 1
+  %and.7 = and i32 %not, 7
+  %sub2.7 = and i32 %sub, 248
+  %or.7 = or disjoint i32 %and.7, %sub2.7
+  %conv.7 = trunc nuw i32 %or.7 to i8
+  %p.7 = getelementptr inbounds nuw i8, ptr %out, i64 23
+  store i8 %conv.7, ptr %p.7, align 1
+  ret i32 0
+}
diff --git a/llvm/test/Transforms/SLPVectorizer/volatile-loads-reduction.ll b/llvm/test/Transforms/SLPVectorizer/volatile-loads-reduction.ll
new file mode 100644
index 0000000000000..5dd5e4df06ed8
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/volatile-loads-reduction.ll
@@ -0,0 +1,65 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=slp-vectorizer -S | FileCheck %s
+
+ at a = external global i32
+
+; The reduction of the volatile loads must not be vectorized.
+define i32 @volatile_loads_reduction(i32 %a) {
+; CHECK-LABEL: define i32 @volatile_loads_reduction(
+; CHECK-SAME: i32 [[A:%.*]]) {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[A1:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A2:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A3:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A4:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A5:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A6:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A7:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A8:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A9:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A10:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A11:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[A12:%.*]] = load volatile i32, ptr @a, align 4
+; CHECK-NEXT:    [[TMP0:%.*]] = mul i32 [[A6]], 2
+; CHECK-NEXT:    [[TMP1:%.*]] = mul i32 [[A1]], 2
+; CHECK-NEXT:    [[OP_RDX:%.*]] = add i32 [[TMP0]], [[TMP1]]
+; CHECK-NEXT:    [[OP_RDX1:%.*]] = add i32 [[OP_RDX]], [[A]]
+; CHECK-NEXT:    [[OP_RDX2:%.*]] = add i32 [[A12]], [[A11]]
+; CHECK-NEXT:    [[OP_RDX3:%.*]] = add i32 [[A10]], [[A9]]
+; CHECK-NEXT:    [[OP_RDX4:%.*]] = add i32 [[A8]], [[A5]]
+; CHECK-NEXT:    [[OP_RDX5:%.*]] = add i32 [[A4]], [[A3]]
+; CHECK-NEXT:    [[OP_RDX6:%.*]] = add i32 [[OP_RDX1]], [[OP_RDX2]]
+; CHECK-NEXT:    [[OP_RDX7:%.*]] = add i32 [[OP_RDX3]], [[OP_RDX4]]
+; CHECK-NEXT:    [[OP_RDX8:%.*]] = add i32 [[OP_RDX5]], [[A2]]
+; CHECK-NEXT:    [[OP_RDX9:%.*]] = add i32 [[OP_RDX6]], [[OP_RDX7]]
+; CHECK-NEXT:    [[OP_RDX10:%.*]] = add i32 [[OP_RDX9]], [[OP_RDX8]]
+; CHECK-NEXT:    ret i32 [[OP_RDX10]]
+;
+entry:
+  %a1 = load volatile i32, ptr @a
+  %x1 = add i32 %a1,  %a1
+  %a2 = load volatile i32, ptr @a
+  %x2 = add i32 %x1, %a2
+  %a3 = load volatile i32, ptr @a
+  %x3 = add i32 %x2, %a3
+  %a4 = load volatile i32, ptr @a
+  %x4 = add i32 %x3, %a4
+  %a5 = load volatile i32, ptr @a
+  %x5 = add i32 %x4, %a5
+  %a6 = load volatile i32, ptr @a
+  %x6 = add i32 %x5, %a6
+  %a7 = load volatile i32, ptr @a
+  %x7 = add i32 %x6, %a6
+  %a8 = load volatile i32, ptr @a
+  %x8 = add i32 %x7, %a8
+  %a9 = load volatile i32, ptr @a
+  %x9 = add i32 %x8, %a9
+  %a10 = load volatile i32, ptr @a
+  %x10 = add i32 %x9, %a10
+  %a11 = load volatile i32, ptr @a
+  %x11 = add i32 %x10, %a11
+  %a12 = load volatile i32, ptr @a
+  %x12 = add i32 %x11, %a12
+  %add = add i32 %x12, %a
+  ret i32 %add
+}



More information about the llvm-commits mailing list