[llvm] [SLP] Add pre-commit tests for zero-tested OR/UMax reductions (NFC) (PR #205738)

via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 25 07:30:44 PDT 2026


https://github.com/ParkHanbum updated https://github.com/llvm/llvm-project/pull/205738

>From 1a99fbfefbf7e1561426ed912bdf58609c983f2d Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Mon, 22 Jun 2026 15:12:43 +0900
Subject: [PATCH 1/2] [SLP] Add pre-commit tests for zero-tested OR/UMax
 reductions (NFC)

Add pre-commit tests for scalar OR/UMax reductions whose result is
only used by an eq/ne-zero comparison.

These tests document the current SLP behavior before teaching the
vectorizer to form a lane-wise compare followed by a boolean reduction.
---
 .../WebAssembly/or-reduction-zero-test.ll     | 235 ++++++++++++++++++
 1 file changed, 235 insertions(+)
 create mode 100644 llvm/test/Transforms/SLPVectorizer/WebAssembly/or-reduction-zero-test.ll

diff --git a/llvm/test/Transforms/SLPVectorizer/WebAssembly/or-reduction-zero-test.ll b/llvm/test/Transforms/SLPVectorizer/WebAssembly/or-reduction-zero-test.ll
new file mode 100644
index 0000000000000..b7d0c2694af7f
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/WebAssembly/or-reduction-zero-test.ll
@@ -0,0 +1,235 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -mtriple=wasm32 -mattr=+simd128 -passes=slp-vectorizer -S < %s | FileCheck %s
+
+define i1 @or_reduction_nonzero(ptr %p) {
+; CHECK-LABEL: define i1 @or_reduction_nonzero(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[P]], align 1
+; CHECK-NEXT:    [[TMP18:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 0, i32 8>
+; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 1, i32 9>
+; CHECK-NEXT:    [[TMP3:%.*]] = or <2 x i8> [[TMP18]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 2, i32 10>
+; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 3, i32 11>
+; CHECK-NEXT:    [[TMP6:%.*]] = or <2 x i8> [[TMP4]], [[TMP5]]
+; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 4, i32 12>
+; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 5, i32 13>
+; CHECK-NEXT:    [[TMP9:%.*]] = or <2 x i8> [[TMP7]], [[TMP8]]
+; CHECK-NEXT:    [[TMP10:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 6, i32 14>
+; CHECK-NEXT:    [[TMP11:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 7, i32 15>
+; CHECK-NEXT:    [[TMP12:%.*]] = or <2 x i8> [[TMP10]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = or <2 x i8> [[TMP3]], [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = or <2 x i8> [[TMP9]], [[TMP12]]
+; CHECK-NEXT:    [[TMP15:%.*]] = or <2 x i8> [[TMP13]], [[TMP14]]
+; CHECK-NEXT:    [[TMP16:%.*]] = extractelement <2 x i8> [[TMP15]], i32 0
+; CHECK-NEXT:    [[TMP17:%.*]] = extractelement <2 x i8> [[TMP15]], i32 1
+; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[TMP16]], [[TMP17]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP1]], 0
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+entry:
+  %v0 = load i8, ptr %p, align 1
+  %p1 = getelementptr inbounds i8, ptr %p, i32 1
+  %v1 = load i8, ptr %p1, align 1
+  %p2 = getelementptr inbounds i8, ptr %p, i32 2
+  %v2 = load i8, ptr %p2, align 1
+  %p3 = getelementptr inbounds i8, ptr %p, i32 3
+  %v3 = load i8, ptr %p3, align 1
+  %p4 = getelementptr inbounds i8, ptr %p, i32 4
+  %v4 = load i8, ptr %p4, align 1
+  %p5 = getelementptr inbounds i8, ptr %p, i32 5
+  %v5 = load i8, ptr %p5, align 1
+  %p6 = getelementptr inbounds i8, ptr %p, i32 6
+  %v6 = load i8, ptr %p6, align 1
+  %p7 = getelementptr inbounds i8, ptr %p, i32 7
+  %v7 = load i8, ptr %p7, align 1
+  %p8 = getelementptr inbounds i8, ptr %p, i32 8
+  %v8 = load i8, ptr %p8, align 1
+  %p9 = getelementptr inbounds i8, ptr %p, i32 9
+  %v9 = load i8, ptr %p9, align 1
+  %p10 = getelementptr inbounds i8, ptr %p, i32 10
+  %v10 = load i8, ptr %p10, align 1
+  %p11 = getelementptr inbounds i8, ptr %p, i32 11
+  %v11 = load i8, ptr %p11, align 1
+  %p12 = getelementptr inbounds i8, ptr %p, i32 12
+  %v12 = load i8, ptr %p12, align 1
+  %p13 = getelementptr inbounds i8, ptr %p, i32 13
+  %v13 = load i8, ptr %p13, align 1
+  %p14 = getelementptr inbounds i8, ptr %p, i32 14
+  %v14 = load i8, ptr %p14, align 1
+  %p15 = getelementptr inbounds i8, ptr %p, i32 15
+  %v15 = load i8, ptr %p15, align 1
+  %o01 = or i8 %v0, %v1
+  %o23 = or i8 %v2, %v3
+  %o45 = or i8 %v4, %v5
+  %o67 = or i8 %v6, %v7
+  %o89 = or i8 %v8, %v9
+  %o1011 = or i8 %v10, %v11
+  %o1213 = or i8 %v12, %v13
+  %o1415 = or i8 %v14, %v15
+  %o0123 = or i8 %o01, %o23
+  %o4567 = or i8 %o45, %o67
+  %o891011 = or i8 %o89, %o1011
+  %o12131415 = or i8 %o1213, %o1415
+  %o07 = or i8 %o0123, %o4567
+  %o815 = or i8 %o891011, %o12131415
+  %o = or i8 %o07, %o815
+  %cmp = icmp ne i8 %o, 0
+  ret i1 %cmp
+}
+
+define i1 @or_reduction_zero(ptr %p) {
+; CHECK-LABEL: define i1 @or_reduction_zero(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[P]], align 1
+; CHECK-NEXT:    [[TMP18:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 0, i32 8>
+; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 1, i32 9>
+; CHECK-NEXT:    [[TMP3:%.*]] = or <2 x i8> [[TMP18]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 2, i32 10>
+; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 3, i32 11>
+; CHECK-NEXT:    [[TMP6:%.*]] = or <2 x i8> [[TMP4]], [[TMP5]]
+; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 4, i32 12>
+; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 5, i32 13>
+; CHECK-NEXT:    [[TMP9:%.*]] = or <2 x i8> [[TMP7]], [[TMP8]]
+; CHECK-NEXT:    [[TMP10:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 6, i32 14>
+; CHECK-NEXT:    [[TMP11:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 7, i32 15>
+; CHECK-NEXT:    [[TMP12:%.*]] = or <2 x i8> [[TMP10]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = or <2 x i8> [[TMP3]], [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = or <2 x i8> [[TMP9]], [[TMP12]]
+; CHECK-NEXT:    [[TMP15:%.*]] = or <2 x i8> [[TMP13]], [[TMP14]]
+; CHECK-NEXT:    [[TMP16:%.*]] = extractelement <2 x i8> [[TMP15]], i32 0
+; CHECK-NEXT:    [[TMP17:%.*]] = extractelement <2 x i8> [[TMP15]], i32 1
+; CHECK-NEXT:    [[TMP1:%.*]] = or i8 [[TMP16]], [[TMP17]]
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+entry:
+  %v0 = load i8, ptr %p, align 1
+  %p1 = getelementptr inbounds i8, ptr %p, i32 1
+  %v1 = load i8, ptr %p1, align 1
+  %p2 = getelementptr inbounds i8, ptr %p, i32 2
+  %v2 = load i8, ptr %p2, align 1
+  %p3 = getelementptr inbounds i8, ptr %p, i32 3
+  %v3 = load i8, ptr %p3, align 1
+  %p4 = getelementptr inbounds i8, ptr %p, i32 4
+  %v4 = load i8, ptr %p4, align 1
+  %p5 = getelementptr inbounds i8, ptr %p, i32 5
+  %v5 = load i8, ptr %p5, align 1
+  %p6 = getelementptr inbounds i8, ptr %p, i32 6
+  %v6 = load i8, ptr %p6, align 1
+  %p7 = getelementptr inbounds i8, ptr %p, i32 7
+  %v7 = load i8, ptr %p7, align 1
+  %p8 = getelementptr inbounds i8, ptr %p, i32 8
+  %v8 = load i8, ptr %p8, align 1
+  %p9 = getelementptr inbounds i8, ptr %p, i32 9
+  %v9 = load i8, ptr %p9, align 1
+  %p10 = getelementptr inbounds i8, ptr %p, i32 10
+  %v10 = load i8, ptr %p10, align 1
+  %p11 = getelementptr inbounds i8, ptr %p, i32 11
+  %v11 = load i8, ptr %p11, align 1
+  %p12 = getelementptr inbounds i8, ptr %p, i32 12
+  %v12 = load i8, ptr %p12, align 1
+  %p13 = getelementptr inbounds i8, ptr %p, i32 13
+  %v13 = load i8, ptr %p13, align 1
+  %p14 = getelementptr inbounds i8, ptr %p, i32 14
+  %v14 = load i8, ptr %p14, align 1
+  %p15 = getelementptr inbounds i8, ptr %p, i32 15
+  %v15 = load i8, ptr %p15, align 1
+  %o01 = or i8 %v0, %v1
+  %o23 = or i8 %v2, %v3
+  %o45 = or i8 %v4, %v5
+  %o67 = or i8 %v6, %v7
+  %o89 = or i8 %v8, %v9
+  %o1011 = or i8 %v10, %v11
+  %o1213 = or i8 %v12, %v13
+  %o1415 = or i8 %v14, %v15
+  %o0123 = or i8 %o01, %o23
+  %o4567 = or i8 %o45, %o67
+  %o891011 = or i8 %o89, %o1011
+  %o12131415 = or i8 %o1213, %o1415
+  %o07 = or i8 %o0123, %o4567
+  %o815 = or i8 %o891011, %o12131415
+  %o = or i8 %o07, %o815
+  %cmp = icmp eq i8 %o, 0
+  ret i1 %cmp
+}
+
+define i1 @or_reduction_nonzero_multiuse(ptr %p, ptr %out) {
+; CHECK-LABEL: define i1 @or_reduction_nonzero_multiuse(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[OUT:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:  [[ENTRY:.*:]]
+; CHECK-NEXT:    [[TMP0:%.*]] = load <16 x i8>, ptr [[P]], align 1
+; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 0, i32 8>
+; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 1, i32 9>
+; CHECK-NEXT:    [[TMP3:%.*]] = or <2 x i8> [[TMP1]], [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 2, i32 10>
+; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 3, i32 11>
+; CHECK-NEXT:    [[TMP6:%.*]] = or <2 x i8> [[TMP4]], [[TMP5]]
+; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 4, i32 12>
+; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 5, i32 13>
+; CHECK-NEXT:    [[TMP9:%.*]] = or <2 x i8> [[TMP7]], [[TMP8]]
+; CHECK-NEXT:    [[TMP10:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 6, i32 14>
+; CHECK-NEXT:    [[TMP11:%.*]] = shufflevector <16 x i8> [[TMP0]], <16 x i8> poison, <2 x i32> <i32 7, i32 15>
+; CHECK-NEXT:    [[TMP12:%.*]] = or <2 x i8> [[TMP10]], [[TMP11]]
+; CHECK-NEXT:    [[TMP13:%.*]] = or <2 x i8> [[TMP3]], [[TMP6]]
+; CHECK-NEXT:    [[TMP14:%.*]] = or <2 x i8> [[TMP9]], [[TMP12]]
+; CHECK-NEXT:    [[TMP15:%.*]] = or <2 x i8> [[TMP13]], [[TMP14]]
+; CHECK-NEXT:    [[TMP16:%.*]] = extractelement <2 x i8> [[TMP15]], i32 0
+; CHECK-NEXT:    [[TMP17:%.*]] = extractelement <2 x i8> [[TMP15]], i32 1
+; CHECK-NEXT:    [[O:%.*]] = or i8 [[TMP16]], [[TMP17]]
+; CHECK-NEXT:    store i8 [[O]], ptr [[OUT]], align 1
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[O]], 0
+; CHECK-NEXT:    ret i1 [[CMP]]
+;
+entry:
+  %v0 = load i8, ptr %p, align 1
+  %p1 = getelementptr inbounds i8, ptr %p, i32 1
+  %v1 = load i8, ptr %p1, align 1
+  %p2 = getelementptr inbounds i8, ptr %p, i32 2
+  %v2 = load i8, ptr %p2, align 1
+  %p3 = getelementptr inbounds i8, ptr %p, i32 3
+  %v3 = load i8, ptr %p3, align 1
+  %p4 = getelementptr inbounds i8, ptr %p, i32 4
+  %v4 = load i8, ptr %p4, align 1
+  %p5 = getelementptr inbounds i8, ptr %p, i32 5
+  %v5 = load i8, ptr %p5, align 1
+  %p6 = getelementptr inbounds i8, ptr %p, i32 6
+  %v6 = load i8, ptr %p6, align 1
+  %p7 = getelementptr inbounds i8, ptr %p, i32 7
+  %v7 = load i8, ptr %p7, align 1
+  %p8 = getelementptr inbounds i8, ptr %p, i32 8
+  %v8 = load i8, ptr %p8, align 1
+  %p9 = getelementptr inbounds i8, ptr %p, i32 9
+  %v9 = load i8, ptr %p9, align 1
+  %p10 = getelementptr inbounds i8, ptr %p, i32 10
+  %v10 = load i8, ptr %p10, align 1
+  %p11 = getelementptr inbounds i8, ptr %p, i32 11
+  %v11 = load i8, ptr %p11, align 1
+  %p12 = getelementptr inbounds i8, ptr %p, i32 12
+  %v12 = load i8, ptr %p12, align 1
+  %p13 = getelementptr inbounds i8, ptr %p, i32 13
+  %v13 = load i8, ptr %p13, align 1
+  %p14 = getelementptr inbounds i8, ptr %p, i32 14
+  %v14 = load i8, ptr %p14, align 1
+  %p15 = getelementptr inbounds i8, ptr %p, i32 15
+  %v15 = load i8, ptr %p15, align 1
+  %o01 = or i8 %v0, %v1
+  %o23 = or i8 %v2, %v3
+  %o45 = or i8 %v4, %v5
+  %o67 = or i8 %v6, %v7
+  %o89 = or i8 %v8, %v9
+  %o1011 = or i8 %v10, %v11
+  %o1213 = or i8 %v12, %v13
+  %o1415 = or i8 %v14, %v15
+  %o0123 = or i8 %o01, %o23
+  %o4567 = or i8 %o45, %o67
+  %o891011 = or i8 %o89, %o1011
+  %o12131415 = or i8 %o1213, %o1415
+  %o07 = or i8 %o0123, %o4567
+  %o815 = or i8 %o891011, %o12131415
+  %o = or i8 %o07, %o815
+  store i8 %o, ptr %out, align 1
+  %cmp = icmp ne i8 %o, 0
+  ret i1 %cmp
+}

>From 57aa95dede6a3316177baf1119c2622fa80feb46 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Thu, 25 Jun 2026 19:10:37 +0900
Subject: [PATCH 2/2] append testcases for ctpop

---
 .../X86/reduction-zero-test-ctpop.ll          | 166 ++++++++++++++++++
 1 file changed, 166 insertions(+)
 create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/reduction-zero-test-ctpop.ll

diff --git a/llvm/test/Transforms/SLPVectorizer/X86/reduction-zero-test-ctpop.ll b/llvm/test/Transforms/SLPVectorizer/X86/reduction-zero-test-ctpop.ll
new file mode 100644
index 0000000000000..67fd3f4acacaa
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/reduction-zero-test-ctpop.ll
@@ -0,0 +1,166 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux -mcpu=skylake-avx512 < %s | FileCheck %s
+
+define i32 @or_nonzero(ptr %p) {
+; CHECK-LABEL: define i32 @or_nonzero(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT:    [[INPUT:%.*]] = load <8 x i8>, ptr [[P]], align 1
+; CHECK-NEXT:    [[TMP3:%.*]] = call i8 @llvm.vector.reduce.or.v8i8(<8 x i8> [[INPUT]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP3]], 0
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i1 [[CMP]] to i32
+; CHECK-NEXT:    ret i32 [[RESULT]]
+;
+  %input = load <8 x i8>, ptr %p, align 1
+  %a0 = extractelement <8 x i8> %input, i64 0
+  %a1 = extractelement <8 x i8> %input, i64 1
+  %a2 = extractelement <8 x i8> %input, i64 2
+  %a3 = extractelement <8 x i8> %input, i64 3
+  %a4 = extractelement <8 x i8> %input, i64 4
+  %a5 = extractelement <8 x i8> %input, i64 5
+  %a6 = extractelement <8 x i8> %input, i64 6
+  %a7 = extractelement <8 x i8> %input, i64 7
+  %or1 = or i8 %a0, %a1
+  %or2 = or i8 %or1, %a2
+  %or3 = or i8 %or2, %a3
+  %or4 = or i8 %or3, %a4
+  %or5 = or i8 %or4, %a5
+  %or6 = or i8 %or5, %a6
+  %or7 = or i8 %or6, %a7
+  %cmp = icmp ne i8 %or7, 0
+  %result = zext i1 %cmp to i32
+  ret i32 %result
+}
+
+define i32 @or_nonzero_commuted(ptr %p) {
+; CHECK-LABEL: define i32 @or_nonzero_commuted(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[INPUT:%.*]] = load <8 x i8>, ptr [[P]], align 1
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.vector.reduce.or.v8i8(<8 x i8> [[INPUT]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 0, [[TMP1]]
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i1 [[CMP]] to i32
+; CHECK-NEXT:    ret i32 [[RESULT]]
+;
+  %input = load <8 x i8>, ptr %p, align 1
+  %a0 = extractelement <8 x i8> %input, i64 0
+  %a1 = extractelement <8 x i8> %input, i64 1
+  %a2 = extractelement <8 x i8> %input, i64 2
+  %a3 = extractelement <8 x i8> %input, i64 3
+  %a4 = extractelement <8 x i8> %input, i64 4
+  %a5 = extractelement <8 x i8> %input, i64 5
+  %a6 = extractelement <8 x i8> %input, i64 6
+  %a7 = extractelement <8 x i8> %input, i64 7
+  %or1 = or i8 %a0, %a1
+  %or2 = or i8 %or1, %a2
+  %or3 = or i8 %or2, %a3
+  %or4 = or i8 %or3, %a4
+  %or5 = or i8 %or4, %a5
+  %or6 = or i8 %or5, %a6
+  %or7 = or i8 %or6, %a7
+  %cmp = icmp ne i8 0, %or7
+  %result = zext i1 %cmp to i32
+  ret i32 %result
+}
+
+define i32 @or_zero(ptr %p) {
+; CHECK-LABEL: define i32 @or_zero(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[INPUT:%.*]] = load <8 x i8>, ptr [[P]], align 1
+; CHECK-NEXT:    [[TMP3:%.*]] = call i8 @llvm.vector.reduce.or.v8i8(<8 x i8> [[INPUT]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP3]], 0
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i1 [[CMP]] to i32
+; CHECK-NEXT:    ret i32 [[RESULT]]
+;
+  %input = load <8 x i8>, ptr %p, align 1
+  %a0 = extractelement <8 x i8> %input, i64 0
+  %a1 = extractelement <8 x i8> %input, i64 1
+  %a2 = extractelement <8 x i8> %input, i64 2
+  %a3 = extractelement <8 x i8> %input, i64 3
+  %a4 = extractelement <8 x i8> %input, i64 4
+  %a5 = extractelement <8 x i8> %input, i64 5
+  %a6 = extractelement <8 x i8> %input, i64 6
+  %a7 = extractelement <8 x i8> %input, i64 7
+  %or1 = or i8 %a0, %a1
+  %or2 = or i8 %or1, %a2
+  %or3 = or i8 %or2, %a3
+  %or4 = or i8 %or3, %a4
+  %or5 = or i8 %or4, %a5
+  %or6 = or i8 %or5, %a6
+  %or7 = or i8 %or6, %a7
+  %cmp = icmp eq i8 %or7, 0
+  %result = zext i1 %cmp to i32
+  ret i32 %result
+}
+
+define i32 @umax_nonzero(ptr %p) {
+; CHECK-LABEL: define i32 @umax_nonzero(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[INPUT:%.*]] = load <8 x i8>, ptr [[P]], align 1
+; CHECK-NEXT:    [[TMP3:%.*]] = call i8 @llvm.vector.reduce.umax.v8i8(<8 x i8> [[INPUT]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i8 [[TMP3]], 0
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i1 [[CMP]] to i32
+; CHECK-NEXT:    ret i32 [[RESULT]]
+;
+  %input = load <8 x i8>, ptr %p, align 1
+  %a0 = extractelement <8 x i8> %input, i64 0
+  %a1 = extractelement <8 x i8> %input, i64 1
+  %a2 = extractelement <8 x i8> %input, i64 2
+  %a3 = extractelement <8 x i8> %input, i64 3
+  %a4 = extractelement <8 x i8> %input, i64 4
+  %a5 = extractelement <8 x i8> %input, i64 5
+  %a6 = extractelement <8 x i8> %input, i64 6
+  %a7 = extractelement <8 x i8> %input, i64 7
+  %c1 = icmp ugt i8 %a0, %a1
+  %m1 = select i1 %c1, i8 %a0, i8 %a1
+  %c2 = icmp ugt i8 %m1, %a2
+  %m2 = select i1 %c2, i8 %m1, i8 %a2
+  %c3 = icmp ugt i8 %m2, %a3
+  %m3 = select i1 %c3, i8 %m2, i8 %a3
+  %c4 = icmp ugt i8 %m3, %a4
+  %m4 = select i1 %c4, i8 %m3, i8 %a4
+  %c5 = icmp ugt i8 %m4, %a5
+  %m5 = select i1 %c5, i8 %m4, i8 %a5
+  %c6 = icmp ugt i8 %m5, %a6
+  %m6 = select i1 %c6, i8 %m5, i8 %a6
+  %c7 = icmp ugt i8 %m6, %a7
+  %m7 = select i1 %c7, i8 %m6, i8 %a7
+  %cmp = icmp ne i8 %m7, 0
+  %result = zext i1 %cmp to i32
+  ret i32 %result
+}
+
+define i32 @umax_zero_commuted(ptr %p) {
+; CHECK-LABEL: define i32 @umax_zero_commuted(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT:    [[INPUT:%.*]] = load <8 x i8>, ptr [[P]], align 1
+; CHECK-NEXT:    [[TMP1:%.*]] = call i8 @llvm.vector.reduce.umax.v8i8(<8 x i8> [[INPUT]])
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 0, [[TMP1]]
+; CHECK-NEXT:    [[RESULT:%.*]] = zext i1 [[CMP]] to i32
+; CHECK-NEXT:    ret i32 [[RESULT]]
+;
+  %input = load <8 x i8>, ptr %p, align 1
+  %a0 = extractelement <8 x i8> %input, i64 0
+  %a1 = extractelement <8 x i8> %input, i64 1
+  %a2 = extractelement <8 x i8> %input, i64 2
+  %a3 = extractelement <8 x i8> %input, i64 3
+  %a4 = extractelement <8 x i8> %input, i64 4
+  %a5 = extractelement <8 x i8> %input, i64 5
+  %a6 = extractelement <8 x i8> %input, i64 6
+  %a7 = extractelement <8 x i8> %input, i64 7
+  %c1 = icmp ugt i8 %a0, %a1
+  %m1 = select i1 %c1, i8 %a0, i8 %a1
+  %c2 = icmp ugt i8 %m1, %a2
+  %m2 = select i1 %c2, i8 %m1, i8 %a2
+  %c3 = icmp ugt i8 %m2, %a3
+  %m3 = select i1 %c3, i8 %m2, i8 %a3
+  %c4 = icmp ugt i8 %m3, %a4
+  %m4 = select i1 %c4, i8 %m3, i8 %a4
+  %c5 = icmp ugt i8 %m4, %a5
+  %m5 = select i1 %c5, i8 %m4, i8 %a5
+  %c6 = icmp ugt i8 %m5, %a6
+  %m6 = select i1 %c6, i8 %m5, i8 %a6
+  %c7 = icmp ugt i8 %m6, %a7
+  %m7 = select i1 %c7, i8 %m6, i8 %a7
+  %cmp = icmp eq i8 0, %m7
+  %result = zext i1 %cmp to i32
+  ret i32 %result
+}



More information about the llvm-commits mailing list