[llvm] [VectorCombine] Fold zero tests of or/umax reductions (PR #205622)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 25 07:47:15 PDT 2026
https://github.com/ParkHanbum updated https://github.com/llvm/llvm-project/pull/205622
>From f41fd62b663950d490955b09a297274f4e632712 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Thu, 25 Jun 2026 01:23:22 +0900
Subject: [PATCH 1/3] add testcases for upcoming patch
---
.../X86/fold-reduction-zero-test.ll | 67 +++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 llvm/test/Transforms/VectorCombine/X86/fold-reduction-zero-test.ll
diff --git a/llvm/test/Transforms/VectorCombine/X86/fold-reduction-zero-test.ll b/llvm/test/Transforms/VectorCombine/X86/fold-reduction-zero-test.ll
new file mode 100644
index 0000000000000..4f7e1c78f19ab
--- /dev/null
+++ b/llvm/test/Transforms/VectorCombine/X86/fold-reduction-zero-test.ll
@@ -0,0 +1,67 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt -passes=vector-combine -S %s | FileCheck %s
+
+declare i8 @llvm.vector.reduce.or.v16i8(<16 x i8>)
+declare i8 @llvm.vector.reduce.umax.v16i8(<16 x i8>)
+
+define i1 @or_nonzero(<16 x i8> %x) {
+; CHECK-LABEL: define i1 @or_nonzero(
+; CHECK-SAME: <16 x i8> [[X:%.*]]) {
+; CHECK-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %reduction = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> %x)
+ %cmp = icmp ne i8 %reduction, 0
+ ret i1 %cmp
+}
+
+define i1 @or_zero(<16 x i8> %x) {
+; CHECK-LABEL: define i1 @or_zero(
+; CHECK-SAME: <16 x i8> [[X:%.*]]) {
+; CHECK-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[REDUCTION]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %reduction = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> %x)
+ %cmp = icmp eq i8 %reduction, 0
+ ret i1 %cmp
+}
+
+define i1 @umax_nonzero(<16 x i8> %x) {
+; CHECK-LABEL: define i1 @umax_nonzero(
+; CHECK-SAME: <16 x i8> [[X:%.*]]) {
+; CHECK-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> [[X]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %reduction = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> %x)
+ %cmp = icmp ne i8 %reduction, 0
+ ret i1 %cmp
+}
+
+define i1 @umax_zero_commuted(<16 x i8> %x) {
+; CHECK-LABEL: define i1 @umax_zero_commuted(
+; CHECK-SAME: <16 x i8> [[X:%.*]]) {
+; CHECK-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> [[X]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 0, [[REDUCTION]]
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %reduction = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> %x)
+ %cmp = icmp eq i8 0, %reduction
+ ret i1 %cmp
+}
+
+define i1 @or_nonzero_multiuse(<16 x i8> %x, ptr %out) {
+; CHECK-LABEL: define i1 @or_nonzero_multiuse(
+; CHECK-SAME: <16 x i8> [[X:%.*]], ptr [[OUT:%.*]]) {
+; CHECK-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
+; CHECK-NEXT: store i8 [[REDUCTION]], ptr [[OUT]], align 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %reduction = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> %x)
+ store i8 %reduction, ptr %out, align 1
+ %cmp = icmp ne i8 %reduction, 0
+ ret i1 %cmp
+}
>From 359323538f24231631fb0265f6fdb8cacf87e855 Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Thu, 25 Jun 2026 02:07:39 +0900
Subject: [PATCH 2/3] [VectorCombine] Fold zero tests of or/umax reductions
Recognize equality and inequality tests against zero on vector.reduce.or
and vector.reduce.umax. When profitable, replace the scalar reduction and
compare with a lane-wise comparison followed by an i1 reduce.or or
reduce.and.
Run the existing zero-preserving reduction fold first to retain its more
specific canonicalization opportunities.
Fixed #205028
Proof: https://alive2.llvm.org/ce/z/pyoTwP
---
.../Transforms/Vectorize/VectorCombine.cpp | 79 +++++++++
.../AArch64/fold-equivalent-reduction-cmp.ll | 35 ++--
.../AArch64/fold-reduce-add-cmp-zero.ll | 40 ++---
.../AArch64/fold-signbit-reduction-cmp.ll | 35 ++--
.../AArch64/icmp-vector-reduce.ll | 80 +++++-----
.../RISCV/fold-equivalent-reduction-cmp.ll | 20 +--
.../RISCV/fold-reduce-add-cmp-zero.ll | 12 +-
.../RISCV/fold-signbit-reduction-cmp.ll | 23 ++-
.../VectorCombine/RISCV/icmp-vector-reduce.ll | 92 +++++------
.../X86/fold-equivalent-reduction-cmp.ll | 16 +-
.../X86/fold-reduction-zero-test.ll | 150 ++++++++++++++----
.../X86/fold-signbit-reduction-cmp.ll | 16 +-
.../VectorCombine/X86/icmp-vector-reduce.ll | 60 +++----
13 files changed, 415 insertions(+), 243 deletions(-)
diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 6dab072364424..8a52cbba8ad84 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -150,6 +150,7 @@ class VectorCombine {
bool foldShuffleChainsToReduce(Instruction &I);
bool foldCastFromReductions(Instruction &I);
bool foldSignBitReductionCmp(Instruction &I);
+ bool foldReductionZeroTest(Instruction &I);
bool foldICmpEqZeroVectorReduce(Instruction &I);
bool foldEquivalentReductionCmp(Instruction &I);
bool foldReduceAddCmpZero(Instruction &I);
@@ -4592,6 +4593,82 @@ bool VectorCombine::foldSignBitReductionCmp(Instruction &I) {
return true;
}
+/// Fold a zero test of reduce.or or reduce.umax into a boolean reduction.
+///
+/// Vectorization may produce IR that compares the result of a scalar reduction
+/// with zero. Depending on the target, lowering a reduction and a scalar
+/// comparison separately can cost more than reducing lane-wise comparison
+/// results. This fold creates the latter form only when it is not costlier.
+///
+/// Before:
+/// %r = call iT @llvm.vector.reduce.or.vNiT(<N x iT> %x)
+/// %cmp = icmp ne iT %r, 0
+///
+/// After:
+/// %lane.cmp = icmp ne <N x iT> %x, zeroinitializer
+/// %cmp = call i1 @llvm.vector.reduce.or.vNi1(<N x i1> %lane.cmp)
+///
+/// `reduce.or` and `reduce.umax` are non-zero when at least one lane is
+/// non-zero. Therefore, `icmp ne` uses the existential `reduce.or` test.
+/// Conversely, `icmp eq` must check that every lane is zero, so it uses the
+/// universal `reduce.and` test.
+///
+/// Before:
+/// %r = call iT @llvm.vector.reduce.umax.vNiT(<N x iT> %x)
+/// %cmp = icmp eq iT %r, 0
+///
+/// After:
+/// %lane.cmp = icmp eq <N x iT> %x, zeroinitializer
+/// %cmp = call i1 @llvm.vector.reduce.and.vNi1(<N x i1> %lane.cmp)
+bool VectorCombine::foldReductionZeroTest(Instruction &I) {
+ CmpPredicate Pred;
+ Value *Op;
+
+ if (!match(&I, m_c_ICmp(Pred, m_Value(Op), m_Zero())) ||
+ !ICmpInst::isEquality(Pred))
+ return false;
+
+ auto *II = dyn_cast<IntrinsicInst>(Op);
+ if (!II || !II->hasOneUse())
+ return false;
+
+ auto ReduceID = II->getIntrinsicID();
+ if (ReduceID != Intrinsic::vector_reduce_or &&
+ ReduceID != Intrinsic::vector_reduce_umax)
+ return false;
+
+ Value *Vec = II->getArgOperand(0);
+ auto *VecTy = dyn_cast<FixedVectorType>(Vec->getType());
+ if (!VecTy || !VecTy->getElementType()->isIntegerTy())
+ return false;
+
+ // Map the scalar zero test to an any-lane or all-lane boolean reduction.
+ Intrinsic::ID NewIID = (Pred == ICmpInst::ICMP_NE)
+ ? Intrinsic::vector_reduce_or
+ : Intrinsic::vector_reduce_and;
+
+ // This is not an unconditional canonicalization: compare the cost of the
+ // original scalar reduction and compare with the vector compare and i1
+ // reduction replacement for both reduce.or and reduce.umax.
+ InstructionCost OldCost = TTI.getInstructionCost(II, CostKind) +
+ TTI.getInstructionCost(&I, CostKind);
+
+ auto *CmpTy = cast<VectorType>(CmpInst::makeCmpResultType(VecTy));
+ InstructionCost NewCost =
+ TTI.getCmpSelInstrCost(Instruction::ICmp, VecTy, CmpTy, Pred, CostKind);
+ NewCost += TTI.getArithmeticReductionCost(
+ getArithmeticReductionInstruction(NewIID), CmpTy, std::nullopt, CostKind);
+
+ if (!OldCost.isValid() || !NewCost.isValid() || NewCost > OldCost)
+ return false;
+
+ Builder.SetInsertPoint(&I);
+ Value *NewCmp = Builder.CreateICmp(Pred, Vec, Constant::getNullValue(VecTy));
+ Value *NewReduce = Builder.CreateIntrinsic(NewIID, {CmpTy}, {NewCmp});
+ replaceValue(I, *NewReduce);
+ return true;
+}
+
/// vector.reduce.OP f(X_i) == 0 -> vector.reduce.OP X_i == 0
///
/// We can prove it for cases when:
@@ -6267,6 +6344,8 @@ bool VectorCombine::run() {
return true;
if (foldICmpEqZeroVectorReduce(I))
return true;
+ if (foldReductionZeroTest(I))
+ return true;
if (foldEquivalentReductionCmp(I))
return true;
if (foldReduceAddCmpZero(I))
diff --git a/llvm/test/Transforms/VectorCombine/AArch64/fold-equivalent-reduction-cmp.ll b/llvm/test/Transforms/VectorCombine/AArch64/fold-equivalent-reduction-cmp.ll
index 26d7647e5afde..0a5a065f128ef 100644
--- a/llvm/test/Transforms/VectorCombine/AArch64/fold-equivalent-reduction-cmp.ll
+++ b/llvm/test/Transforms/VectorCombine/AArch64/fold-equivalent-reduction-cmp.ll
@@ -4,8 +4,8 @@
define i1 @or_eq_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_eq_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %x)
@@ -16,8 +16,8 @@ define i1 @or_eq_0(<4 x i32> %x) {
define i1 @or_ne_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_ne_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %x)
@@ -124,8 +124,8 @@ define i1 @and_sgt_m2(<4 x i32> %x) {
define i1 @umax_eq_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_eq_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %x)
@@ -136,8 +136,8 @@ define i1 @umax_eq_0(<4 x i32> %x) {
define i1 @umax_ne_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_ne_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %x)
@@ -220,8 +220,8 @@ define i1 @umin_sgt_m1(<4 x i32> %x) {
define i1 @or_eq_0_i8(<16 x i8> %x) {
; CHECK-LABEL: define i1 @or_eq_0_i8(
; CHECK-SAME: <16 x i8> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <16 x i8> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> %x)
@@ -232,8 +232,8 @@ define i1 @or_eq_0_i8(<16 x i8> %x) {
define i1 @or_eq_0_i64(<2 x i64> %x) {
; CHECK-LABEL: define i1 @or_eq_0_i64(
; CHECK-SAME: <2 x i64> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i64 @llvm.vector.reduce.umax.v2i64(<2 x i64> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i64> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v2i1(<2 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i64 @llvm.vector.reduce.or.v2i64(<2 x i64> %x)
@@ -344,8 +344,8 @@ define i1 @or_eq_0_scalable_negative(<vscale x 4 x i32> %x) {
define i1 @or_eq_0_v4i1(<4 x i1> %x) {
; CHECK-LABEL: define i1 @or_eq_0_v4i1(
; CHECK-SAME: <4 x i1> [[X:%.*]]) {
-; CHECK-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[RED]], false
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i1> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %x)
@@ -357,8 +357,7 @@ define i1 @or_ne_0_v4i1(<4 x i1> %x) {
; CHECK-LABEL: define i1 @or_ne_0_v4i1(
; CHECK-SAME: <4 x i1> [[X:%.*]]) {
; CHECK-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i1 [[RED]], false
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 [[RED]]
;
%red = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %x)
%cmp = icmp ne i1 %red, 0
@@ -392,8 +391,8 @@ define i1 @and_ne_allones_v4i1(<4 x i1> %x) {
define i1 @umax_eq_0_v4i1(<4 x i1> %x) {
; CHECK-LABEL: define i1 @umax_eq_0_v4i1(
; CHECK-SAME: <4 x i1> [[X:%.*]]) {
-; CHECK-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.umax.v4i1(<4 x i1> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[RED]], false
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i1> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i1 @llvm.vector.reduce.umax.v4i1(<4 x i1> %x)
diff --git a/llvm/test/Transforms/VectorCombine/AArch64/fold-reduce-add-cmp-zero.ll b/llvm/test/Transforms/VectorCombine/AArch64/fold-reduce-add-cmp-zero.ll
index 377ea6cd81246..027e0257f1372 100644
--- a/llvm/test/Transforms/VectorCombine/AArch64/fold-reduce-add-cmp-zero.ll
+++ b/llvm/test/Transforms/VectorCombine/AArch64/fold-reduce-add-cmp-zero.ll
@@ -7,8 +7,8 @@ define i1 @nn_zext_eq_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[ZA:%.*]] = zext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[ZB:%.*]] = zext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nuw <4 x i32> [[ZA]], [[ZB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%za = zext <4 x i1> %a to <4 x i32>
@@ -25,8 +25,8 @@ define i1 @np_sext_eq_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[SA:%.*]] = sext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[SB:%.*]] = sext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nsw <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = sext <4 x i1> %a to <4 x i32>
@@ -43,8 +43,8 @@ define i1 @np_sext_ne_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[SA:%.*]] = sext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[SB:%.*]] = sext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nsw <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = sext <4 x i1> %a to <4 x i32>
@@ -61,8 +61,8 @@ define i1 @nn_ule_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[ZA:%.*]] = zext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[ZB:%.*]] = zext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nuw <4 x i32> [[ZA]], [[ZB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%za = zext <4 x i1> %a to <4 x i32>
@@ -79,8 +79,8 @@ define i1 @nn_ugt_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[ZA:%.*]] = zext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[ZB:%.*]] = zext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nuw <4 x i32> [[ZA]], [[ZB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%za = zext <4 x i1> %a to <4 x i32>
@@ -97,8 +97,8 @@ define i1 @nn_sle_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[ZA:%.*]] = zext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[ZB:%.*]] = zext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nuw <4 x i32> [[ZA]], [[ZB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%za = zext <4 x i1> %a to <4 x i32>
@@ -115,8 +115,8 @@ define i1 @np_sge_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[SA:%.*]] = sext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[SB:%.*]] = sext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nsw <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = sext <4 x i1> %a to <4 x i32>
@@ -133,8 +133,8 @@ define i1 @np_slt_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[SA:%.*]] = sext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[SB:%.*]] = sext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nsw <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = sext <4 x i1> %a to <4 x i32>
@@ -151,8 +151,8 @@ define i1 @nn_sgt_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[ZA:%.*]] = zext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[ZB:%.*]] = zext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nuw <4 x i32> [[ZA]], [[ZB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%za = zext <4 x i1> %a to <4 x i32>
@@ -318,8 +318,8 @@ define i1 @overflow_boundary_ok(<4 x i32> %x) {
; CHECK-LABEL: define i1 @overflow_boundary_ok(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
; CHECK-NEXT: [[MASKED:%.*]] = and <4 x i32> [[X]], splat (i32 536870911)
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[MASKED]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[MASKED]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%masked = and <4 x i32> %x, splat (i32 536870911)
diff --git a/llvm/test/Transforms/VectorCombine/AArch64/fold-signbit-reduction-cmp.ll b/llvm/test/Transforms/VectorCombine/AArch64/fold-signbit-reduction-cmp.ll
index cb434b0bf36d2..68cd6e5115e7d 100644
--- a/llvm/test/Transforms/VectorCombine/AArch64/fold-signbit-reduction-cmp.ll
+++ b/llvm/test/Transforms/VectorCombine/AArch64/fold-signbit-reduction-cmp.ll
@@ -331,8 +331,8 @@ define i1 @negative_wrong_shift(<4 x i32> %x) {
; CHECK-LABEL: define i1 @negative_wrong_shift(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
; CHECK-NEXT: [[SHR:%.*]] = lshr <4 x i32> [[X]], splat (i32 30)
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SHR]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = lshr <4 x i32> %x, splat (i32 30)
@@ -362,8 +362,8 @@ define i1 @negative_multi_use_shift(<4 x i32> %x, ptr %p) {
; CHECK-SAME: <4 x i32> [[X:%.*]], ptr [[P:%.*]]) {
; CHECK-NEXT: [[SHR:%.*]] = lshr <4 x i32> [[X]], splat (i32 31)
; CHECK-NEXT: store <4 x i32> [[SHR]], ptr [[P]], align 16
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SHR]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = lshr <4 x i32> %x, splat (i32 31)
@@ -573,8 +573,8 @@ define i1 @i1_or_eq_0(<4 x i1> %x) {
; CHECK-LABEL: define i1 @i1_or_eq_0(
; CHECK-SAME: <4 x i1> [[X:%.*]]) {
; CHECK-NEXT: [[SHR:%.*]] = lshr <4 x i1> [[X]], zeroinitializer
-; CHECK-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[RED]], false
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i1> [[SHR]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = lshr <4 x i1> %x, splat (i1 0)
@@ -588,8 +588,7 @@ define i1 @i1_or_ne_0(<4 x i1> %x) {
; CHECK-SAME: <4 x i1> [[X:%.*]]) {
; CHECK-NEXT: [[SHR:%.*]] = lshr <4 x i1> [[X]], zeroinitializer
; CHECK-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i1 [[RED]], false
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 [[RED]]
;
%shr = lshr <4 x i1> %x, splat (i1 0)
%red = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %shr)
@@ -629,8 +628,8 @@ define i1 @i1_umax_eq_0(<4 x i1> %x) {
; CHECK-LABEL: define i1 @i1_umax_eq_0(
; CHECK-SAME: <4 x i1> [[X:%.*]]) {
; CHECK-NEXT: [[SHR:%.*]] = lshr <4 x i1> [[X]], zeroinitializer
-; CHECK-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.umax.v4i1(<4 x i1> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[RED]], false
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i1> [[SHR]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = lshr <4 x i1> %x, splat (i1 0)
@@ -657,8 +656,8 @@ define i1 @i1_ashr_or_eq_0(<4 x i1> %x) {
; CHECK-LABEL: define i1 @i1_ashr_or_eq_0(
; CHECK-SAME: <4 x i1> [[X:%.*]]) {
; CHECK-NEXT: [[SHR:%.*]] = ashr <4 x i1> [[X]], zeroinitializer
-; CHECK-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[RED]], false
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i1> [[SHR]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = ashr <4 x i1> %x, splat (i1 0)
@@ -1013,8 +1012,8 @@ define i1 @negative_multi_shift_multiuse(<4 x i32> %a, <4 x i32> %b, ptr %p) {
; CHECK-NEXT: store <4 x i32> [[SA]], ptr [[P]], align 16
; CHECK-NEXT: [[SB:%.*]] = lshr <4 x i32> [[B]], splat (i32 31)
; CHECK-NEXT: [[SUM:%.*]] = add <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[SUM]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SUM]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = lshr <4 x i32> %a, splat (i32 31)
@@ -1036,8 +1035,8 @@ define i1 @negative_multi_tree_node_multiuse(<4 x i32> %a, <4 x i32> %b, <4 x i3
; CHECK-NEXT: [[AB:%.*]] = add <4 x i32> [[SA]], [[SB]]
; CHECK-NEXT: store <4 x i32> [[AB]], ptr [[P]], align 16
; CHECK-NEXT: [[ABC:%.*]] = add <4 x i32> [[AB]], [[SC]]
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[ABC]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ABC]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = lshr <4 x i32> %a, splat (i32 31)
@@ -1058,8 +1057,8 @@ define i1 @negative_multi_op_mismatch(<4 x i32> %a, <4 x i32> %b) {
; CHECK-NEXT: [[SA:%.*]] = lshr <4 x i32> [[A]], splat (i32 31)
; CHECK-NEXT: [[SB:%.*]] = lshr <4 x i32> [[B]], splat (i32 31)
; CHECK-NEXT: [[SUM:%.*]] = add <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[SUM]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SUM]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = lshr <4 x i32> %a, splat (i32 31)
diff --git a/llvm/test/Transforms/VectorCombine/AArch64/icmp-vector-reduce.ll b/llvm/test/Transforms/VectorCombine/AArch64/icmp-vector-reduce.ll
index ec11495218a92..0a6f4e9b95553 100644
--- a/llvm/test/Transforms/VectorCombine/AArch64/icmp-vector-reduce.ll
+++ b/llvm/test/Transforms/VectorCombine/AArch64/icmp-vector-reduce.ll
@@ -32,8 +32,8 @@ define i1 @or_zext_i3(<4 x i3> %x) {
define i1 @or_zext_v3_costly(<3 x i8> %x) {
; CHECK-LABEL: define i1 @or_zext_v3_costly(
; CHECK-SAME: <3 x i8> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.vector.reduce.umax.v3i8(<3 x i8> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <3 x i8> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v3i1(<3 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <3 x i8> %x to <3 x i32>
@@ -59,8 +59,8 @@ define i1 @or_sext(<4 x i16> %x) {
define i1 @or_neg(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_neg(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%neg = sub <4 x i32> zeroinitializer, %x
@@ -72,8 +72,8 @@ define i1 @or_neg(<4 x i32> %x) {
define i1 @or_mul(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_mul(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul nuw <4 x i32> %x, splat (i32 7)
@@ -85,8 +85,8 @@ define i1 @or_mul(<4 x i32> %x) {
define i1 @or_shl(<4 x i32> %x, <4 x i32> %y) {
; CHECK-LABEL: define i1 @or_shl(
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shl = shl nuw <4 x i32> %x, %y
@@ -163,8 +163,8 @@ define i1 @umin_shl(<4 x i32> %x, <4 x i32> %y) {
define i1 @umax_zext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @umax_zext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -176,8 +176,8 @@ define i1 @umax_zext(<4 x i16> %x) {
define i1 @umax_sext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @umax_sext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sext = sext <4 x i16> %x to <4 x i32>
@@ -189,8 +189,8 @@ define i1 @umax_sext(<4 x i16> %x) {
define i1 @umax_neg(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_neg(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%neg = sub <4 x i32> zeroinitializer, %x
@@ -202,8 +202,8 @@ define i1 @umax_neg(<4 x i32> %x) {
define i1 @umax_mul(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_mul(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul nuw <4 x i32> %x, splat (i32 7)
@@ -215,8 +215,8 @@ define i1 @umax_mul(<4 x i32> %x) {
define i1 @umax_shl(<4 x i32> %x, <4 x i32> %y) {
; CHECK-LABEL: define i1 @umax_shl(
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shl = shl nuw <4 x i32> %x, %y
@@ -385,8 +385,8 @@ define i1 @add_zext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_zext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[X]], splat (i16 8191)
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[AND]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[AND]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%and = and <4 x i16> %x, splat (i16 8191)
@@ -400,8 +400,8 @@ define i1 @add_sext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_sext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[X]], splat (i16 8191)
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[AND]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[AND]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%and = and <4 x i16> %x, splat (i16 8191)
@@ -431,8 +431,8 @@ define i1 @add_neg(<4 x i16> %x) {
define i1 @add_mul(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_mul(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -445,8 +445,8 @@ define i1 @add_mul(<4 x i16> %x) {
define i1 @add_shl(<4 x i16> %x, <4 x i32> %y) {
; CHECK-LABEL: define i1 @add_shl(
; CHECK-SAME: <4 x i16> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -460,8 +460,8 @@ define i1 @add_shl(<4 x i16> %x, <4 x i32> %y) {
define i1 @add_shl_ne(<4 x i16> %x, <4 x i32> %y) {
; CHECK-LABEL: define i1 @add_shl_ne(
; CHECK-SAME: <4 x i16> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -516,8 +516,8 @@ define i1 @add_shl_multiuse(<4 x i16> %x, <4 x i32> %y, ptr %p) {
; CHECK-NEXT: [[YMASKED:%.*]] = and <4 x i32> [[Y]], splat (i32 7)
; CHECK-NEXT: [[SHL:%.*]] = shl nsw <4 x i32> [[ZEXT]], [[YMASKED]]
; CHECK-NEXT: store <4 x i32> [[SHL]], ptr [[P]], align 16
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[SHL]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SHL]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -549,8 +549,8 @@ define i1 @add_shl_unbounded(<4 x i16> %x, <4 x i32> %y) {
define i1 @add_mul_nonsplat(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_mul_nonsplat(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -563,8 +563,8 @@ define i1 @add_mul_nonsplat(<4 x i16> %x) {
define i1 @add_mul_poison(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_mul_poison(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -580,8 +580,8 @@ define i1 @add_mul_zero_lane(<4 x i16> %x) {
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
; CHECK-NEXT: [[ZEXT:%.*]] = zext <4 x i16> [[X]] to <4 x i32>
; CHECK-NEXT: [[MUL:%.*]] = mul nuw <4 x i32> [[ZEXT]], <i32 1, i32 0, i32 3, i32 4>
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[MUL]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[MUL]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -615,8 +615,8 @@ define void @or_zext_two_blocks(<4 x i16> %x) {
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[A:%.*]] = zext <4 x i16> [[X]] to <4 x i32>
-; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP0]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP0]])
; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[EXIT:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: call void @foo(<4 x i32> [[A]])
@@ -643,8 +643,8 @@ define void @or_shl_two_blocks(<4 x i32> %x, <4 x i32> %y) {
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[A:%.*]] = shl nuw <4 x i32> [[X]], [[Y]]
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP0]])
; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[EXIT:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: call void @foo(<4 x i32> [[A]])
diff --git a/llvm/test/Transforms/VectorCombine/RISCV/fold-equivalent-reduction-cmp.ll b/llvm/test/Transforms/VectorCombine/RISCV/fold-equivalent-reduction-cmp.ll
index 23fcf1f93dfe6..9de5b9c07ba9d 100644
--- a/llvm/test/Transforms/VectorCombine/RISCV/fold-equivalent-reduction-cmp.ll
+++ b/llvm/test/Transforms/VectorCombine/RISCV/fold-equivalent-reduction-cmp.ll
@@ -4,8 +4,8 @@
define i1 @or_eq_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_eq_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %x)
@@ -16,8 +16,8 @@ define i1 @or_eq_0(<4 x i32> %x) {
define i1 @or_ne_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_ne_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %x)
@@ -124,8 +124,8 @@ define i1 @and_sgt_m2(<4 x i32> %x) {
define i1 @umax_eq_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_eq_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %x)
@@ -136,8 +136,8 @@ define i1 @umax_eq_0(<4 x i32> %x) {
define i1 @umax_ne_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_ne_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %x)
@@ -220,8 +220,8 @@ define i1 @umin_sgt_m1(<4 x i32> %x) {
define i1 @or_eq_0_i8(<16 x i8> %x) {
; CHECK-LABEL: define i1 @or_eq_0_i8(
; CHECK-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[RED:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <16 x i8> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> %x)
diff --git a/llvm/test/Transforms/VectorCombine/RISCV/fold-reduce-add-cmp-zero.ll b/llvm/test/Transforms/VectorCombine/RISCV/fold-reduce-add-cmp-zero.ll
index 402d01cefc0d5..0c376c122b854 100644
--- a/llvm/test/Transforms/VectorCombine/RISCV/fold-reduce-add-cmp-zero.ll
+++ b/llvm/test/Transforms/VectorCombine/RISCV/fold-reduce-add-cmp-zero.ll
@@ -7,8 +7,8 @@ define i1 @nn_zext_eq_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[ZA:%.*]] = zext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[ZB:%.*]] = zext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nuw <4 x i32> [[ZA]], [[ZB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%za = zext <4 x i1> %a to <4 x i32>
@@ -25,8 +25,8 @@ define i1 @np_sext_eq_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[SA:%.*]] = sext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[SB:%.*]] = sext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nsw <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = sext <4 x i1> %a to <4 x i32>
@@ -43,8 +43,8 @@ define i1 @np_sext_ne_0(<4 x i1> %a, <4 x i1> %b) {
; CHECK-NEXT: [[SA:%.*]] = sext <4 x i1> [[A]] to <4 x i32>
; CHECK-NEXT: [[SB:%.*]] = sext <4 x i1> [[B]] to <4 x i32>
; CHECK-NEXT: [[ADD:%.*]] = add nsw <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[ADD]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[ADD]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = sext <4 x i1> %a to <4 x i32>
diff --git a/llvm/test/Transforms/VectorCombine/RISCV/fold-signbit-reduction-cmp.ll b/llvm/test/Transforms/VectorCombine/RISCV/fold-signbit-reduction-cmp.ll
index 39ca7a7fc4008..afba5ddb2d42c 100644
--- a/llvm/test/Transforms/VectorCombine/RISCV/fold-signbit-reduction-cmp.ll
+++ b/llvm/test/Transforms/VectorCombine/RISCV/fold-signbit-reduction-cmp.ll
@@ -330,8 +330,8 @@ define i1 @negative_wrong_shift(<4 x i32> %x) {
; CHECK-LABEL: define i1 @negative_wrong_shift(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SHR:%.*]] = lshr <4 x i32> [[X]], splat (i32 30)
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SHR]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = lshr <4 x i32> %x, splat (i32 30)
@@ -359,8 +359,8 @@ define i1 @negative_multi_use_shift(<4 x i32> %x, ptr %p) {
; CHECK-SAME: <4 x i32> [[X:%.*]], ptr [[P:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SHR:%.*]] = lshr <4 x i32> [[X]], splat (i32 31)
; CHECK-NEXT: store <4 x i32> [[SHR]], ptr [[P]], align 16
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SHR]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = lshr <4 x i32> %x, splat (i32 31)
@@ -581,8 +581,7 @@ define i1 @i1_or_ne_0(<4 x i1> %x) {
; CHECK-SAME: <4 x i1> [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[SHR:%.*]] = lshr <4 x i1> [[X]], zeroinitializer
; CHECK-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i1 [[RED]], false
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 [[RED]]
;
%shr = lshr <4 x i1> %x, splat (i1 0)
%red = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> %shr)
@@ -1006,8 +1005,8 @@ define i1 @negative_multi_shift_multiuse(<4 x i32> %a, <4 x i32> %b, ptr %p) {
; CHECK-NEXT: store <4 x i32> [[SA]], ptr [[P]], align 16
; CHECK-NEXT: [[SB:%.*]] = lshr <4 x i32> [[B]], splat (i32 31)
; CHECK-NEXT: [[SUM:%.*]] = add <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[SUM]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SUM]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = lshr <4 x i32> %a, splat (i32 31)
@@ -1029,8 +1028,8 @@ define i1 @negative_multi_tree_node_multiuse(<4 x i32> %a, <4 x i32> %b, <4 x i3
; CHECK-NEXT: [[AB:%.*]] = add <4 x i32> [[SA]], [[SB]]
; CHECK-NEXT: store <4 x i32> [[AB]], ptr [[P]], align 16
; CHECK-NEXT: [[ABC:%.*]] = add <4 x i32> [[AB]], [[SC]]
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[ABC]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[ABC]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = lshr <4 x i32> %a, splat (i32 31)
@@ -1051,8 +1050,8 @@ define i1 @negative_multi_op_mismatch(<4 x i32> %a, <4 x i32> %b) {
; CHECK-NEXT: [[SA:%.*]] = lshr <4 x i32> [[A]], splat (i32 31)
; CHECK-NEXT: [[SB:%.*]] = lshr <4 x i32> [[B]], splat (i32 31)
; CHECK-NEXT: [[SUM:%.*]] = add <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[SUM]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SUM]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = lshr <4 x i32> %a, splat (i32 31)
diff --git a/llvm/test/Transforms/VectorCombine/RISCV/icmp-vector-reduce.ll b/llvm/test/Transforms/VectorCombine/RISCV/icmp-vector-reduce.ll
index 023377a0a1670..91c9e863ac77c 100644
--- a/llvm/test/Transforms/VectorCombine/RISCV/icmp-vector-reduce.ll
+++ b/llvm/test/Transforms/VectorCombine/RISCV/icmp-vector-reduce.ll
@@ -4,8 +4,8 @@
define i1 @or_zext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @or_zext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -17,8 +17,8 @@ define i1 @or_zext(<4 x i16> %x) {
define i1 @or_zext_i3(<4 x i3> %x) {
; CHECK-LABEL: define i1 @or_zext_i3(
; CHECK-SAME: <4 x i3> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i3 @llvm.vector.reduce.or.v4i3(<4 x i3> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i3 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i3> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i3> %x to <4 x i32>
@@ -30,8 +30,8 @@ define i1 @or_zext_i3(<4 x i3> %x) {
define i1 @or_zext_v3_costly(<3 x i8> %x) {
; CHECK-LABEL: define i1 @or_zext_v3_costly(
; CHECK-SAME: <3 x i8> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.vector.reduce.or.v3i8(<3 x i8> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <3 x i8> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v3i1(<3 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <3 x i8> %x to <3 x i32>
@@ -43,8 +43,8 @@ define i1 @or_zext_v3_costly(<3 x i8> %x) {
define i1 @or_sext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @or_sext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sext = sext <4 x i16> %x to <4 x i32>
@@ -56,8 +56,8 @@ define i1 @or_sext(<4 x i16> %x) {
define i1 @or_neg(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_neg(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%neg = sub <4 x i32> zeroinitializer, %x
@@ -69,8 +69,8 @@ define i1 @or_neg(<4 x i32> %x) {
define i1 @or_mul(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_mul(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul nuw <4 x i32> %x, splat (i32 7)
@@ -82,8 +82,8 @@ define i1 @or_mul(<4 x i32> %x) {
define i1 @or_shl(<4 x i32> %x, <4 x i32> %y) {
; CHECK-LABEL: define i1 @or_shl(
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shl = shl nuw <4 x i32> %x, %y
@@ -160,8 +160,8 @@ define i1 @umin_shl(<4 x i32> %x, <4 x i32> %y) {
define i1 @umax_zext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @umax_zext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -173,8 +173,8 @@ define i1 @umax_zext(<4 x i16> %x) {
define i1 @umax_sext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @umax_sext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sext = sext <4 x i16> %x to <4 x i32>
@@ -186,8 +186,8 @@ define i1 @umax_sext(<4 x i16> %x) {
define i1 @umax_neg(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_neg(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%neg = sub <4 x i32> zeroinitializer, %x
@@ -199,8 +199,8 @@ define i1 @umax_neg(<4 x i32> %x) {
define i1 @umax_mul(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_mul(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul nuw <4 x i32> %x, splat (i32 7)
@@ -212,8 +212,8 @@ define i1 @umax_mul(<4 x i32> %x) {
define i1 @umax_shl(<4 x i32> %x, <4 x i32> %y) {
; CHECK-LABEL: define i1 @umax_shl(
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shl = shl nuw <4 x i32> %x, %y
@@ -380,8 +380,8 @@ define i1 @add_zext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_zext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[X]], splat (i16 8191)
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[AND]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[AND]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%and = and <4 x i16> %x, splat (i16 8191)
@@ -395,8 +395,8 @@ define i1 @add_sext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_sext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[X]], splat (i16 8191)
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[AND]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[AND]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%and = and <4 x i16> %x, splat (i16 8191)
@@ -425,8 +425,8 @@ define i1 @add_neg(<4 x i16> %x) {
define i1 @add_mul(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_mul(
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -439,8 +439,8 @@ define i1 @add_mul(<4 x i16> %x) {
define i1 @add_shl(<4 x i16> %x, <4 x i32> %y) {
; CHECK-LABEL: define i1 @add_shl(
; CHECK-SAME: <4 x i16> [[X:%.*]], <4 x i32> [[Y:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -454,8 +454,8 @@ define i1 @add_shl(<4 x i16> %x, <4 x i32> %y) {
define i1 @add_shl_ne(<4 x i16> %x, <4 x i32> %y) {
; CHECK-LABEL: define i1 @add_shl_ne(
; CHECK-SAME: <4 x i16> [[X:%.*]], <4 x i32> [[Y:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -507,8 +507,8 @@ define i1 @add_shl_multiuse(<4 x i16> %x, <4 x i32> %y, ptr %p) {
; CHECK-NEXT: [[YMASKED:%.*]] = and <4 x i32> [[Y]], splat (i32 7)
; CHECK-NEXT: [[SHL:%.*]] = shl nsw <4 x i32> [[ZEXT]], [[YMASKED]]
; CHECK-NEXT: store <4 x i32> [[SHL]], ptr [[P]], align 16
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[SHL]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SHL]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -539,8 +539,8 @@ define i1 @add_shl_unbounded(<4 x i16> %x, <4 x i32> %y) {
define i1 @add_mul_nonsplat(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_mul_nonsplat(
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -553,8 +553,8 @@ define i1 @add_mul_nonsplat(<4 x i16> %x) {
define i1 @add_mul_poison(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_mul_poison(
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -569,8 +569,8 @@ define i1 @add_mul_zero_lane(<4 x i16> %x) {
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ZEXT:%.*]] = zext <4 x i16> [[X]] to <4 x i32>
; CHECK-NEXT: [[MUL:%.*]] = mul nuw <4 x i32> [[ZEXT]], <i32 1, i32 0, i32 3, i32 4>
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[MUL]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[MUL]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -603,8 +603,8 @@ define void @or_zext_two_blocks(<4 x i16> %x) {
; CHECK-SAME: <4 x i16> [[X:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[A:%.*]] = zext <4 x i16> [[X]] to <4 x i32>
-; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.vector.reduce.or.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP0]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP0]])
; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[EXIT:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: call void @foo(<4 x i32> [[A]])
@@ -631,8 +631,8 @@ define void @or_shl_two_blocks(<4 x i32> %x, <4 x i32> %y) {
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) #[[ATTR0]] {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[A:%.*]] = shl nuw <4 x i32> [[X]], [[Y]]
-; CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP0]])
; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[EXIT:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: call void @foo(<4 x i32> [[A]])
diff --git a/llvm/test/Transforms/VectorCombine/X86/fold-equivalent-reduction-cmp.ll b/llvm/test/Transforms/VectorCombine/X86/fold-equivalent-reduction-cmp.ll
index f103da3ee7342..9f11651e04f4c 100644
--- a/llvm/test/Transforms/VectorCombine/X86/fold-equivalent-reduction-cmp.ll
+++ b/llvm/test/Transforms/VectorCombine/X86/fold-equivalent-reduction-cmp.ll
@@ -4,8 +4,8 @@
define i1 @or_eq_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_eq_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %x)
@@ -16,8 +16,8 @@ define i1 @or_eq_0(<4 x i32> %x) {
define i1 @or_ne_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_ne_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.or.v4i32(<4 x i32> %x)
@@ -100,8 +100,8 @@ define i1 @and_sgt_m1(<4 x i32> %x) {
define i1 @umax_eq_0(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_eq_0(
; CHECK-SAME: <4 x i32> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> %x)
@@ -220,8 +220,8 @@ define i1 @umin_sgt_m2(<4 x i32> %x) {
define i1 @umax_eq_0_i8(<16 x i8> %x) {
; CHECK-LABEL: define i1 @umax_eq_0_i8(
; CHECK-SAME: <16 x i8> [[X:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT: [[RED:%.*]] = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <16 x i8> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%red = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> %x)
diff --git a/llvm/test/Transforms/VectorCombine/X86/fold-reduction-zero-test.ll b/llvm/test/Transforms/VectorCombine/X86/fold-reduction-zero-test.ll
index 4f7e1c78f19ab..3df785f000195 100644
--- a/llvm/test/Transforms/VectorCombine/X86/fold-reduction-zero-test.ll
+++ b/llvm/test/Transforms/VectorCombine/X86/fold-reduction-zero-test.ll
@@ -1,15 +1,36 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
-; RUN: opt -passes=vector-combine -S %s | FileCheck %s
+; RUN: opt -mtriple=x86_64-- -mcpu=x86-64 -passes=vector-combine -S %s | FileCheck %s --check-prefix=V1
+; RUN: opt -mtriple=x86_64-- -mcpu=x86-64-v2 -passes=vector-combine -S %s | FileCheck %s --check-prefix=V2
+; RUN: opt -mtriple=x86_64-- -mcpu=x86-64-v3 -passes=vector-combine -S %s | FileCheck %s --check-prefix=V3
+; RUN: opt -mtriple=x86_64-- -mcpu=x86-64-v4 -passes=vector-combine -S %s | FileCheck %s --check-prefix=V4
declare i8 @llvm.vector.reduce.or.v16i8(<16 x i8>)
declare i8 @llvm.vector.reduce.umax.v16i8(<16 x i8>)
define i1 @or_nonzero(<16 x i8> %x) {
-; CHECK-LABEL: define i1 @or_nonzero(
-; CHECK-SAME: <16 x i8> [[X:%.*]]) {
-; CHECK-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; V1-LABEL: define i1 @or_nonzero(
+; V1-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1:[0-9]+]] {
+; V1-NEXT: [[TMP1:%.*]] = icmp ne <16 x i8> [[X]], zeroinitializer
+; V1-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> [[TMP1]])
+; V1-NEXT: ret i1 [[CMP]]
+;
+; V2-LABEL: define i1 @or_nonzero(
+; V2-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1:[0-9]+]] {
+; V2-NEXT: [[TMP1:%.*]] = icmp ne <16 x i8> [[X]], zeroinitializer
+; V2-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> [[TMP1]])
+; V2-NEXT: ret i1 [[CMP]]
+;
+; V3-LABEL: define i1 @or_nonzero(
+; V3-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1:[0-9]+]] {
+; V3-NEXT: [[TMP1:%.*]] = icmp ne <16 x i8> [[X]], zeroinitializer
+; V3-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> [[TMP1]])
+; V3-NEXT: ret i1 [[CMP]]
+;
+; V4-LABEL: define i1 @or_nonzero(
+; V4-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1:[0-9]+]] {
+; V4-NEXT: [[TMP1:%.*]] = icmp ne <16 x i8> [[X]], zeroinitializer
+; V4-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> [[TMP1]])
+; V4-NEXT: ret i1 [[CMP]]
;
%reduction = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> %x)
%cmp = icmp ne i8 %reduction, 0
@@ -17,11 +38,29 @@ define i1 @or_nonzero(<16 x i8> %x) {
}
define i1 @or_zero(<16 x i8> %x) {
-; CHECK-LABEL: define i1 @or_zero(
-; CHECK-SAME: <16 x i8> [[X:%.*]]) {
-; CHECK-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[REDUCTION]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; V1-LABEL: define i1 @or_zero(
+; V1-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V1-NEXT: [[TMP1:%.*]] = icmp eq <16 x i8> [[X]], zeroinitializer
+; V1-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[TMP1]])
+; V1-NEXT: ret i1 [[CMP]]
+;
+; V2-LABEL: define i1 @or_zero(
+; V2-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V2-NEXT: [[TMP1:%.*]] = icmp eq <16 x i8> [[X]], zeroinitializer
+; V2-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[TMP1]])
+; V2-NEXT: ret i1 [[CMP]]
+;
+; V3-LABEL: define i1 @or_zero(
+; V3-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V3-NEXT: [[TMP1:%.*]] = icmp eq <16 x i8> [[X]], zeroinitializer
+; V3-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[TMP1]])
+; V3-NEXT: ret i1 [[CMP]]
+;
+; V4-LABEL: define i1 @or_zero(
+; V4-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V4-NEXT: [[TMP1:%.*]] = icmp eq <16 x i8> [[X]], zeroinitializer
+; V4-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[TMP1]])
+; V4-NEXT: ret i1 [[CMP]]
;
%reduction = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> %x)
%cmp = icmp eq i8 %reduction, 0
@@ -29,11 +68,29 @@ define i1 @or_zero(<16 x i8> %x) {
}
define i1 @umax_nonzero(<16 x i8> %x) {
-; CHECK-LABEL: define i1 @umax_nonzero(
-; CHECK-SAME: <16 x i8> [[X:%.*]]) {
-; CHECK-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; V1-LABEL: define i1 @umax_nonzero(
+; V1-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V1-NEXT: [[TMP1:%.*]] = icmp ne <16 x i8> [[X]], zeroinitializer
+; V1-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> [[TMP1]])
+; V1-NEXT: ret i1 [[CMP]]
+;
+; V2-LABEL: define i1 @umax_nonzero(
+; V2-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V2-NEXT: [[TMP1:%.*]] = icmp ne <16 x i8> [[X]], zeroinitializer
+; V2-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> [[TMP1]])
+; V2-NEXT: ret i1 [[CMP]]
+;
+; V3-LABEL: define i1 @umax_nonzero(
+; V3-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V3-NEXT: [[TMP1:%.*]] = icmp ne <16 x i8> [[X]], zeroinitializer
+; V3-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.or.v16i1(<16 x i1> [[TMP1]])
+; V3-NEXT: ret i1 [[CMP]]
+;
+; V4-LABEL: define i1 @umax_nonzero(
+; V4-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V4-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> [[X]])
+; V4-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
+; V4-NEXT: ret i1 [[CMP]]
;
%reduction = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> %x)
%cmp = icmp ne i8 %reduction, 0
@@ -41,11 +98,29 @@ define i1 @umax_nonzero(<16 x i8> %x) {
}
define i1 @umax_zero_commuted(<16 x i8> %x) {
-; CHECK-LABEL: define i1 @umax_zero_commuted(
-; CHECK-SAME: <16 x i8> [[X:%.*]]) {
-; CHECK-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 0, [[REDUCTION]]
-; CHECK-NEXT: ret i1 [[CMP]]
+; V1-LABEL: define i1 @umax_zero_commuted(
+; V1-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V1-NEXT: [[TMP1:%.*]] = icmp eq <16 x i8> [[X]], zeroinitializer
+; V1-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[TMP1]])
+; V1-NEXT: ret i1 [[CMP]]
+;
+; V2-LABEL: define i1 @umax_zero_commuted(
+; V2-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V2-NEXT: [[TMP1:%.*]] = icmp eq <16 x i8> [[X]], zeroinitializer
+; V2-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[TMP1]])
+; V2-NEXT: ret i1 [[CMP]]
+;
+; V3-LABEL: define i1 @umax_zero_commuted(
+; V3-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V3-NEXT: [[TMP1:%.*]] = icmp eq <16 x i8> [[X]], zeroinitializer
+; V3-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v16i1(<16 x i1> [[TMP1]])
+; V3-NEXT: ret i1 [[CMP]]
+;
+; V4-LABEL: define i1 @umax_zero_commuted(
+; V4-SAME: <16 x i8> [[X:%.*]]) #[[ATTR1]] {
+; V4-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> [[X]])
+; V4-NEXT: [[CMP:%.*]] = icmp eq i8 0, [[REDUCTION]]
+; V4-NEXT: ret i1 [[CMP]]
;
%reduction = call i8 @llvm.vector.reduce.umax.v16i8(<16 x i8> %x)
%cmp = icmp eq i8 0, %reduction
@@ -53,12 +128,33 @@ define i1 @umax_zero_commuted(<16 x i8> %x) {
}
define i1 @or_nonzero_multiuse(<16 x i8> %x, ptr %out) {
-; CHECK-LABEL: define i1 @or_nonzero_multiuse(
-; CHECK-SAME: <16 x i8> [[X:%.*]], ptr [[OUT:%.*]]) {
-; CHECK-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
-; CHECK-NEXT: store i8 [[REDUCTION]], ptr [[OUT]], align 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; V1-LABEL: define i1 @or_nonzero_multiuse(
+; V1-SAME: <16 x i8> [[X:%.*]], ptr [[OUT:%.*]]) #[[ATTR1]] {
+; V1-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
+; V1-NEXT: store i8 [[REDUCTION]], ptr [[OUT]], align 1
+; V1-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
+; V1-NEXT: ret i1 [[CMP]]
+;
+; V2-LABEL: define i1 @or_nonzero_multiuse(
+; V2-SAME: <16 x i8> [[X:%.*]], ptr [[OUT:%.*]]) #[[ATTR1]] {
+; V2-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
+; V2-NEXT: store i8 [[REDUCTION]], ptr [[OUT]], align 1
+; V2-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
+; V2-NEXT: ret i1 [[CMP]]
+;
+; V3-LABEL: define i1 @or_nonzero_multiuse(
+; V3-SAME: <16 x i8> [[X:%.*]], ptr [[OUT:%.*]]) #[[ATTR1]] {
+; V3-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
+; V3-NEXT: store i8 [[REDUCTION]], ptr [[OUT]], align 1
+; V3-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
+; V3-NEXT: ret i1 [[CMP]]
+;
+; V4-LABEL: define i1 @or_nonzero_multiuse(
+; V4-SAME: <16 x i8> [[X:%.*]], ptr [[OUT:%.*]]) #[[ATTR1]] {
+; V4-NEXT: [[REDUCTION:%.*]] = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> [[X]])
+; V4-NEXT: store i8 [[REDUCTION]], ptr [[OUT]], align 1
+; V4-NEXT: [[CMP:%.*]] = icmp ne i8 [[REDUCTION]], 0
+; V4-NEXT: ret i1 [[CMP]]
;
%reduction = call i8 @llvm.vector.reduce.or.v16i8(<16 x i8> %x)
store i8 %reduction, ptr %out, align 1
diff --git a/llvm/test/Transforms/VectorCombine/X86/fold-signbit-reduction-cmp.ll b/llvm/test/Transforms/VectorCombine/X86/fold-signbit-reduction-cmp.ll
index e24053604adec..74d651e91871c 100644
--- a/llvm/test/Transforms/VectorCombine/X86/fold-signbit-reduction-cmp.ll
+++ b/llvm/test/Transforms/VectorCombine/X86/fold-signbit-reduction-cmp.ll
@@ -572,8 +572,8 @@ define i1 @i1_or_eq_0(<4 x i1> %x) {
; CHECK-LABEL: define i1 @i1_or_eq_0(
; CHECK-SAME: <4 x i1> [[X:%.*]]) {
; CHECK-NEXT: [[SHR:%.*]] = lshr <4 x i1> [[X]], zeroinitializer
-; CHECK-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[RED]], false
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i1> [[SHR]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = lshr <4 x i1> %x, splat (i1 0)
@@ -628,8 +628,8 @@ define i1 @i1_umax_eq_0(<4 x i1> %x) {
; CHECK-LABEL: define i1 @i1_umax_eq_0(
; CHECK-SAME: <4 x i1> [[X:%.*]]) {
; CHECK-NEXT: [[SHR:%.*]] = lshr <4 x i1> [[X]], zeroinitializer
-; CHECK-NEXT: [[TMP1:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[TMP1]], false
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i1> [[SHR]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = lshr <4 x i1> %x, splat (i1 0)
@@ -655,8 +655,8 @@ define i1 @i1_ashr_or_eq_0(<4 x i1> %x) {
; CHECK-LABEL: define i1 @i1_ashr_or_eq_0(
; CHECK-SAME: <4 x i1> [[X:%.*]]) {
; CHECK-NEXT: [[SHR:%.*]] = ashr <4 x i1> [[X]], zeroinitializer
-; CHECK-NEXT: [[RED:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[SHR]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i1 [[RED]], false
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i1> [[SHR]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shr = ashr <4 x i1> %x, splat (i1 0)
@@ -1056,8 +1056,8 @@ define i1 @negative_multi_op_mismatch(<4 x i32> %a, <4 x i32> %b) {
; CHECK-NEXT: [[SA:%.*]] = lshr <4 x i32> [[A]], splat (i32 31)
; CHECK-NEXT: [[SB:%.*]] = lshr <4 x i32> [[B]], splat (i32 31)
; CHECK-NEXT: [[SUM:%.*]] = add <4 x i32> [[SA]], [[SB]]
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[SUM]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[SUM]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sa = lshr <4 x i32> %a, splat (i32 31)
diff --git a/llvm/test/Transforms/VectorCombine/X86/icmp-vector-reduce.ll b/llvm/test/Transforms/VectorCombine/X86/icmp-vector-reduce.ll
index 3d8a9e329a791..28bc789236635 100644
--- a/llvm/test/Transforms/VectorCombine/X86/icmp-vector-reduce.ll
+++ b/llvm/test/Transforms/VectorCombine/X86/icmp-vector-reduce.ll
@@ -4,8 +4,8 @@
define i1 @or_zext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @or_zext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -17,8 +17,8 @@ define i1 @or_zext(<4 x i16> %x) {
define i1 @or_zext_i3(<4 x i3> %x) {
; CHECK-LABEL: define i1 @or_zext_i3(
; CHECK-SAME: <4 x i3> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i3 @llvm.vector.reduce.umax.v4i3(<4 x i3> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i3 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i3> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i3> %x to <4 x i32>
@@ -32,8 +32,8 @@ define i1 @or_zext_v3_costly(<3 x i8> %x) {
; CHECK-LABEL: define i1 @or_zext_v3_costly(
; CHECK-SAME: <3 x i8> [[X:%.*]]) {
; CHECK-NEXT: [[ZEXT:%.*]] = zext <3 x i8> [[X]] to <3 x i32>
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.or.v3i32(<3 x i32> [[ZEXT]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <3 x i32> [[ZEXT]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v3i1(<3 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <3 x i8> %x to <3 x i32>
@@ -59,8 +59,8 @@ define i1 @or_sext(<4 x i16> %x) {
define i1 @or_neg(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_neg(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%neg = sub <4 x i32> zeroinitializer, %x
@@ -72,8 +72,8 @@ define i1 @or_neg(<4 x i32> %x) {
define i1 @or_mul(<4 x i32> %x) {
; CHECK-LABEL: define i1 @or_mul(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul nuw <4 x i32> %x, splat (i32 7)
@@ -85,8 +85,8 @@ define i1 @or_mul(<4 x i32> %x) {
define i1 @or_shl(<4 x i32> %x, <4 x i32> %y) {
; CHECK-LABEL: define i1 @or_shl(
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shl = shl nuw <4 x i32> %x, %y
@@ -163,8 +163,8 @@ define i1 @umin_shl(<4 x i32> %x, <4 x i32> %y) {
define i1 @umax_zext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @umax_zext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%zext = zext <4 x i16> %x to <4 x i32>
@@ -176,8 +176,8 @@ define i1 @umax_zext(<4 x i16> %x) {
define i1 @umax_sext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @umax_sext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%sext = sext <4 x i16> %x to <4 x i32>
@@ -189,8 +189,8 @@ define i1 @umax_sext(<4 x i16> %x) {
define i1 @umax_neg(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_neg(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%neg = sub <4 x i32> zeroinitializer, %x
@@ -202,8 +202,8 @@ define i1 @umax_neg(<4 x i32> %x) {
define i1 @umax_mul(<4 x i32> %x) {
; CHECK-LABEL: define i1 @umax_mul(
; CHECK-SAME: <4 x i32> [[X:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%mul = mul nuw <4 x i32> %x, splat (i32 7)
@@ -215,8 +215,8 @@ define i1 @umax_mul(<4 x i32> %x) {
define i1 @umax_shl(<4 x i32> %x, <4 x i32> %y) {
; CHECK-LABEL: define i1 @umax_shl(
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%shl = shl nuw <4 x i32> %x, %y
@@ -385,8 +385,8 @@ define i1 @add_zext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_zext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[X]], splat (i16 8191)
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[AND]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[AND]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%and = and <4 x i16> %x, splat (i16 8191)
@@ -400,8 +400,8 @@ define i1 @add_sext(<4 x i16> %x) {
; CHECK-LABEL: define i1 @add_sext(
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
; CHECK-NEXT: [[AND:%.*]] = and <4 x i16> [[X]], splat (i16 8191)
-; CHECK-NEXT: [[TMP1:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[AND]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP1]], 0
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <4 x i16> [[AND]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP1]])
; CHECK-NEXT: ret i1 [[CMP]]
;
%and = and <4 x i16> %x, splat (i16 8191)
@@ -620,8 +620,8 @@ define void @or_zext_two_blocks(<4 x i16> %x) {
; CHECK-SAME: <4 x i16> [[X:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[A:%.*]] = zext <4 x i16> [[X]] to <4 x i32>
-; CHECK-NEXT: [[TMP0:%.*]] = call i16 @llvm.vector.reduce.umax.v4i16(<4 x i16> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[TMP0]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = icmp eq <4 x i16> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP0]])
; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[EXIT:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: call void @foo(<4 x i32> [[A]])
@@ -648,8 +648,8 @@ define void @or_shl_two_blocks(<4 x i32> %x, <4 x i32> %y) {
; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]]) {
; CHECK-NEXT: [[ENTRY:.*:]]
; CHECK-NEXT: [[A:%.*]] = shl nuw <4 x i32> [[X]], [[Y]]
-; CHECK-NEXT: [[RED:%.*]] = call i32 @llvm.vector.reduce.umax.v4i32(<4 x i32> [[X]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[RED]], 0
+; CHECK-NEXT: [[TMP0:%.*]] = icmp eq <4 x i32> [[X]], zeroinitializer
+; CHECK-NEXT: [[CMP:%.*]] = call i1 @llvm.vector.reduce.and.v4i1(<4 x i1> [[TMP0]])
; CHECK-NEXT: br i1 [[CMP]], label %[[THEN:.*]], label %[[EXIT:.*]]
; CHECK: [[THEN]]:
; CHECK-NEXT: call void @foo(<4 x i32> [[A]])
>From ea903cf4c09c6fca7a9352fa226fa45e003693bc Mon Sep 17 00:00:00 2001
From: Hanbum Park <kese111 at gmail.com>
Date: Thu, 25 Jun 2026 23:46:57 +0900
Subject: [PATCH 3/3] add debug message
---
llvm/lib/Transforms/Vectorize/VectorCombine.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
index 8a52cbba8ad84..ef467b4c91aff 100644
--- a/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
+++ b/llvm/lib/Transforms/Vectorize/VectorCombine.cpp
@@ -4659,6 +4659,9 @@ bool VectorCombine::foldReductionZeroTest(Instruction &I) {
NewCost += TTI.getArithmeticReductionCost(
getArithmeticReductionInstruction(NewIID), CmpTy, std::nullopt, CostKind);
+ LLVM_DEBUG(dbgs() << "Found a reduction zero test: " << I << "\n OldCost: "
+ << OldCost << " vs NewCost: " << NewCost << "\n");
+
if (!OldCost.isValid() || !NewCost.isValid() || NewCost > OldCost)
return false;
More information about the llvm-commits
mailing list