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,11 @@ assert(!RHSKnown.hasConflict() && "Bits known to be one AND zero?"); assert(!LHSKnown.hasConflict() && "Bits known to be one AND zero?"); - Known = LHSKnown & RHSKnown; + if (const Operator *Op = dyn_cast(I)) + Known = analyzeKnownBitsFromAndXorOr(Op, LHSKnown, RHSKnown, Depth, DL, + &AC, CxtI, &DT); + else + Known = LHSKnown & RHSKnown; // If the client is only demanding bits that we know, return the known // constant. @@ -224,7 +228,11 @@ assert(!RHSKnown.hasConflict() && "Bits known to be one AND zero?"); assert(!LHSKnown.hasConflict() && "Bits known to be one AND zero?"); - Known = LHSKnown | RHSKnown; + if (const Operator *Op = dyn_cast(I)) + Known = analyzeKnownBitsFromAndXorOr(Op, LHSKnown, RHSKnown, Depth, DL, + &AC, CxtI, &DT); + else + Known = LHSKnown | RHSKnown; // If the client is only demanding bits that we know, return the known // constant. @@ -262,7 +270,11 @@ assert(!RHSKnown.hasConflict() && "Bits known to be one AND zero?"); assert(!LHSKnown.hasConflict() && "Bits known to be one AND zero?"); - Known = LHSKnown ^ RHSKnown; + if (const Operator *Op = dyn_cast(I)) + Known = analyzeKnownBitsFromAndXorOr(Op, LHSKnown, RHSKnown, Depth, DL, + &AC, CxtI, &DT); + else + Known = LHSKnown ^ RHSKnown; // 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 @@ -228,10 +228,7 @@ define <2 x i32> @cmp_ne_0_add_and_eval_vec(<2 x i32> %x, <2 x i32> %C) { ; CHECK-LABEL: @cmp_ne_0_add_and_eval_vec( -; CHECK-NEXT: [[Y:%.*]] = add <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[Z:%.*]] = and <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> zeroinitializer ; %C1 = or <2 x i32> %C, %y = add <2 x i32> %C1, %x @@ -242,10 +239,7 @@ define <2 x i32> @cmp_ugt_0_sub_and_eval_vec(<2 x i32> %x, <2 x i32> %C) { ; CHECK-LABEL: @cmp_ugt_0_sub_and_eval_vec( -; CHECK-NEXT: [[Y:%.*]] = add <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[Z:%.*]] = and <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> zeroinitializer ; %C1 = or <2 x i32> %C, %y = sub <2 x i32> %x, %C1 @@ -267,10 +261,7 @@ define <2 x i32> @cmp_eq_0_add_xor_eval_vec(<2 x i32> %x, <2 x i32> %C) { ; CHECK-LABEL: @cmp_eq_0_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> ; %C1 = or <2 x i32> %C, %y = add <2 x i32> %x, %C1 @@ -281,10 +272,7 @@ define <2 x i32> @cmp_ne_0_sub_xor_eval_vec(<2 x i32> %x, <2 x i32> %C) { ; CHECK-LABEL: @cmp_ne_0_sub_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> ; %C1 = or <2 x i32> %C, %y = sub <2 x i32> %x, %C1 @@ -306,10 +294,7 @@ define <2 x i32> @cmp_sgt_0_add_or_eval_vec(<2 x i32> %x, <2 x i32> %C) { ; CHECK-LABEL: @cmp_sgt_0_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> ; %C1 = or <2 x i32> %C, %y = add <2 x i32> %x, %C1 @@ -320,10 +305,7 @@ define <2 x i32> @cmp_ne_0_sub_or_eval_vec(<2 x i32> %x, <2 x i32> %C) { ; CHECK-LABEL: @cmp_ne_0_sub_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> ; %C1 = or <2 x i32> %C, %y = sub <2 x i32> %x, %C1 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 @@ -49,11 +49,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 @@ -64,11 +60,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, @@ -101,11 +93,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, @@ -116,11 +104,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 @@ -142,11 +126,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, @@ -255,10 +235,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 nsw i32 [[X]], -1 -; CHECK-NEXT: [[X3:%.*]] = xor 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, 1 %cmp = icmp ne i32 %lb, 0 @@ -298,10 +275,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 @@ -398,10 +372,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 @@ -635,11 +606,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 @@ -683,11 +650,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 @@ -720,11 +683,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 @@ -886,10 +845,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 @@ -905,10 +861,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:%.*]] = sub nsw i32 0, [[X]] -; CHECK-NEXT: [[X3:%.*]] = and 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, 1 %cmp = icmp ne i32 %lb, 0 diff --git a/llvm/test/Transforms/InstCombine/and-or-xor-lowbit-simplified.ll b/llvm/test/Transforms/InstCombine/and-or-xor-lowbit-simplified.ll --- a/llvm/test/Transforms/InstCombine/and-or-xor-lowbit-simplified.ll +++ b/llvm/test/Transforms/InstCombine/and-or-xor-lowbit-simplified.ll @@ -3,11 +3,7 @@ define i1 @cmp_ne_0_add_and_eval(i32 %x, i32 %C) { ; CHECK-LABEL: @cmp_ne_0_add_and_eval( -; CHECK-NEXT: [[Y:%.*]] = add i32 [[X:%.*]], 1 -; CHECK-NEXT: [[Z:%.*]] = and i32 [[Y]], [[X]] -; CHECK-NEXT: [[B:%.*]] = and i32 [[Z]], 1 -; CHECK-NEXT: [[E:%.*]] = icmp ne i32 [[B]], 0 -; CHECK-NEXT: ret i1 [[E]] +; CHECK-NEXT: ret i1 false ; %C1 = or i32 %C, 131 %y = add i32 %C1, %x @@ -19,11 +15,7 @@ define i1 @cmp_ugt_0_sub_and_eval(i32 %x, i32 %C) { ; CHECK-LABEL: @cmp_ugt_0_sub_and_eval( -; CHECK-NEXT: [[Y:%.*]] = add i32 [[X:%.*]], 1 -; CHECK-NEXT: [[Z:%.*]] = and i32 [[Y]], [[X]] -; CHECK-NEXT: [[B:%.*]] = and i32 [[Z]], 1 -; CHECK-NEXT: [[E:%.*]] = icmp ne i32 [[B]], 0 -; CHECK-NEXT: ret i1 [[E]] +; CHECK-NEXT: ret i1 false ; %C1 = or i32 %C, 129 %y = sub i32 %x, %C1 @@ -263,10 +255,7 @@ define <2 x i1> @cmp_ne_0_add_and_eval_vec(<2 x i32> %x, <2 x i32> %C) { ; CHECK-LABEL: @cmp_ne_0_add_and_eval_vec( -; CHECK-NEXT: [[Y:%.*]] = add <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[Z:%.*]] = and <2 x i32> [[Y]], [[X]] -; CHECK-NEXT: [[E:%.*]] = trunc <2 x i32> [[Z]] to <2 x i1> -; CHECK-NEXT: ret <2 x i1> [[E]] +; CHECK-NEXT: ret <2 x i1> zeroinitializer ; %C1 = or <2 x i32> %C, %y = add <2 x i32> %C1, %x @@ -278,10 +267,7 @@ define <2 x i1> @cmp_ugt_0_sub_and_eval_vec(<2 x i32> %x, <2 x i32> %C) { ; CHECK-LABEL: @cmp_ugt_0_sub_and_eval_vec( -; CHECK-NEXT: [[Y:%.*]] = add <2 x i32> [[X:%.*]], -; CHECK-NEXT: [[Z:%.*]] = and <2 x i32> [[Y]], [[X]] -; CHECK-NEXT: [[E:%.*]] = trunc <2 x i32> [[Z]] to <2 x i1> -; CHECK-NEXT: ret <2 x i1> [[E]] +; CHECK-NEXT: ret <2 x i1> zeroinitializer ; %C1 = or <2 x i32> %C, %y = sub <2 x i32> %x, %C1 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