diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index 6cc241781d112..19bf81137aab7 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -3347,12 +3347,6 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS, } } - // handle (roughly): - // (icmp ne (A & B), C) | (icmp ne (A & D), E) - // (icmp eq (A & B), C) & (icmp eq (A & D), E) - if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, IsAnd, IsLogical, Builder, Q)) - return V; - if (Value *V = foldAndOrOfICmpEqConstantAndICmp(LHS, RHS, IsAnd, IsLogical, Builder)) return V; @@ -3527,6 +3521,13 @@ Value *InstCombinerImpl::foldBooleanAndOr(Value *LHS, Value *RHS, if (!LHS->getType()->isIntOrIntVectorTy(1)) return nullptr; + // handle (roughly): + // (icmp ne (A & B), C) | (icmp ne (A & D), E) + // (icmp eq (A & B), C) & (icmp eq (A & D), E) + if (Value *V = foldLogOpOfMaskedICmps(LHS, RHS, IsAnd, IsLogical, Builder, + SQ.getWithInstruction(&I))) + return V; + if (auto *LHSCmp = dyn_cast(LHS)) if (auto *RHSCmp = dyn_cast(RHS)) if (Value *Res = foldAndOrOfICmps(LHSCmp, RHSCmp, I, IsAnd, IsLogical)) diff --git a/llvm/test/Transforms/InstCombine/eq-of-parts.ll b/llvm/test/Transforms/InstCombine/eq-of-parts.ll index d07c2e6a5be52..4dc502788db47 100644 --- a/llvm/test/Transforms/InstCombine/eq-of-parts.ll +++ b/llvm/test/Transforms/InstCombine/eq-of-parts.ll @@ -1455,10 +1455,8 @@ define i1 @and_trunc_i1(i8 %a1, i8 %a2) { define i1 @and_trunc_i1_wrong_const(i8 %a1, i8 %a2) { ; CHECK-LABEL: @and_trunc_i1_wrong_const( ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[A1:%.*]], [[A2:%.*]] -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i8 [[XOR]], 4 -; CHECK-NEXT: [[LOBIT:%.*]] = trunc i8 [[XOR]] to i1 -; CHECK-NEXT: [[LOBIT_INV:%.*]] = xor i1 [[LOBIT]], true -; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[LOBIT_INV]] +; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[XOR]], -3 +; CHECK-NEXT: [[AND:%.*]] = icmp eq i8 [[TMP1]], 0 ; CHECK-NEXT: ret i1 [[AND]] ; %xor = xor i8 %a1, %a2 diff --git a/llvm/test/Transforms/InstCombine/onehot_merge.ll b/llvm/test/Transforms/InstCombine/onehot_merge.ll index e60edc7315d46..33e39d78e1ce4 100644 --- a/llvm/test/Transforms/InstCombine/onehot_merge.ll +++ b/llvm/test/Transforms/InstCombine/onehot_merge.ll @@ -1163,10 +1163,9 @@ define i1 @two_types_of_bittest(i8 %x, i8 %c) { define i1 @trunc_bittest_and_icmp_bittest(i8 %x, i8 %c) { ; CHECK-LABEL: @trunc_bittest_and_icmp_bittest( ; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[C:%.*]] -; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X:%.*]] to i1 -; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[T0]] -; CHECK-NEXT: [[ICMP2:%.*]] = icmp ne i8 [[AND]], 0 -; CHECK-NEXT: [[RET:%.*]] = and i1 [[ICMP2]], [[TRUNC]] +; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[T0]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]] +; CHECK-NEXT: [[RET:%.*]] = icmp eq i8 [[TMP2]], [[TMP1]] ; CHECK-NEXT: ret i1 [[RET]] ; %t0 = shl i8 1, %c @@ -1180,11 +1179,9 @@ define i1 @trunc_bittest_and_icmp_bittest(i8 %x, i8 %c) { define i1 @trunc_bittest_or_icmp_bittest(i8 %x, i8 %c) { ; CHECK-LABEL: @trunc_bittest_or_icmp_bittest( ; CHECK-NEXT: [[T0:%.*]] = shl nuw i8 1, [[C:%.*]] -; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[X:%.*]] to i1 -; CHECK-NEXT: [[AND:%.*]] = and i8 [[X]], [[T0]] -; CHECK-NEXT: [[ICMP2:%.*]] = icmp eq i8 [[AND]], 0 -; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[TRUNC]], true -; CHECK-NEXT: [[RET:%.*]] = or i1 [[ICMP2]], [[NOT]] +; CHECK-NEXT: [[TMP1:%.*]] = or i8 [[T0]], 1 +; CHECK-NEXT: [[TMP2:%.*]] = and i8 [[X:%.*]], [[TMP1]] +; CHECK-NEXT: [[RET:%.*]] = icmp ne i8 [[TMP2]], [[TMP1]] ; CHECK-NEXT: ret i1 [[RET]] ; %t0 = shl i8 1, %c