Skip to content

Commit

Permalink
Use analyzeKnownBitsFromAndXorOr in SimplifyDemandedUseBits for a…
Browse files Browse the repository at this point in the history
…nd/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
  • Loading branch information
goldsteinn committed Feb 24, 2023
1 parent 196d3e3 commit 4fcfff4
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 71 deletions.
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
15 changes: 3 additions & 12 deletions llvm/test/Analysis/ValueTracking/knownbits-and-or-xor-lowbit.ll
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
63 changes: 11 additions & 52 deletions llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll
Expand Up @@ -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
Expand All @@ -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>
Expand Down Expand Up @@ -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>
Expand All @@ -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
Expand All @@ -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>
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
5 changes: 1 addition & 4 deletions llvm/test/Transforms/InstCombine/ctpop-pow2.ll
Expand Up @@ -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
Expand Down

0 comments on commit 4fcfff4

Please sign in to comment.