Skip to content

Commit 6c71707

Browse files
committed
[ValueTracking] Implement computeKnownBits for llvm.vector.reduce.xor
1 parent 44b1523 commit 6c71707

File tree

2 files changed

+21
-24
lines changed

2 files changed

+21
-24
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,21 @@ static void computeKnownBitsFromOperator(const Operator *I,
16341634
case Intrinsic::vector_reduce_smin:
16351635
computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
16361636
break;
1637+
case Intrinsic::vector_reduce_xor: {
1638+
computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
1639+
// The zeros common to all vecs are zero in the output.
1640+
// If the number of elements is odd, then the common ones remain. If the
1641+
// number of elements is even, then the common ones becomes zeros.
1642+
auto *VecTy = cast<VectorType>(I->getOperand(0)->getType());
1643+
// Even, so the ones become zeros.
1644+
bool EvenCnt = VecTy->getElementCount().isKnownEven();
1645+
if (EvenCnt)
1646+
Known.Zero |= Known.One;
1647+
// Maybe even element count so need to clear ones.
1648+
if (VecTy->isScalableTy() || EvenCnt)
1649+
Known.One.clearAllBits();
1650+
break;
1651+
}
16371652
case Intrinsic::umin:
16381653
computeKnownBits(I->getOperand(0), Known, Depth + 1, Q);
16391654
computeKnownBits(I->getOperand(1), Known2, Depth + 1, Q);

llvm/test/Transforms/InstCombine/known-bits.ll

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,10 +1243,7 @@ define i8 @known_reduce_and_fail(<2 x i8> %xx) {
12431243

12441244
define i8 @known_reduce_xor_even(<2 x i8> %xx) {
12451245
; CHECK-LABEL: @known_reduce_xor_even(
1246-
; CHECK-NEXT: [[X:%.*]] = or <2 x i8> [[XX:%.*]], <i8 5, i8 3>
1247-
; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v2i8(<2 x i8> [[X]])
1248-
; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
1249-
; CHECK-NEXT: ret i8 [[R]]
1246+
; CHECK-NEXT: ret i8 0
12501247
;
12511248
%x = or <2 x i8> %xx, <i8 5, i8 3>
12521249
%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) {
12561253

12571254
define i8 @known_reduce_xor_even2(<2 x i8> %xx) {
12581255
; CHECK-LABEL: @known_reduce_xor_even2(
1259-
; CHECK-NEXT: [[X:%.*]] = and <2 x i8> [[XX:%.*]], <i8 15, i8 15>
1260-
; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v2i8(<2 x i8> [[X]])
1261-
; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 16
1262-
; CHECK-NEXT: ret i8 [[R]]
1256+
; CHECK-NEXT: ret i8 0
12631257
;
12641258
%x = and <2 x i8> %xx, <i8 15, i8 15>
12651259
%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) {
12821276

12831277
define i8 @known_reduce_xor_odd(<3 x i8> %xx) {
12841278
; CHECK-LABEL: @known_reduce_xor_odd(
1285-
; CHECK-NEXT: [[X:%.*]] = or <3 x i8> [[XX:%.*]], <i8 5, i8 3, i8 9>
1286-
; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]])
1287-
; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
1288-
; CHECK-NEXT: ret i8 [[R]]
1279+
; CHECK-NEXT: ret i8 1
12891280
;
12901281
%x = or <3 x i8> %xx, <i8 5, i8 3, i8 9>
12911282
%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) {
12951286

12961287
define i8 @known_reduce_xor_odd2(<3 x i8> %xx) {
12971288
; CHECK-LABEL: @known_reduce_xor_odd2(
1298-
; CHECK-NEXT: [[X:%.*]] = and <3 x i8> [[XX:%.*]], <i8 15, i8 15, i8 31>
1299-
; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.v3i8(<3 x i8> [[X]])
1300-
; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 32
1301-
; CHECK-NEXT: ret i8 [[R]]
1289+
; CHECK-NEXT: ret i8 0
13021290
;
13031291
%x = and <3 x i8> %xx, <i8 15, i8 15, i8 31>
13041292
%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) {
13341322

13351323
define i8 @nonzero_reduce_xor_vscale_even(<vscale x 2 x i8> %xx) {
13361324
; CHECK-LABEL: @nonzero_reduce_xor_vscale_even(
1337-
; 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)
1338-
; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv2i8(<vscale x 2 x i8> [[X]])
1339-
; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 1
1340-
; CHECK-NEXT: ret i8 [[R]]
1325+
; CHECK-NEXT: ret i8 0
13411326
;
13421327
%one = insertelement <vscale x 2 x i8> poison, i8 1, i64 0
13431328
%ones = shufflevector <vscale x 2 x i8> %one, <vscale x 2 x i8> poison, <vscale x 2 x i32> zeroinitializer
@@ -1379,10 +1364,7 @@ define i8 @nonzero_reduce_xor_vscale_even_fail(<vscale x 2 x i8> %xx) {
13791364

13801365
define i8 @nonzero_reduce_xor_vscale_odd(<vscale x 3 x i8> %xx) {
13811366
; CHECK-LABEL: @nonzero_reduce_xor_vscale_odd(
1382-
; CHECK-NEXT: [[X:%.*]] = and <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)
1383-
; CHECK-NEXT: [[V:%.*]] = call i8 @llvm.vector.reduce.xor.nxv3i8(<vscale x 3 x i8> [[X]])
1384-
; CHECK-NEXT: [[R:%.*]] = and i8 [[V]], 2
1385-
; CHECK-NEXT: ret i8 [[R]]
1367+
; CHECK-NEXT: ret i8 0
13861368
;
13871369
%one = insertelement <vscale x 3 x i8> poison, i8 1, i64 0
13881370
%ones = shufflevector <vscale x 3 x i8> %one, <vscale x 3 x i8> poison, <vscale x 3 x i32> zeroinitializer

0 commit comments

Comments
 (0)