[llvm] 6c71707 - [ValueTracking] Implement `computeKnownBits` for `llvm.vector.reduce.xor`

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 14 20:49:21 PDT 2024


Author: Noah Goldstein
Date: 2024-04-14T22:49:06-05:00
New Revision: 6c71707872e4d2f9aef19d0dbd502752b7fdfba0

URL: https://github.com/llvm/llvm-project/commit/6c71707872e4d2f9aef19d0dbd502752b7fdfba0
DIFF: https://github.com/llvm/llvm-project/commit/6c71707872e4d2f9aef19d0dbd502752b7fdfba0.diff

LOG: [ValueTracking] Implement `computeKnownBits` for `llvm.vector.reduce.xor`

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/InstCombine/known-bits.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 359a9dc7907b7e..378e4aa9974e56 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -1634,6 +1634,21 @@ 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.
+        bool EvenCnt = VecTy->getElementCount().isKnownEven();
+        if (EvenCnt)
+          Known.Zero |= Known.One;
+        // Maybe even element count so need to clear ones.
+        if (VecTy->isScalableTy() || EvenCnt)
+          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 fa19adbd5580c3..85a21332b07889 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
@@ -1379,10 +1364,7 @@ define i8 @nonzero_reduce_xor_vscale_even_fail(<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:%.*]] = 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)
-; 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]]
+; CHECK-NEXT:    ret i8 0
 ;
   %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


        


More information about the llvm-commits mailing list