[llvm] 3bd38f6 - [ValueTracking] Add cases for additional ops in `isKnownNonZero`

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 18 11:45:43 PST 2023


Author: Noah Goldstein
Date: 2023-02-18T13:45:15-06:00
New Revision: 3bd38f66398303eb375085dc2681c94c7169f273

URL: https://github.com/llvm/llvm-project/commit/3bd38f66398303eb375085dc2681c94c7169f273
DIFF: https://github.com/llvm/llvm-project/commit/3bd38f66398303eb375085dc2681c94c7169f273.diff

LOG: [ValueTracking] Add cases for additional ops in `isKnownNonZero`

Add cases for the following ops:
    - 0-X            -- https://alive2.llvm.org/ce/z/6C75Li
    - bitreverse(X)  -- https://alive2.llvm.org/ce/z/SGG1q9
    - bswap(X)       -- https://alive2.llvm.org/ce/z/p7pzwh
    - ctpop(X)       -- https://alive2.llvm.org/ce/z/c5y3BC
    - abs(X)         -- https://alive2.llvm.org/ce/z/yxXGz_
                        https://alive2.llvm.org/ce/z/rSRg4K
    - uadd_sat(X, Y) -- https://alive2.llvm.org/ce/z/Zw-y4W
                        https://alive2.llvm.org/ce/z/2NRqRz
                        https://alive2.llvm.org/ce/z/M1OpF8

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D142828

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Analysis/ValueTracking/known-non-zero.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 536d880a8600..bf3b4c94249d 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -2607,6 +2607,12 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
             Q.DL.getTypeSizeInBits(I->getType()).getFixedValue())
       return isKnownNonZero(I->getOperand(0), Depth, Q);
     break;
+  case Instruction::Sub:
+    if (auto *C = dyn_cast<Constant>(I->getOperand(0)))
+      if (C->isNullValue() &&
+          isKnownNonZero(I->getOperand(1), DemandedElts, Depth, Q))
+        return true;
+    break;
   case Instruction::Or:
     // X | Y != 0 if X != 0 or Y != 0.
     return isKnownNonZero(I->getOperand(0), DemandedElts, Depth, Q) ||
@@ -2751,8 +2757,26 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
            isGuaranteedNotToBePoison(I->getOperand(0), Q.AC, Q.CxtI, Q.DT,
                                      Depth);
   case Instruction::Call:
-    if (cast<CallInst>(I)->getIntrinsicID() == Intrinsic::vscale)
-      return true;
+    if (auto *II = dyn_cast<IntrinsicInst>(I)) {
+      switch (II->getIntrinsicID()) {
+      case Intrinsic::abs:
+      case Intrinsic::bitreverse:
+      case Intrinsic::bswap:
+      case Intrinsic::ctpop:
+        if (isKnownNonZero(II->getArgOperand(0), DemandedElts, Depth, Q))
+          return true;
+        break;
+      case Intrinsic::uadd_sat:
+        if (isKnownNonZero(II->getArgOperand(0), DemandedElts, Depth, Q) ||
+            isKnownNonZero(II->getArgOperand(1), DemandedElts, Depth, Q))
+          return true;
+        break;
+      case Intrinsic::vscale:
+        return true;
+      default:
+        break;
+      }
+    }
     break;
   }
 

diff  --git a/llvm/test/Analysis/ValueTracking/known-non-zero.ll b/llvm/test/Analysis/ValueTracking/known-non-zero.ll
index 013aa0709e60..75c13ff3de4e 100644
--- a/llvm/test/Analysis/ValueTracking/known-non-zero.ll
+++ b/llvm/test/Analysis/ValueTracking/known-non-zero.ll
@@ -20,9 +20,7 @@ define i1 @check_neg(i8 %x, i8 %y) {
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
 ; CHECK-NEXT:    [[Z:%.*]] = sub i8 0, [[X]]
 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[Y]], 0
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 [[CMP0]]
 ;
   %ne = icmp ne i8 %x, 0
   call void @llvm.assume(i1 %ne)
@@ -40,9 +38,7 @@ define i1 @check_abs(i8 %x, i8 %y) {
 ; CHECK:       true:
 ; CHECK-NEXT:    [[Z:%.*]] = call i8 @llvm.abs.i8(i8 [[X]], i1 true)
 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[Y]], 0
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 [[CMP0]]
 ; CHECK:       false:
 ; CHECK-NEXT:    ret i1 [[NE]]
 ;
@@ -89,9 +85,7 @@ define i1 @check_bitreverse(i8 %x, i8 %y) {
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
 ; CHECK-NEXT:    [[Z:%.*]] = call i8 @llvm.bitreverse.i8(i8 [[X]])
 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[Y]], 0
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 [[CMP0]]
 ;
   %ne = icmp ne i8 %x, 0
   call void @llvm.assume(i1 %ne)
@@ -108,9 +102,7 @@ define i1 @check_bswap(i16 %x, i16 %y) {
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
 ; CHECK-NEXT:    [[Z:%.*]] = call i16 @llvm.bswap.i16(i16 [[X]])
 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i16 [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i16 [[Y]], 0
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 [[CMP0]]
 ;
   %ne = icmp ne i16 %x, 0
   call void @llvm.assume(i1 %ne)
@@ -130,9 +122,7 @@ define i1 @check_ctpop(i8 %x, i8 %y) {
 ; CHECK:       false:
 ; CHECK-NEXT:    [[Z:%.*]] = call i8 @llvm.ctpop.i8(i8 [[X]])
 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[Y:%.*]]
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[Y]], 0
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 [[CMP0]]
 ;
   %ne = icmp eq i8 %x, 0
   br i1 %ne, label %true, label %false
@@ -152,9 +142,7 @@ define i1 @check_add_sat(i8 %x, i8 %y, i8 %w) {
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[NE]])
 ; CHECK-NEXT:    [[Z:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[X]], i8 [[Y:%.*]])
 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt i8 [[Z]], [[W:%.*]]
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq i8 [[W]], 0
-; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP0]], [[CMP1]]
-; CHECK-NEXT:    ret i1 [[R]]
+; CHECK-NEXT:    ret i1 [[CMP0]]
 ;
   %ne = icmp ne i8 %x, 0
   call void @llvm.assume(i1 %ne)
@@ -170,9 +158,7 @@ define <2 x i1> @check_add_sat_vec(<2 x i8> %x, <2 x i8> %y, <2 x i8> %w) {
 ; CHECK-NEXT:    [[YNZ:%.*]] = or <2 x i8> [[Y:%.*]], <i8 2, i8 1>
 ; CHECK-NEXT:    [[Z:%.*]] = call <2 x i8> @llvm.uadd.sat.v2i8(<2 x i8> [[X:%.*]], <2 x i8> [[YNZ]])
 ; CHECK-NEXT:    [[CMP0:%.*]] = icmp ugt <2 x i8> [[Z]], [[W:%.*]]
-; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq <2 x i8> [[W]], zeroinitializer
-; CHECK-NEXT:    [[R:%.*]] = or <2 x i1> [[CMP0]], [[CMP1]]
-; CHECK-NEXT:    ret <2 x i1> [[R]]
+; CHECK-NEXT:    ret <2 x i1> [[CMP0]]
 ;
   %ynz = or <2 x i8> %y, <i8 2, i8 1>
   %z = call <2 x i8> @llvm.uadd.sat.2xi8(<2 x i8> %x, <2 x i8> %ynz)


        


More information about the llvm-commits mailing list