Index: lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineSelect.cpp +++ lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -86,6 +86,16 @@ return (CmpLHS == FalseVal) ? SPF_ABS : SPF_NABS; } } + + // Y >s C ? ~Y : ~C == ~Y (FalseVal)) + if (C1->getType() == C2->getType() && ~C1->getValue() == C2->getValue() && + (match(TrueVal, m_Not(m_Specific(CmpLHS))) || + match(CmpLHS, m_Not(m_Specific(TrueVal))))) { + LHS = TrueVal; + RHS = FalseVal; + return SPF_SMIN; + } } // TODO: (X > 4) ? X : 5 --> (X >= 5) ? X : 5 --> MAX(X, 5) Index: test/Transforms/InstCombine/select.ll =================================================================== --- test/Transforms/InstCombine/select.ll +++ test/Transforms/InstCombine/select.ll @@ -1520,3 +1520,15 @@ %s1 = select i1 %c1, i32 %r0, i32 %s0 ret i32 %s1 } + +define i32 @test_max_of_min(i32 %a) { +; MAX(MIN(%a, -1), -1) == -1 +; CHECK-LABEL: @test_max_of_min( +; CHECK: ret i32 -1 + %not_a = xor i32 %a, -1 + %c0 = icmp sgt i32 %a, 0 + %s0 = select i1 %c0, i32 %not_a, i32 -1 + %c1 = icmp sgt i32 %s0, -1 + %s1 = select i1 %c1, i32 %s0, i32 -1 + ret i32 %s1 +}