Index: lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineSelect.cpp +++ lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -651,11 +651,31 @@ return ReplaceInstUsesWith(Outer, C); } - // TODO: MIN(MIN(A, 23), 97) + // MIN(MIN(A, 23), 97) -> MIN(A, 23) + // MAX(MAX(A, 97), 23) -> MAX(A, 97) + if (SPF1 == SPF2 && isa(B) && isa(C)) { + unsigned short Pred = ICmpInst::BAD_ICMP_PREDICATE; + if (SPF1 == SPF_SMIN) + Pred = ICmpInst::ICMP_SLE; + if (SPF1 == SPF_UMIN) + Pred = ICmpInst::ICMP_ULE; + if (SPF1 == SPF_SMAX) + Pred = ICmpInst::ICMP_SGE; + if (SPF1 == SPF_UMAX) + Pred = ICmpInst::ICMP_UGE; + + if (Pred != ICmpInst::BAD_ICMP_PREDICATE) { + Constant *B1 = cast(B); + Constant *C1 = cast(C); + Constant *IsCPredB = ConstantExpr::getICmp(Pred, C1, B1); + if (IsCPredB && IsCPredB->isZeroValue()) { + return ReplaceInstUsesWith(Outer, Inner); + } + } + } return nullptr; } - /// foldSelectICmpAnd - If one of the constants is zero (we know they can't /// both be) and we have an icmp instruction with zero, and we have an 'and' /// with the non-constant value and a power of two we can turn the select Index: test/Transforms/InstCombine/select.ll =================================================================== --- test/Transforms/InstCombine/select.ll +++ test/Transforms/InstCombine/select.ll @@ -1031,3 +1031,51 @@ ; CHECK: lshr exact i32 %2, 1 ; CHECK: xor i32 %3, 42 } + +; SMIN(SMIN(X, 11), 92) -> SMIN(X, 11) +define i32 @test68(i32 %x) { +entry: + %cmp = icmp slt i32 11, %x + %cond = select i1 %cmp, i32 11, i32 %x + %cmp3 = icmp slt i32 92, %cond + %cond3 = select i1 %cmp3, i32 92, i32 %cond + ret i32 %cond3 +; CHECK-LABEL: @test68( +; CHECK: ret i32 %cond +} + +; MIN(MIN(X, 24), 83) -> SMIN(X, 24) +define i32 @test69(i32 %x) { +entry: + %cmp = icmp ult i32 24, %x + %cond = select i1 %cmp, i32 24, i32 %x + %cmp3 = icmp ult i32 83, %cond + %cond3 = select i1 %cmp3, i32 83, i32 %cond + ret i32 %cond3 +; CHECK-LABEL: @test69( +; CHECK: ret i32 %cond +} + +; SMAX(SMAX(X, 75), 36) -> SMAX(X, 75) +define i32 @test70(i32 %x) { +entry: + %cmp = icmp slt i32 %x, 75 + %cond = select i1 %cmp, i32 75, i32 %x + %cmp3 = icmp slt i32 %cond, 36 + %cond3 = select i1 %cmp3, i32 36, i32 %cond + ret i32 %cond3 +; CHECK-LABEL: @test70( +; CHECK: ret i32 %cond +} + +; SMAX(SMAX(X, 68), 47) -> SMAX(X, 68) +define i32 @test71(i32 %x) { +entry: + %cmp = icmp ult i32 %x, 68 + %cond = select i1 %cmp, i32 68, i32 %x + %cmp3 = icmp ult i32 %cond, 47 + %cond3 = select i1 %cmp3, i32 47, i32 %cond + ret i32 %cond3 +; CHECK-LABEL: @test71( +; CHECK: ret i32 %cond +} \ No newline at end of file