diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 173faa32a3878..82700fb8be8fb 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -8139,6 +8139,11 @@ static SelectPatternResult matchClamp(CmpInst::Predicate Pred, if (match(FalseVal, m_UMax(m_Specific(CmpLHS), m_APInt(C2))) && C1->ugt(*C2) && Pred == CmpInst::ICMP_UGT) return {SPF_UMIN, SPNB_NA, false}; + + // (X SMAX(UMIN(X, C2), C1) + if (match(FalseVal, m_UMin(m_Specific(CmpLHS), m_APInt(C2))) && + C1->slt(*C2) && Pred == CmpInst::ICMP_SLT) + return {SPF_SMAX, SPNB_NA, false}; } return {SPF_UNKNOWN, SPNB_NA, false}; } diff --git a/llvm/test/Transforms/InstCombine/clamp-with-unsigned-minmax.ll b/llvm/test/Transforms/InstCombine/clamp-with-unsigned-minmax.ll new file mode 100644 index 0000000000000..a53b739fbd009 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/clamp-with-unsigned-minmax.ll @@ -0,0 +1,13 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +define i32 @clamp_pattern_with_signed_icmp_unsigned_min(i32 %input ) { +; CHECK-LABEL: @clamp_pattern_with_signed_icmp_unsigned_min( +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.umin.i32(i32 [[INPUT:%.*]], i32 255) +; CHECK-NEXT: ret i32 [[TMP1]] +; + %1 = icmp slt i32 %input, 0 + %2 = tail call i32 @llvm.umin.i32(i32 %input, i32 255) + %3 = select i1 %1, i32 0, i32 %2 + ret i32 %3 +}