diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp @@ -195,7 +195,8 @@ 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(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 @@ 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(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 @@ 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(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 --- 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 @@ ;; 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:%.*]], -; CHECK-NEXT: [[Z:%.*]] = and <2 x i32> [[Y]], [[X]] -; CHECK-NEXT: [[B:%.*]] = shl <2 x i32> [[Z]], -; CHECK-NEXT: ret <2 x i32> [[B]] +; CHECK-NEXT: ret <2 x i32> zeroinitializer ; %y = add <2 x i32> %x, %z = and <2 x i32> %x, %y @@ -224,10 +221,7 @@ 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:%.*]], -; CHECK-NEXT: [[Z:%.*]] = xor <2 x i32> [[Y]], [[X]] -; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[Z]], -; CHECK-NEXT: ret <2 x i32> [[B]] +; CHECK-NEXT: ret <2 x i32> ; %y = add <2 x i32> %x, %z = xor <2 x i32> %y, %x @@ -237,10 +231,7 @@ 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:%.*]], -; CHECK-NEXT: [[Z:%.*]] = or <2 x i32> [[Y]], [[X]] -; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[Z]], -; CHECK-NEXT: ret <2 x i32> [[B]] +; CHECK-NEXT: ret <2 x i32> ; %y = add <2 x i32> %x, %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 --- a/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll +++ b/llvm/test/Analysis/ValueTracking/knownbits-bmi-pattern.ll @@ -38,11 +38,7 @@ 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 <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:%.*]], -; CHECK-NEXT: [[X2:%.*]] = add nsw <2 x i32> [[X1]], -; CHECK-NEXT: [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]] -; CHECK-NEXT: [[Z:%.*]] = icmp ugt <2 x i32> [[X3]], -; CHECK-NEXT: ret <2 x i1> [[Z]] +; CHECK-NEXT: ret <2 x i1> zeroinitializer ; %x1 = or <2 x i32> %x, %x2 = sub <2 x i32> %x1, @@ -90,11 +82,7 @@ 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:%.*]], -; CHECK-NEXT: [[X2:%.*]] = add nsw <2 x i32> [[X1]], -; CHECK-NEXT: [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]] -; CHECK-NEXT: [[Z:%.*]] = or <2 x i32> [[X3]], -; CHECK-NEXT: ret <2 x i32> [[Z]] +; CHECK-NEXT: ret <2 x i32> ; %x1 = or <2 x i32> %x, %x2 = add <2 x i32> %x1, @@ -105,11 +93,7 @@ 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 <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:%.*]], -; CHECK-NEXT: [[X2:%.*]] = add nsw <2 x i32> [[X1]], -; CHECK-NEXT: [[X3:%.*]] = xor <2 x i32> [[X2]], [[X1]] -; CHECK-NEXT: [[Z:%.*]] = or <2 x i32> [[X3]], -; CHECK-NEXT: ret <2 x i32> [[Z]] +; CHECK-NEXT: ret <2 x i32> ; %x1 = or <2 x i32> %x, %x2 = add <2 x i32> %x1, @@ -228,10 +208,7 @@ ; 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 @@ ; 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 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 <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:%.*]], -; 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]], -; CHECK-NEXT: ret <2 x i32> [[Z]] +; CHECK-NEXT: ret <2 x i32> ; %x1 = or <2 x i32> %x, %x2 = sub <2 x i32> , %x1 @@ -455,11 +421,7 @@ 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:%.*]], -; 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]], -; CHECK-NEXT: ret <2 x i32> [[Z1]] +; CHECK-NEXT: ret <2 x i32> ; %x1 = or <2 x i32> %x, %x2 = sub <2 x i32> , %x1 @@ -555,10 +517,7 @@ ; 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 --- a/llvm/test/Transforms/InstCombine/ctpop-pow2.ll +++ b/llvm/test/Transforms/InstCombine/ctpop-pow2.ll @@ -144,10 +144,7 @@ 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:%.*]], -; 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> ; %x1 = or <2 x i32> %x, %sub = sub <2 x i32> , %x1