[llvm] 4fcfff4 - Use `analyzeKnownBitsFromAndXorOr` in `SimplifyDemandedUseBits` for and/xor/or

Noah Goldstein via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 23 17:52:30 PST 2023


Author: Noah Goldstein
Date: 2023-02-23T19:52:17-06:00
New Revision: 4fcfff4f2de048cdf1d2d2180534b8cf9207cebd

URL: https://github.com/llvm/llvm-project/commit/4fcfff4f2de048cdf1d2d2180534b8cf9207cebd
DIFF: https://github.com/llvm/llvm-project/commit/4fcfff4f2de048cdf1d2d2180534b8cf9207cebd.diff

LOG: Use `analyzeKnownBitsFromAndXorOr` in `SimplifyDemandedUseBits` for and/xor/or

There are extra patterns that have for these three logic operations
that aren't covered in `SimplifyDemandedUseBits`. To avoid duplicating
the code, just use `analyzeKnownBitsFromAndXorOr` in
`SimplifyDemandedUseBits` to get full coverage.

Reviewed By: nikic

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
    llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll
    llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll
    llvm/test/Transforms/InstCombine/ctpop-pow2.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index b8841274a701c..2dbe83264210c 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -195,7 +195,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
     assert(!RHSKnown.hasConflict() && "Bits known to be one AND zero?");
     assert(!LHSKnown.hasConflict() && "Bits known to be one AND zero?");
 
-    Known = LHSKnown & RHSKnown;
+    Known = analyzeKnownBitsFromAndXorOr(cast<Operator>(I), LHSKnown, RHSKnown,
+                                         Depth, DL, &AC, CxtI, &DT);
 
     // If the client is only demanding bits that we know, return the known
     // constant.
@@ -224,7 +225,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
     assert(!RHSKnown.hasConflict() && "Bits known to be one AND zero?");
     assert(!LHSKnown.hasConflict() && "Bits known to be one AND zero?");
 
-    Known = LHSKnown | RHSKnown;
+    Known = analyzeKnownBitsFromAndXorOr(cast<Operator>(I), LHSKnown, RHSKnown,
+                                         Depth, DL, &AC, CxtI, &DT);
 
     // If the client is only demanding bits that we know, return the known
     // constant.
@@ -262,7 +264,8 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
     assert(!RHSKnown.hasConflict() && "Bits known to be one AND zero?");
     assert(!LHSKnown.hasConflict() && "Bits known to be one AND zero?");
 
-    Known = LHSKnown ^ RHSKnown;
+    Known = analyzeKnownBitsFromAndXorOr(cast<Operator>(I), LHSKnown, RHSKnown,
+                                         Depth, DL, &AC, CxtI, &DT);
 
     // If the client is only demanding bits that we know, return the known
     // constant.

diff  --git a/llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll b/llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll
index 3b5602bc44885..7fbc78079c240 100644
--- a/llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll
+++ b/llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll
@@ -209,10 +209,7 @@ define <2 x i1> @add_XY_or_bit0_is_one_fail(<2 x i8> %x, <2 x i8> %C) nounwind {
 ;; These tests are just to check if it can simplify using demanded bits path.
 define <2 x i32> @add_and_eval_vec(<2 x i32> %x, <2 x i32> %C) {
 ; CHECK-LABEL: @add_and_eval_vec(
-; CHECK-NEXT:    [[Y:%.*]] = add <2 x i32> [[X:%.*]], <i32 1, i32 1>
-; CHECK-NEXT:    [[Z:%.*]] = and <2 x i32> [[Y]], [[X]]
-; CHECK-NEXT:    [[B:%.*]] = shl <2 x i32> [[Z]], <i32 31, i32 31>
-; CHECK-NEXT:    ret <2 x i32> [[B]]
+; CHECK-NEXT:    ret <2 x i32> zeroinitializer
 ;
   %y = add <2 x i32> %x, <i32 1, i32 1>
   %z = and <2 x i32> %x, %y
@@ -224,10 +221,7 @@ define <2 x i32> @add_and_eval_vec(<2 x i32> %x, <2 x i32> %C) {
 
 define <2 x i32> @add_xor_eval_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @add_xor_eval_vec(
-; CHECK-NEXT:    [[Y:%.*]] = add <2 x i32> [[X:%.*]], <i32 1, i32 1>
-; CHECK-NEXT:    [[Z:%.*]] = xor <2 x i32> [[Y]], [[X]]
-; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> [[Z]], <i32 1, i32 1>
-; CHECK-NEXT:    ret <2 x i32> [[B]]
+; CHECK-NEXT:    ret <2 x i32> <i32 1, i32 1>
 ;
   %y = add <2 x i32> %x, <i32 1, i32 1>
   %z = xor <2 x i32> %y, %x
@@ -237,10 +231,7 @@ define <2 x i32> @add_xor_eval_vec(<2 x i32> %x) {
 
 define <2 x i32> @add_or_eval_vec(<2 x i32> %x, <2 x i32> %C) {
 ; CHECK-LABEL: @add_or_eval_vec(
-; CHECK-NEXT:    [[Y:%.*]] = add <2 x i32> [[X:%.*]], <i32 1, i32 1>
-; CHECK-NEXT:    [[Z:%.*]] = or <2 x i32> [[Y]], [[X]]
-; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> [[Z]], <i32 1, i32 1>
-; CHECK-NEXT:    ret <2 x i32> [[B]]
+; CHECK-NEXT:    ret <2 x i32> <i32 1, i32 1>
 ;
   %y = add <2 x i32> %x, <i32 1, i32 1>
   %z = or <2 x i32> %y, %x

diff  --git a/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll b/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll
index e3a36fb2387a4..793d6ffa3e34e 100644
--- a/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll
+++ b/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll
@@ -38,11 +38,7 @@ define <2 x i1> @blsmsk_ne_is_true_
diff _vec(<2 x i32> %x) {
 
 define i1 @blsmsk_ge_is_false(i32 %x) {
 ; CHECK-LABEL: @blsmsk_ge_is_false(
-; CHECK-NEXT:    [[X1:%.*]] = or i32 [[X:%.*]], 10
-; CHECK-NEXT:    [[X2:%.*]] = add nsw i32 [[X1]], -1
-; CHECK-NEXT:    [[X3:%.*]] = xor i32 [[X1]], [[X2]]
-; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i32 [[X3]], 7
-; CHECK-NEXT:    ret i1 [[Z]]
+; CHECK-NEXT:    ret i1 false
 ;
   %x1 = or i32 %x, 10
   %x2 = sub i32 %x1, 1
@@ -53,11 +49,7 @@ define i1 @blsmsk_ge_is_false(i32 %x) {
 
 define <2 x i1> @blsmsk_gt_is_false_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @blsmsk_gt_is_false_vec(
-; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 10, i32 10>
-; CHECK-NEXT:    [[X2:%.*]] = add nsw <2 x i32> [[X1]], <i32 -1, i32 -1>
-; CHECK-NEXT:    [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]]
-; CHECK-NEXT:    [[Z:%.*]] = icmp ugt <2 x i32> [[X3]], <i32 8, i32 8>
-; CHECK-NEXT:    ret <2 x i1> [[Z]]
+; CHECK-NEXT:    ret <2 x i1> zeroinitializer
 ;
   %x1 = or <2 x i32> %x, <i32 10, i32 10>
   %x2 = sub <2 x i32> %x1, <i32 1, i32 1>
@@ -90,11 +82,7 @@ define i32 @blsmsk_add_eval(i32 %x) {
 
 define <2 x i32> @blsmsk_add_eval_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @blsmsk_add_eval_vec(
-; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 9, i32 9>
-; CHECK-NEXT:    [[X2:%.*]] = add nsw <2 x i32> [[X1]], <i32 -1, i32 -1>
-; CHECK-NEXT:    [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]]
-; CHECK-NEXT:    [[Z:%.*]] = or <2 x i32> [[X3]], <i32 32, i32 32>
-; CHECK-NEXT:    ret <2 x i32> [[Z]]
+; CHECK-NEXT:    ret <2 x i32> <i32 33, i32 33>
 ;
   %x1 = or <2 x i32> %x, <i32 9, i32 9>
   %x2 = add <2 x i32> %x1, <i32 -1, i32 -1>
@@ -105,11 +93,7 @@ define <2 x i32> @blsmsk_add_eval_vec(<2 x i32> %x) {
 
 define i32 @blsmsk_sub_eval(i32 %x) {
 ; CHECK-LABEL: @blsmsk_sub_eval(
-; CHECK-NEXT:    [[X1:%.*]] = or i32 [[X:%.*]], 9
-; CHECK-NEXT:    [[X2:%.*]] = add i32 [[X1]], 31
-; CHECK-NEXT:    [[X3:%.*]] = xor i32 [[X1]], [[X2]]
-; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X3]], -32
-; CHECK-NEXT:    ret i32 [[Z]]
+; CHECK-NEXT:    ret i32 -31
 ;
   %x1 = or i32 %x, 9
   %x2 = sub i32 %x1, 1
@@ -131,11 +115,7 @@ define i32 @blsmsk_or_eval(i32 %x) {
 
 define <2 x i32> @blsmsk_or_eval_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @blsmsk_or_eval_vec(
-; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 9, i32 9>
-; CHECK-NEXT:    [[X2:%.*]] = add nsw <2 x i32> [[X1]], <i32 -1, i32 -1>
-; CHECK-NEXT:    [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]]
-; CHECK-NEXT:    [[Z:%.*]] = or <2 x i32> [[X3]], <i32 32, i32 32>
-; CHECK-NEXT:    ret <2 x i32> [[Z]]
+; CHECK-NEXT:    ret <2 x i32> <i32 33, i32 33>
 ;
   %x1 = or <2 x i32> %x, <i32 9, i32 9>
   %x2 = add <2 x i32> %x1, <i32 -1, i32 -1>
@@ -228,10 +208,7 @@ define i1 @blsmsk_gt_is_false_assume(i32 %x) {
 ; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 2
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT:    [[X2:%.*]] = add nsw i32 [[X]], -1
-; CHECK-NEXT:    [[X3:%.*]] = xor i32 [[X2]], [[X]]
-; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i32 [[X3]], 8
-; CHECK-NEXT:    ret i1 [[Z]]
+; CHECK-NEXT:    ret i1 false
 ;
   %lb = and i32 %x, 2
   %cmp = icmp ne i32 %lb, 0
@@ -287,10 +264,7 @@ define i32 @blsmsk_sub_eval_assume(i32 %x) {
 ; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 1
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT:    [[X2:%.*]] = add i32 [[X]], 31
-; CHECK-NEXT:    [[X3:%.*]] = xor i32 [[X2]], [[X]]
-; CHECK-NEXT:    [[Z:%.*]] = or i32 [[X3]], -32
-; CHECK-NEXT:    ret i32 [[Z]]
+; CHECK-NEXT:    ret i32 -31
 ;
   %lb = and i32 %x, 1
   %cmp = icmp ne i32 %lb, 0
@@ -391,11 +365,7 @@ define <2 x i1> @blsi_ge_is_false_
diff _vec(<2 x i32> %x) {
 
 define i1 @blsi_gt_is_false(i32 %x) {
 ; CHECK-LABEL: @blsi_gt_is_false(
-; CHECK-NEXT:    [[X1:%.*]] = or i32 [[X:%.*]], 10
-; CHECK-NEXT:    [[X2:%.*]] = sub nsw i32 0, [[X1]]
-; CHECK-NEXT:    [[X3:%.*]] = and i32 [[X1]], [[X2]]
-; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i32 [[X3]], 8
-; CHECK-NEXT:    ret i1 [[Z]]
+; CHECK-NEXT:    ret i1 false
 ;
   %x1 = or i32 %x, 10
   %x2 = sub i32 0, %x1
@@ -429,11 +399,7 @@ define i32 @blsi_sub_eval(i32 %x) {
 
 define <2 x i32> @blsi_sub_eval_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @blsi_sub_eval_vec(
-; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 33, i32 33>
-; CHECK-NEXT:    [[X2:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X1]]
-; CHECK-NEXT:    [[X3:%.*]] = and <2 x i32> [[X1]], [[X2]]
-; CHECK-NEXT:    [[Z:%.*]] = or <2 x i32> [[X3]], <i32 -32, i32 -32>
-; CHECK-NEXT:    ret <2 x i32> [[Z]]
+; CHECK-NEXT:    ret <2 x i32> <i32 -31, i32 -31>
 ;
   %x1 = or <2 x i32> %x, <i32 33, i32 33>
   %x2 = sub <2 x i32> <i32 0, i32 0>, %x1
@@ -455,11 +421,7 @@ define i32 @blsi_or_eval(i32 %x) {
 
 define <2 x i32> @blsi_xor_eval_vec(<2 x i32> %x) {
 ; CHECK-LABEL: @blsi_xor_eval_vec(
-; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 33, i32 33>
-; CHECK-NEXT:    [[X2:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X1]]
-; CHECK-NEXT:    [[X3:%.*]] = and <2 x i32> [[X1]], [[X2]]
-; CHECK-NEXT:    [[Z1:%.*]] = or <2 x i32> [[X3]], <i32 32, i32 32>
-; CHECK-NEXT:    ret <2 x i32> [[Z1]]
+; CHECK-NEXT:    ret <2 x i32> <i32 33, i32 33>
 ;
   %x1 = or <2 x i32> %x, <i32 33, i32 33>
   %x2 = sub <2 x i32> <i32 0, i32 0>, %x1
@@ -555,10 +517,7 @@ define i1 @blsi_ge_is_false_assume(i32 %x) {
 ; CHECK-NEXT:    [[LB:%.*]] = and i32 [[X:%.*]], 4
 ; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[LB]], 0
 ; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])
-; CHECK-NEXT:    [[X2:%.*]] = sub nsw i32 0, [[X]]
-; CHECK-NEXT:    [[X3:%.*]] = and i32 [[X2]], [[X]]
-; CHECK-NEXT:    [[Z:%.*]] = icmp ugt i32 [[X3]], 7
-; CHECK-NEXT:    ret i1 [[Z]]
+; CHECK-NEXT:    ret i1 false
 ;
   %lb = and i32 %x, 4
   %cmp = icmp ne i32 %lb, 0

diff  --git a/llvm/test/Transforms/InstCombine/ctpop-pow2.ll b/llvm/test/Transforms/InstCombine/ctpop-pow2.ll
index f509fd97b295c..6ae5d32254120 100644
--- a/llvm/test/Transforms/InstCombine/ctpop-pow2.ll
+++ b/llvm/test/Transforms/InstCombine/ctpop-pow2.ll
@@ -144,10 +144,7 @@ define <2 x i64> @ctpop_x_and_negx_vec(<2 x i64> %x) {
 
 define <2 x i32> @ctpop_x_and_negx_vec_nz(<2 x i32> %x) {
 ; CHECK-LABEL: @ctpop_x_and_negx_vec_nz(
-; CHECK-NEXT:    [[X1:%.*]] = or <2 x i32> [[X:%.*]], <i32 1, i32 1>
-; CHECK-NEXT:    [[SUB:%.*]] = sub nsw <2 x i32> zeroinitializer, [[X1]]
-; CHECK-NEXT:    [[AND:%.*]] = and <2 x i32> [[X1]], [[SUB]]
-; CHECK-NEXT:    ret <2 x i32> [[AND]]
+; CHECK-NEXT:    ret <2 x i32> <i32 1, i32 1>
 ;
   %x1 = or <2 x i32> %x, <i32 1 ,i32 1>
   %sub = sub <2 x i32> <i32 0 ,i32 0>, %x1


        


More information about the llvm-commits mailing list