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
This commit is contained in:
parent
196d3e3965
commit
4fcfff4f2d
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user