[llvm] [ValueTracking] Add support for `llvm.vector.reduce.{xor,or,and}` ops. (PR #88320)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 12 13:09:46 PDT 2024
https://github.com/goldsteinn updated https://github.com/llvm/llvm-project/pull/88320
>From 9fe7625a671e8742f56578d972cb3d6daaff8b17 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Wed, 10 Apr 2024 15:29:58 -0500
Subject: [PATCH 1/6] [ValueTracking] Add tests for `computeKnownBits` of
`llvm.vector.reduce.{or,and}`; NFC
---
.../test/Transforms/InstCombine/known-bits.ll | 52 +++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index fea2f647ee2a81..cdc3e991a3fb5a 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -1195,5 +1195,57 @@ define i1 @extract_value_smul_fail(i8 %xx, i8 %yy) {
ret i1 %r
}
+define i8 @known_reduce_or(<2 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_or(
+; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = or <2 x i8> %xx, <i8 5, i8 3>
+ %v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
+ %r = and i8 %v, 1
+ ret i8 %r
+}
+
+define i8 @known_reduce_or_fail(<2 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_or_fail(
+; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 4
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = or <2 x i8> %xx, <i8 5, i8 3>
+ %v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
+ %r = and i8 %v, 4
+ ret i8 %r
+}
+
+define i8 @known_reduce_and(<2 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_and(
+; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = or <2 x i8> %xx, <i8 5, i8 3>
+ %v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
+ %r = and i8 %v, 1
+ ret i8 %r
+}
+
+define i8 @known_reduce_and_fail(<2 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_and_fail(
+; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = or <2 x i8> %xx, <i8 5, i8 3>
+ %v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
+ %r = and i8 %v, 2
+ ret i8 %r
+}
+
declare void @use(i1)
declare void @sink(i8)
>From 24908592f9b98e490636d0a7358624cf10b8ac0d Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Wed, 10 Apr 2024 14:12:50 -0500
Subject: [PATCH 2/6] [ValueTracking] Implement `computeKnownBits` for
`llvm.vector.reduce.{or,and}`
---
llvm/lib/Analysis/ValueTracking.cpp | 6 ++++--
llvm/test/Transforms/InstCombine/known-bits.ll | 10 ++--------
2 files changed, 6 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index b83e7e6769c200..359a9dc7907b7e 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1624,8 +1624,10 @@ static void computeKnownBitsFromOperator(const Operator *I,
computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
Known = KnownBits::ssub_sat(Known, Known2);
break;
- // for min/max reduce, any bit common to each element in the input vec
- // is set in the output.
+ // for min/max/and/or reduce, any bit common to each element in the
+ // input vec is set in the output.
+ case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_or:
case Intrinsic::vector_reduce_umax:
case Intrinsic::vector_reduce_umin:
case Intrinsic::vector_reduce_smax:
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index cdc3e991a3fb5a..ce415dd406c05c 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -1197,10 +1197,7 @@ define i1 @extract_value_smul_fail(i8 %xx, i8 %yy) {
define i8 @known_reduce_or(<2 x i8> %xx) {
; CHECK-LABEL: @known_reduce_or(
-; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
-; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]])
-; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 1
;
%x = or <2 x i8> %xx, <i8 5, i8 3>
%v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
@@ -1223,10 +1220,7 @@ define i8 @known_reduce_or_fail(<2 x i8> %xx) {
define i8 @known_reduce_and(<2 x i8> %xx) {
; CHECK-LABEL: @known_reduce_and(
-; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
-; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]])
-; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 1
;
%x = or <2 x i8> %xx, <i8 5, i8 3>
%v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
>From 7252513bc162faa15c80b19737a4c0ca45bfd9c2 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Wed, 10 Apr 2024 15:30:11 -0500
Subject: [PATCH 3/6] [ValueTracking] Add tests for `computeKnownBits` of
`llvm.vector.reduce.xor`; NFC
---
.../test/Transforms/InstCombine/known-bits.ll | 151 ++++++++++++++++++
1 file changed, 151 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index ce415dd406c05c..3ce9327eb9001b 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -1241,5 +1241,156 @@ define i8 @known_reduce_and_fail(<2 x i8> %xx) {
ret i8 %r
}
+define i8 @known_reduce_xor_even(<2 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_xor_even(
+; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v2i8(<2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = or <2 x i8> %xx, <i8 5, i8 3>
+ %v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x)
+ %r = and i8 %v, 1
+ ret i8 %r
+}
+
+define i8 @known_reduce_xor_even2(<2 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_xor_even2(
+; CHECK-NEXT: [[X:%.*]] = and <2 x i8> [[XX:%.*]], <i8 15, i8 15>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v2i8(<2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 16
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = and <2 x i8> %xx, <i8 15, i8 15>
+ %v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x)
+ %r = and i8 %v, 16
+ ret i8 %r
+}
+
+define i8 @known_reduce_xor_even_fail(<2 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_xor_even_fail(
+; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v2i8(<2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = or <2 x i8> %xx, <i8 5, i8 3>
+ %v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x)
+ %r = and i8 %v, 2
+ ret i8 %r
+}
+
+define i8 @known_reduce_xor_odd(<3 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_xor_odd(
+; CHECK-NEXT: [[X:%.*]] = or <3 x i8> [[XX:%.*]], <i8 5, i8 3, i8 9>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = or <3 x i8> %xx, <i8 5, i8 3, i8 9>
+ %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x)
+ %r = and i8 %v, 1
+ ret i8 %r
+}
+
+define i8 @known_reduce_xor_odd2(<3 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_xor_odd2(
+; CHECK-NEXT: [[X:%.*]] = and <3 x i8> [[XX:%.*]], <i8 15, i8 15, i8 31>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 32
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = and <3 x i8> %xx, <i8 15, i8 15, i8 31>
+ %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x)
+ %r = and i8 %v, 32
+ ret i8 %r
+}
+
+define i8 @known_reduce_xor_odd2_fail(<3 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_xor_odd2_fail(
+; CHECK-NEXT: [[X:%.*]] = and <3 x i8> [[XX:%.*]], <i8 15, i8 15, i8 31>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 16
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = and <3 x i8> %xx, <i8 15, i8 15, i8 31>
+ %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x)
+ %r = and i8 %v, 16
+ ret i8 %r
+}
+
+define i8 @known_reduce_xor_odd_fail(<3 x i8> %xx) {
+; CHECK-LABEL: @known_reduce_xor_odd_fail(
+; CHECK-NEXT: [[X:%.*]] = or <3 x i8> [[XX:%.*]], <i8 5, i8 3, i8 9>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %x = or <3 x i8> %xx, <i8 5, i8 3, i8 9>
+ %v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x)
+ %r = and i8 %v, 2
+ ret i8 %r
+}
+
+define i8 @nonzero_reduce_xor_vscale_even(<vscale x 2 x i8> %xx) {
+; CHECK-LABEL: @nonzero_reduce_xor_vscale_even(
+; CHECK-NEXT: [[X:%.*]] = or <vscale x 2 x i8> [[XX:%.*]], shufflevector (<vscale x 2 x i8> insertelement (<vscale x 2 x i8> poison, i8 1, i64 0), <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer)
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %one = insertelement <vscale x 2 x i8> poison, i8 1, i64 0
+ %ones = shufflevector <vscale x 2 x i8> %one, <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer
+ %x = or <vscale x 2 x i8> %xx, %ones
+ %v = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> %x)
+ %r = and i8 %v, 1
+ ret i8 %r
+}
+
+define i8 @nonzero_reduce_xor_vscale_odd(<vscale x 3 x i8> %xx) {
+; CHECK-LABEL: @nonzero_reduce_xor_vscale_odd(
+; CHECK-NEXT: [[X:%.*]] = or <vscale x 3 x i8> [[XX:%.*]], shufflevector (<vscale x 3 x i8> insertelement (<vscale x 3 x i8> poison, i8 1, i64 0), <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer)
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %one = insertelement <vscale x 3 x i8> poison, i8 1, i64 0
+ %ones = shufflevector <vscale x 3 x i8> %one, <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer
+ %x = or <vscale x 3 x i8> %xx, %ones
+ %v = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> %x)
+ %r = and i8 %v, 1
+ ret i8 %r
+}
+
+define i8 @nonzero_reduce_xor_vscale_even_fail(<vscale x 2 x i8> %xx) {
+; CHECK-LABEL: @nonzero_reduce_xor_vscale_even_fail(
+; CHECK-NEXT: [[X:%.*]] = or <vscale x 2 x i8> [[XX:%.*]], shufflevector (<vscale x 2 x i8> insertelement (<vscale x 2 x i8> poison, i8 1, i64 0), <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer)
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %one = insertelement <vscale x 2 x i8> poison, i8 1, i64 0
+ %ones = shufflevector <vscale x 2 x i8> %one, <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer
+ %x = or <vscale x 2 x i8> %xx, %ones
+ %v = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> %x)
+ %r = and i8 %v, 2
+ ret i8 %r
+}
+
+define i8 @nonzero_reduce_xor_vscale_odd_fail(<vscale x 3 x i8> %xx) {
+; CHECK-LABEL: @nonzero_reduce_xor_vscale_odd_fail(
+; CHECK-NEXT: [[X:%.*]] = or <vscale x 3 x i8> [[XX:%.*]], shufflevector (<vscale x 3 x i8> insertelement (<vscale x 3 x i8> poison, i8 1, i64 0), <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer)
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2
+; CHECK-NEXT: ret i8 [[R]]
+;
+ %one = insertelement <vscale x 3 x i8> poison, i8 1, i64 0
+ %ones = shufflevector <vscale x 3 x i8> %one, <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer
+ %x = or <vscale x 3 x i8> %xx, %ones
+ %v = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> %x)
+ %r = and i8 %v, 2
+ ret i8 %r
+}
+
declare void @use(i1)
declare void @sink(i8)
>From f7af02243137f7be2d6188c9c986e1fa06af085c Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Wed, 10 Apr 2024 14:15:54 -0500
Subject: [PATCH 4/6] [ValueTracking] Implement `computeKnownBits` for
`llvm.vector.reduce.xor`
---
llvm/lib/Analysis/ValueTracking.cpp | 13 ++++++++
.../test/Transforms/InstCombine/known-bits.ll | 30 ++++---------------
2 files changed, 19 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 359a9dc7907b7e..9e27333496adec 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1634,6 +1634,19 @@ static void computeKnownBitsFromOperator(const Operator *I,
case Intrinsic::vector_reduce_smin:
computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
break;
+ case Intrinsic::vector_reduce_xor: {
+ computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
+ // The zeros common to all vecs are zero in the output.
+ // If the number of elements is odd, then the common ones remain. If the
+ // number of elements is even, then the common ones becomes zeros.
+ auto *VecTy = cast<VectorType>(I->getOperand(0)->getType());
+ // Even, so the ones become zeros.
+ if (VecTy->getElementCount().isKnownEven()) {
+ Known.Zero |= Known.One;
+ Known.One.clearAllBits();
+ }
+ break;
+ }
case Intrinsic::umin:
computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index 3ce9327eb9001b..516ab3020dcffc 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -1243,10 +1243,7 @@ define i8 @known_reduce_and_fail(<2 x i8> %xx) {
define i8 @known_reduce_xor_even(<2 x i8> %xx) {
; CHECK-LABEL: @known_reduce_xor_even(
-; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
-; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v2i8(<2 x i8> [[X]])
-; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
;
%x = or <2 x i8> %xx, <i8 5, i8 3>
%v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x)
@@ -1256,10 +1253,7 @@ define i8 @known_reduce_xor_even(<2 x i8> %xx) {
define i8 @known_reduce_xor_even2(<2 x i8> %xx) {
; CHECK-LABEL: @known_reduce_xor_even2(
-; CHECK-NEXT: [[X:%.*]] = and <2 x i8> [[XX:%.*]], <i8 15, i8 15>
-; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v2i8(<2 x i8> [[X]])
-; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 16
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
;
%x = and <2 x i8> %xx, <i8 15, i8 15>
%v = call i8 @llvm.vector.reduce.xor(<2 x i8> %x)
@@ -1282,10 +1276,7 @@ define i8 @known_reduce_xor_even_fail(<2 x i8> %xx) {
define i8 @known_reduce_xor_odd(<3 x i8> %xx) {
; CHECK-LABEL: @known_reduce_xor_odd(
-; CHECK-NEXT: [[X:%.*]] = or <3 x i8> [[XX:%.*]], <i8 5, i8 3, i8 9>
-; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]])
-; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 1
;
%x = or <3 x i8> %xx, <i8 5, i8 3, i8 9>
%v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x)
@@ -1295,10 +1286,7 @@ define i8 @known_reduce_xor_odd(<3 x i8> %xx) {
define i8 @known_reduce_xor_odd2(<3 x i8> %xx) {
; CHECK-LABEL: @known_reduce_xor_odd2(
-; CHECK-NEXT: [[X:%.*]] = and <3 x i8> [[XX:%.*]], <i8 15, i8 15, i8 31>
-; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]])
-; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 32
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
;
%x = and <3 x i8> %xx, <i8 15, i8 15, i8 31>
%v = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> %x)
@@ -1334,10 +1322,7 @@ define i8 @known_reduce_xor_odd_fail(<3 x i8> %xx) {
define i8 @nonzero_reduce_xor_vscale_even(<vscale x 2 x i8> %xx) {
; CHECK-LABEL: @nonzero_reduce_xor_vscale_even(
-; CHECK-NEXT: [[X:%.*]] = or <vscale x 2 x i8> [[XX:%.*]], shufflevector (<vscale x 2 x i8> insertelement (<vscale x 2 x i8> poison, i8 1, i64 0), <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer)
-; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> [[X]])
-; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
;
%one = insertelement <vscale x 2 x i8> poison, i8 1, i64 0
%ones = shufflevector <vscale x 2 x i8> %one, <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer
@@ -1349,10 +1334,7 @@ define i8 @nonzero_reduce_xor_vscale_even(<vscale x 2 x i8> %xx) {
define i8 @nonzero_reduce_xor_vscale_odd(<vscale x 3 x i8> %xx) {
; CHECK-LABEL: @nonzero_reduce_xor_vscale_odd(
-; CHECK-NEXT: [[X:%.*]] = or <vscale x 3 x i8> [[XX:%.*]], shufflevector (<vscale x 3 x i8> insertelement (<vscale x 3 x i8> poison, i8 1, i64 0), <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer)
-; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> [[X]])
-; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 1
;
%one = insertelement <vscale x 3 x i8> poison, i8 1, i64 0
%ones = shufflevector <vscale x 3 x i8> %one, <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer
>From 72b2be816debb9ced7a48a74d461c1e3d96d0c29 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Thu, 11 Apr 2024 11:18:33 -0500
Subject: [PATCH 5/6] [ValueTracking] Add tests for `isKnownNonZero` of
`llvm.vector.reduce.or`; NFC
---
.../Transforms/InstSimplify/known-non-zero.ll | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/llvm/test/Transforms/InstSimplify/known-non-zero.ll b/llvm/test/Transforms/InstSimplify/known-non-zero.ll
index d9b8f5eed32390..b0b825efaeee29 100644
--- a/llvm/test/Transforms/InstSimplify/known-non-zero.ll
+++ b/llvm/test/Transforms/InstSimplify/known-non-zero.ll
@@ -377,3 +377,29 @@ define <2 x i1> @insert_nonzero_any_idx_fail(<2 x i8> %xx, i8 %yy, i32 %idx) {
%r = icmp eq <2 x i8> %ins, zeroinitializer
ret <2 x i1> %r
}
+
+define i1 @nonzero_reduce_or(<2 x i8> %xx) {
+; CHECK-LABEL: @nonzero_reduce_or(
+; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[XX:%.*]], <i8 1, i8 1>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[V]], 0
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %x = add nuw <2 x i8> %xx, <i8 1, i8 1>
+ %v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
+ %r = icmp eq i8 %v, 0
+ ret i1 %r
+}
+
+define i1 @nonzero_reduce_or_fail(<2 x i8> %xx) {
+; CHECK-LABEL: @nonzero_reduce_or_fail(
+; CHECK-NEXT: [[X:%.*]] = add nsw <2 x i8> [[XX:%.*]], <i8 1, i8 1>
+; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]])
+; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[V]], 0
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %x = add nsw <2 x i8> %xx, <i8 1, i8 1>
+ %v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
+ %r = icmp eq i8 %v, 0
+ ret i1 %r
+}
>From ed99b2a9720001ee5c6113c946396a2b74b6b194 Mon Sep 17 00:00:00 2001
From: Noah Goldstein <goldstein.w.n at gmail.com>
Date: Thu, 11 Apr 2024 11:19:15 -0500
Subject: [PATCH 6/6] [ValueTracking] Implement `isKnownNonZero` for
`llvm.vector.reduce.or`
---
llvm/lib/Analysis/ValueTracking.cpp | 3 ++-
llvm/test/Transforms/InstSimplify/known-non-zero.ll | 5 +----
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9e27333496adec..bb9261ea46a761 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2916,7 +2916,8 @@ static bool isKnownNonZeroFromOperator(const Operator *I,
return isNonZeroAdd(DemandedElts, Depth, Q, BitWidth,
II->getArgOperand(0), II->getArgOperand(1),
/*NSW=*/true, /* NUW=*/false);
- // umin/smin/smax/smin of all non-zero elements is always non-zero.
+ // umin/smin/smax/smin/or of all non-zero elements is always non-zero.
+ case Intrinsic::vector_reduce_or:
case Intrinsic::vector_reduce_umax:
case Intrinsic::vector_reduce_umin:
case Intrinsic::vector_reduce_smax:
diff --git a/llvm/test/Transforms/InstSimplify/known-non-zero.ll b/llvm/test/Transforms/InstSimplify/known-non-zero.ll
index b0b825efaeee29..fd2862eb04a24d 100644
--- a/llvm/test/Transforms/InstSimplify/known-non-zero.ll
+++ b/llvm/test/Transforms/InstSimplify/known-non-zero.ll
@@ -380,10 +380,7 @@ define <2 x i1> @insert_nonzero_any_idx_fail(<2 x i8> %xx, i8 %yy, i32 %idx) {
define i1 @nonzero_reduce_or(<2 x i8> %xx) {
; CHECK-LABEL: @nonzero_reduce_or(
-; CHECK-NEXT: [[X:%.*]] = add nuw <2 x i8> [[XX:%.*]], <i8 1, i8 1>
-; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.or.v2i8(<2 x i8> [[X]])
-; CHECK-NEXT: [[R:%.*]] = icmp eq i8 [[V]], 0
-; CHECK-NEXT: ret i1 [[R]]
+; CHECK-NEXT: ret i1 false
;
%x = add nuw <2 x i8> %xx, <i8 1, i8 1>
%v = call i8 @llvm.vector.reduce.or(<2 x i8> %x)
More information about the llvm-commits
mailing list