[llvm] 52a1998 - [ValueTracking] Don't accept undef in isKnownNonZero()

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 14 21:54:21 PDT 2024


Author: Nikita Popov
Date: 2024-04-15T13:54:09+09:00
New Revision: 52a1998f15ab0e5b9ff7afa8b92cc714463d5dd8

URL: https://github.com/llvm/llvm-project/commit/52a1998f15ab0e5b9ff7afa8b92cc714463d5dd8
DIFF: https://github.com/llvm/llvm-project/commit/52a1998f15ab0e5b9ff7afa8b92cc714463d5dd8.diff

LOG: [ValueTracking] Don't accept undef in isKnownNonZero()

As the undef can be replaced with a zero value, this is not legal
in the general case. We can only allow poison values. This matches
what the other ValueTracking helpers like computeKnownBits() do.

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/InstCombine/add.ll
    llvm/test/Transforms/InstSimplify/vec-cmp.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 5c2806078261d8..5beea614e332ee 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -3034,7 +3034,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
       // Must be non-zero due to null test above.
       return true;
 
-    // For constant vectors, check that all elements are undefined or known
+    // For constant vectors, check that all elements are poison or known
     // non-zero to determine that the whole vector is known non-zero.
     if (auto *VecTy = dyn_cast<FixedVectorType>(Ty)) {
       for (unsigned i = 0, e = VecTy->getNumElements(); i != e; ++i) {
@@ -3043,7 +3043,7 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts, unsigned Depth,
         Constant *Elt = C->getAggregateElement(i);
         if (!Elt || Elt->isNullValue())
           return false;
-        if (!isa<UndefValue>(Elt) && !isa<ConstantInt>(Elt))
+        if (!isa<PoisonValue>(Elt) && !isa<ConstantInt>(Elt))
           return false;
       }
       return true;

diff  --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll
index 515b80d9d6ea07..408b0c6559b001 100644
--- a/llvm/test/Transforms/InstCombine/add.ll
+++ b/llvm/test/Transforms/InstCombine/add.ll
@@ -3093,10 +3093,14 @@ define <2 x i32> @dec_zext_add_nonzero_vec(<2 x i8> %x) {
   ret <2 x i32> %c
 }
 
+; Negative test: Folding this with undef is not safe.
+
 define <2 x i32> @dec_zext_add_nonzero_vec_undef0(<2 x i8> %x) {
 ; CHECK-LABEL: @dec_zext_add_nonzero_vec_undef0(
 ; CHECK-NEXT:    [[O:%.*]] = or <2 x i8> [[X:%.*]], <i8 8, i8 undef>
-; CHECK-NEXT:    [[C:%.*]] = zext <2 x i8> [[O]] to <2 x i32>
+; CHECK-NEXT:    [[A:%.*]] = add <2 x i8> [[O]], <i8 -1, i8 -1>
+; CHECK-NEXT:    [[B:%.*]] = zext <2 x i8> [[A]] to <2 x i32>
+; CHECK-NEXT:    [[C:%.*]] = add nuw nsw <2 x i32> [[B]], <i32 1, i32 1>
 ; CHECK-NEXT:    ret <2 x i32> [[C]]
 ;
   %o = or <2 x i8> %x, <i8 8, i8 undef>

diff  --git a/llvm/test/Transforms/InstSimplify/vec-cmp.ll b/llvm/test/Transforms/InstSimplify/vec-cmp.ll
index 6391e9aaa04694..dce1261d7031c9 100644
--- a/llvm/test/Transforms/InstSimplify/vec-cmp.ll
+++ b/llvm/test/Transforms/InstSimplify/vec-cmp.ll
@@ -21,13 +21,24 @@ define <2 x i1> @nonzero_vec_nonsplat(<2 x i32> %x) {
 
 define <2 x i1> @nonzero_vec_undef_elt(<2 x i32> %x) {
 ; CHECK-LABEL: @nonzero_vec_undef_elt(
-; CHECK-NEXT:    ret <2 x i1> zeroinitializer
+; CHECK-NEXT:    [[Y:%.*]] = or <2 x i32> [[X:%.*]], <i32 undef, i32 1>
+; CHECK-NEXT:    [[C:%.*]] = icmp eq <2 x i32> [[Y]], zeroinitializer
+; CHECK-NEXT:    ret <2 x i1> [[C]]
 ;
   %y = or <2 x i32> %x, <i32 undef, i32 1>
   %c = icmp eq <2 x i32> %y, zeroinitializer
   ret <2 x i1> %c
 }
 
+define <2 x i1> @nonzero_vec_poison_elt(<2 x i32> %x) {
+; CHECK-LABEL: @nonzero_vec_poison_elt(
+; CHECK-NEXT:    ret <2 x i1> zeroinitializer
+;
+  %y = or <2 x i32> %x, <i32 poison, i32 1>
+  %c = icmp eq <2 x i32> %y, zeroinitializer
+  ret <2 x i1> %c
+}
+
 define <2 x i1> @may_be_zero_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @may_be_zero_vec(
 ; CHECK-NEXT:    [[Y:%.*]] = or <2 x i32> [[X:%.*]], <i32 0, i32 1>
@@ -45,7 +56,7 @@ define <2 x i1> @nonzero_vec_mul_nuw(<2 x i32> %x, <2 x i32> %y) {
 ; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 ;
   %xnz = or <2 x i32> %x, <i32 1, i32 2>
-  %ynz = or <2 x i32> %y, <i32 3, i32 undef>
+  %ynz = or <2 x i32> %y, <i32 3, i32 poison>
   %m = mul nuw <2 x i32> %xnz, %ynz
   %c = icmp eq <2 x i32> %m, zeroinitializer
   ret <2 x i1> %c
@@ -56,7 +67,7 @@ define <2 x i1> @nonzero_vec_mul_nsw(<2 x i32> %x, <2 x i32> %y) {
 ; CHECK-LABEL: @nonzero_vec_mul_nsw(
 ; CHECK-NEXT:    ret <2 x i1> <i1 true, i1 true>
 ;
-  %xnz = or <2 x i32> %x, <i32 undef, i32 2>
+  %xnz = or <2 x i32> %x, <i32 poison, i32 2>
   %ynz = or <2 x i32> %y, <i32 3, i32 4>
   %m = mul nsw <2 x i32> %xnz, %ynz
   %c = icmp ne <2 x i32> %m, zeroinitializer


        


More information about the llvm-commits mailing list