Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -705,10 +705,16 @@ "Unexpected isUnsigned predicate!"); // Account for swapped form of subtraction: ((a > b) ? b - a : 0). + // Checking for both a-b and a+(-b) as a constant. bool IsNegative = false; - if (match(TrueVal, m_Sub(m_Specific(B), m_Specific(A)))) + const APInt *C; + if (match(TrueVal, m_Sub(m_Specific(B), m_Specific(A))) || + (match(A, m_APInt(C)) && + match(TrueVal, m_Add(m_Specific(B), m_SpecificInt(-*C))))) IsNegative = true; - else if (!match(TrueVal, m_Sub(m_Specific(A), m_Specific(B)))) + else if (!match(TrueVal, m_Sub(m_Specific(A), m_Specific(B))) && + !(match(B, m_APInt(C)) && + match(TrueVal, m_Add(m_Specific(A), m_SpecificInt(-*C))))) return nullptr; // If sub is used anywhere else, we wouldn't be able to eliminate it Index: llvm/test/Transforms/InstCombine/unsigned_saturated_sub.ll =================================================================== --- llvm/test/Transforms/InstCombine/unsigned_saturated_sub.ll +++ llvm/test/Transforms/InstCombine/unsigned_saturated_sub.ll @@ -160,10 +160,8 @@ define i32 @max_sub_ugt_c1(i32 %a) { ; CHECK-LABEL: @max_sub_ugt_c1( -; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 1 -; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -1 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0 -; CHECK-NEXT: ret i32 [[SEL]] +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 1) +; CHECK-NEXT: ret i32 [[TMP1]] ; %cmp = icmp ugt i32 %a, 1 %sub = add i32 %a, -1 @@ -173,10 +171,8 @@ define i32 @max_sub_ugt_c10(i32 %a) { ; CHECK-LABEL: @max_sub_ugt_c10( -; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[A:%.*]], 10 -; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -10 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0 -; CHECK-NEXT: ret i32 [[SEL]] +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 [[A:%.*]], i32 10) +; CHECK-NEXT: ret i32 [[TMP1]] ; %cmp = icmp ugt i32 %a, 10 %sub = add i32 %a, -10 @@ -211,10 +207,9 @@ define i32 @max_sub_ult_c2(i32 %a) { ; CHECK-LABEL: @max_sub_ult_c2( -; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A:%.*]], 2 -; CHECK-NEXT: [[SUB:%.*]] = add i32 [[A]], -2 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 0 -; CHECK-NEXT: ret i32 [[SEL]] +; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.usub.sat.i32(i32 2, i32 [[A:%.*]]) +; CHECK-NEXT: [[TMP2:%.*]] = sub nsw i32 0, [[TMP1]] +; CHECK-NEXT: ret i32 [[TMP2]] ; %cmp = icmp ult i32 %a, 2 %sub = add i32 %a, -2