diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2532,19 +2532,30 @@ if (Instruction *I = canonicalizeScalarSelectOfVecs(SI, *this)) return I; - // Canonicalize a one-use integer compare with a non-canonical predicate by - // inverting the predicate and swapping the select operands. This matches a - // compare canonicalization for conditional branches. + // Canonicalize a integer compare with a non-canonical predicate by + // inverting the predicate and swapping the select operands. + // This matches a compare canonicalization for conditional branches. // TODO: Should we do the same for FP compares? CmpInst::Predicate Pred; - if (match(CondVal, m_OneUse(m_ICmp(Pred, m_Value(), m_Value()))) && - !isCanonicalPredicate(Pred)) { - // Swap true/false values and condition. - CmpInst *Cond = cast(CondVal); - Cond->setPredicate(CmpInst::getInversePredicate(Pred)); + if (match(CondVal, m_ICmp(Pred, m_Value(), m_Value())) && + !isCanonicalPredicate(Pred) && + (CondVal->hasOneUse() || + canFreelyInvertAllUsersOf(CondVal, /*IgnoredUser=*/nullptr))) { + ICmpInst* OrigCond = cast(CondVal); + BuilderTy::InsertPointGuard Guard(Builder); + // Set insertion point to right before the OrigCond. + Builder.SetInsertPoint(OrigCond); + Value *CanonicalCond = Builder.CreateICmp( + CmpInst::getInversePredicate(Pred), OrigCond->getOperand(0), + OrigCond->getOperand(1), OrigCond->getName() + ".not"); + Value *NewCond = Builder.CreateNot(CanonicalCond, OrigCond->getName()); + // Replace all uses of OrigCond with NewCond. + Worklist.pushUsersToWorkList(*OrigCond); + OrigCond->replaceAllUsesWith(NewCond); + // And adjust this `select` directly. + SI.setCondition(CanonicalCond); SI.swapValues(); SI.swapProfMetadata(); - Worklist.push(Cond); return &SI; } diff --git a/llvm/test/Transforms/InstCombine/canonicalize-selects-icmp-condition-bittest.ll b/llvm/test/Transforms/InstCombine/canonicalize-selects-icmp-condition-bittest.ll --- a/llvm/test/Transforms/InstCombine/canonicalize-selects-icmp-condition-bittest.ll +++ b/llvm/test/Transforms/InstCombine/canonicalize-selects-icmp-condition-bittest.ll @@ -8,8 +8,8 @@ define i8 @p0(i8 %x, i8 %v0, i8 %v1) { ; CHECK-LABEL: @p0( ; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 -; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0 -; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V1:%.*]], i8 [[V0:%.*]], !prof !0 +; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 +; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]], !prof !0 ; CHECK-NEXT: ret i8 [[R]] ; %t0 = and i8 %x, 1 @@ -20,8 +20,8 @@ define i8 @p1(i8 %x, i8 %v0, i8 %v1) { ; CHECK-LABEL: @p1( ; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 -; CHECK-NEXT: [[T1:%.*]] = icmp eq i8 [[T0]], 0 -; CHECK-NEXT: [[R:%.*]] = select i1 [[T1]], i8 [[V1:%.*]], i8 [[V0:%.*]] +; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 +; CHECK-NEXT: [[R:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]] ; CHECK-NEXT: ret i8 [[R]] ; %t0 = and i8 %x, 1 @@ -51,14 +51,14 @@ ; CHECK-LABEL: @t3( ; CHECK-NEXT: bb0: ; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 -; CHECK-NEXT: [[T1:%.*]] = icmp ne i8 [[T0]], 0 +; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 ; CHECK-NEXT: br i1 [[C:%.*]], label [[BB1:%.*]], label [[BB2:%.*]] ; CHECK: bb1: -; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]] +; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]] ; CHECK-NEXT: store i8 [[R0]], i8* [[OUT:%.*]], align 1 ; CHECK-NEXT: br label [[BB2]] ; CHECK: bb2: -; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1]], i8 [[V2:%.*]], i8 [[V3:%.*]] +; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]] ; CHECK-NEXT: ret i8 [[R1]] ; bb0: @@ -76,10 +76,10 @@ define i8 @t4(i8 %x, i8 %v0, i8 %v1, i8 %v2, i8 %v3, i8* %out) { ; CHECK-LABEL: @t4( ; CHECK-NEXT: [[T0:%.*]] = and i8 [[X:%.*]], 1 -; CHECK-NEXT: [[T1:%.*]] = icmp ne i8 [[T0]], 0 -; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1]], i8 [[V0:%.*]], i8 [[V1:%.*]] +; CHECK-NEXT: [[T1_NOT:%.*]] = icmp eq i8 [[T0]], 0 +; CHECK-NEXT: [[R0:%.*]] = select i1 [[T1_NOT]], i8 [[V1:%.*]], i8 [[V0:%.*]] ; CHECK-NEXT: store i8 [[R0]], i8* [[OUT:%.*]], align 1 -; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1]], i8 [[V2:%.*]], i8 [[V3:%.*]] +; CHECK-NEXT: [[R1:%.*]] = select i1 [[T1_NOT]], i8 [[V3:%.*]], i8 [[V2:%.*]] ; CHECK-NEXT: ret i8 [[R1]] ; %t0 = and i8 %x, 1 diff --git a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll --- a/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll +++ b/llvm/test/Transforms/InstCombine/select-with-bitwise-ops.ll @@ -153,9 +153,9 @@ define i32 @select_icmp_ne_0_and_4096_xor_4096(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_4096_xor_4096( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 4096 @@ -168,9 +168,9 @@ define i32 @select_icmp_ne_0_and_4096_and_not_4096(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_4096_and_not_4096( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -4097 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 4096 @@ -311,9 +311,9 @@ define i32 @select_icmp_ne_0_and_4096_xor_32(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_4096_xor_32( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 32 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 4096 @@ -326,9 +326,9 @@ define i32 @select_icmp_ne_0_and_4096_and_not_32(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_4096_and_not_32( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -33 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 4096 @@ -371,9 +371,9 @@ define i32 @select_icmp_ne_0_and_32_xor_4096(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_32_xor_4096( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 32 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 32 @@ -386,9 +386,9 @@ define i32 @select_icmp_ne_0_and_32_and_not_4096(i32 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_32_and_not_4096( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 32 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -4097 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i32 %x, 32 @@ -401,9 +401,9 @@ define i8 @select_icmp_ne_0_and_1073741824_or_8(i32 %x, i8 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_1073741824_or_8( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1073741824 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i8 [[Y:%.*]], 8 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i8 [[OR]], i8 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i8 [[OR]], i8 [[Y]] ; CHECK-NEXT: ret i8 [[SELECT]] ; %and = and i32 %x, 1073741824 @@ -416,9 +416,9 @@ define i8 @select_icmp_ne_0_and_1073741824_xor_8(i32 %x, i8 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_1073741824_xor_8( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1073741824 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[Y:%.*]], 8 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i8 [[XOR]], i8 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i8 [[XOR]], i8 [[Y]] ; CHECK-NEXT: ret i8 [[SELECT]] ; %and = and i32 %x, 1073741824 @@ -431,9 +431,9 @@ define i8 @select_icmp_ne_0_and_1073741824_and_not_8(i32 %x, i8 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_1073741824_and_not_8( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 1073741824 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i8 [[Y:%.*]], -9 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i8 [[AND2]], i8 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i8 [[AND2]], i8 [[Y]] ; CHECK-NEXT: ret i8 [[SELECT]] ; %and = and i32 %x, 1073741824 @@ -446,9 +446,9 @@ define i32 @select_icmp_ne_0_and_8_or_1073741824(i8 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_8_or_1073741824( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 1073741824 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[OR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i8 %x, 8 @@ -461,9 +461,9 @@ define i32 @select_icmp_ne_0_and_8_xor_1073741824(i8 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_8_xor_1073741824( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 1073741824 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i8 %x, 8 @@ -476,9 +476,9 @@ define i32 @select_icmp_ne_0_and_8_and_not_1073741824(i8 %x, i32 %y) { ; CHECK-LABEL: @select_icmp_ne_0_and_8_and_not_1073741824( ; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], 8 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i8 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -1073741825 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: ret i32 [[SELECT]] ; %and = and i8 %x, 8 @@ -892,9 +892,9 @@ define i32 @no_shift_xor_multiuse_xor(i32 %x, i32 %y) { ; CHECK-LABEL: @no_shift_xor_multiuse_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[XOR]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -909,9 +909,9 @@ define i32 @no_shift_xor_multiuse_and(i32 %x, i32 %y) { ; CHECK-LABEL: @no_shift_xor_multiuse_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -4097 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[AND2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -926,9 +926,9 @@ define i32 @shift_xor_multiuse_or(i32 %x, i32 %y) { ; CHECK-LABEL: @shift_xor_multiuse_or( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[OR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[OR]], i32 [[Y]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[OR]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -943,9 +943,9 @@ define i32 @shift_xor_multiuse_xor(i32 %x, i32 %y) { ; CHECK-LABEL: @shift_xor_multiuse_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[XOR]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -960,9 +960,9 @@ define i32 @shift_xor_multiuse_and(i32 %x, i32 %y) { ; CHECK-LABEL: @shift_xor_multiuse_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -2049 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[AND2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1090,10 +1090,10 @@ define i32 @no_shift_xor_multiuse_cmp(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[AND]], 4096 ; CHECK-NEXT: [[TMP2:%.*]] = or i32 [[TMP1]], [[Y:%.*]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[W:%.*]], i32 [[Z:%.*]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[TMP2]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1109,10 +1109,10 @@ define i32 @no_shift_xor_multiuse_cmp_with_xor(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp_with_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1128,10 +1128,10 @@ define i32 @no_shift_xor_multiuse_cmp_with_and(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp_with_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -4097 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1147,10 +1147,10 @@ define i32 @shift_xor_multiuse_cmp(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[OR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1166,10 +1166,10 @@ define i32 @shift_xor_multiuse_cmp_with_xor(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp_with_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1185,10 +1185,10 @@ define i32 @shift_xor_multiuse_cmp_with_and(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp_with_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -2049 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: ret i32 [[RES]] ; @@ -1330,10 +1330,10 @@ define i32 @no_shift_xor_multiuse_cmp_or(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp_or( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[OR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[OR]] ; CHECK-NEXT: ret i32 [[RES2]] @@ -1351,10 +1351,10 @@ define i32 @no_shift_xor_multiuse_cmp_xor(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 4096 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[XOR]] ; CHECK-NEXT: ret i32 [[RES2]] @@ -1372,10 +1372,10 @@ define i32 @no_shift_xor_multiuse_cmp_and(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @no_shift_xor_multiuse_cmp_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], -4097 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[AND2]] ; CHECK-NEXT: ret i32 [[RES2]] @@ -1393,10 +1393,10 @@ define i32 @shift_xor_multiuse_cmp_or(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp_or( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[OR:%.*]] = or i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[OR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[OR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[OR]] ; CHECK-NEXT: ret i32 [[RES2]] @@ -1414,10 +1414,10 @@ define i32 @shift_xor_multiuse_cmp_xor(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp_xor( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[XOR]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[XOR]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[XOR]] ; CHECK-NEXT: ret i32 [[RES2]] @@ -1435,10 +1435,10 @@ define i32 @shift_xor_multiuse_cmp_and(i32 %x, i32 %y, i32 %z, i32 %w) { ; CHECK-LABEL: @shift_xor_multiuse_cmp_and( ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 4096 -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], 0 +; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[AND]], 0 ; CHECK-NEXT: [[AND2:%.*]] = and i32 [[Y:%.*]], 2048 -; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND2]] -; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP]], i32 [[Z:%.*]], i32 [[W:%.*]] +; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP_NOT]], i32 [[AND2]], i32 [[Y]] +; CHECK-NEXT: [[SELECT2:%.*]] = select i1 [[CMP_NOT]], i32 [[W:%.*]], i32 [[Z:%.*]] ; CHECK-NEXT: [[RES:%.*]] = mul i32 [[SELECT]], [[SELECT2]] ; CHECK-NEXT: [[RES2:%.*]] = mul i32 [[RES]], [[AND2]] ; CHECK-NEXT: ret i32 [[RES2]]