Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -2570,6 +2570,21 @@ match(TrueVal, m_Specific(B)) && match(FalseVal, m_Zero())) return replaceOperand(SI, 0, A); + if (isGuaranteedNotToBeUndefOrPoison(FalseVal)) { + Value *C; + // select (~a | c), a, b -> and a, (or c, b) + if (match(CondVal, m_Or(m_Not(m_Value(TrueVal)), m_Value(C)))) + return BinaryOperator::CreateAnd(TrueVal, + Builder.CreateOr(C, FalseVal)); + } + if (isGuaranteedNotToBeUndefOrPoison(TrueVal)) { + Value *C; + // select (~c & b), a, b -> and b, (or a, c) + if (match(CondVal, m_And(m_Not(m_Value(C)), m_Value(FalseVal)))) + return BinaryOperator::CreateAnd(FalseVal, + Builder.CreateOr(C, TrueVal)); + } + if (!SelType->isVectorTy()) { if (Value *S = simplifyWithOpReplaced(TrueVal, CondVal, One, SQ, /* AllowRefinement */ true)) Index: llvm/test/Transforms/InstCombine/select-and-or.ll =================================================================== --- llvm/test/Transforms/InstCombine/select-and-or.ll +++ llvm/test/Transforms/InstCombine/select-and-or.ll @@ -448,3 +448,27 @@ %C15 = select i1 %not.L, i1 true, i1 xor (i1 and (i1 icmp eq (i16* getelementptr inbounds (i16, i16* @g2, i64 1), i16* @g1), i1 icmp ne (i16* getelementptr inbounds (i16, i16* @g2, i64 1), i16* @g1)), i1 true) ret i1 %C15 } + +define i1 @and_or1(i1 %a, i1 noundef %b, i1 %c) { +; CHECK-LABEL: @and_or1( +; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[C:%.*]], [[B:%.*]] +; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[A:%.*]] +; CHECK-NEXT: ret i1 [[R]] +; + %nota = xor i1 %a, true + %cond = or i1 %nota, %c + %r = select i1 %cond, i1 %a, i1 %b + ret i1 %r +} + +define i1 @and_or2(i1 noundef %a, i1 %b, i1 %c) { +; CHECK-LABEL: @and_or2( +; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[C:%.*]], [[A:%.*]] +; CHECK-NEXT: [[R:%.*]] = and i1 [[TMP1]], [[B:%.*]] +; CHECK-NEXT: ret i1 [[R]] +; + %notc = xor i1 %c, true + %cond = and i1 %notc, %b + %r = select i1 %cond, i1 %a, i1 %b + ret i1 %r +}