[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