Index: llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -768,9 +768,11 @@ // Canonicalize -1 (saturated result) to true value of the select. Just // swapping the compare operands is legal, because the selected value is the // same in case of equality, so we can interchange u< and u<=. + bool Swapped = false; if (match(FVal, m_AllOnes())) { std::swap(TVal, FVal); std::swap(Cmp0, Cmp1); + Swapped = true; } if (!match(TVal, m_AllOnes())) return nullptr; @@ -801,8 +803,9 @@ return Builder.CreateBinaryIntrinsic( Intrinsic::uadd_sat, BO->getOperand(0), BO->getOperand(1)); } - // The overflow may be detected via the add wrapping round. - if (match(Cmp0, m_c_Add(m_Specific(Cmp1), m_Value(Y))) && + // The overflow may be detected via the add wrapping round. Which is only + // valid if we did not swap the true and false values. + if (!Swapped && match(Cmp0, m_c_Add(m_Specific(Cmp1), m_Value(Y))) && match(FVal, m_c_Add(m_Specific(Cmp1), m_Specific(Y)))) { // ((X + Y) u< X) ? -1 : (X + Y) --> uadd.sat(X, Y) // ((X + Y) u< Y) ? -1 : (X + Y) --> uadd.sat(X, Y) Index: llvm/test/Transforms/InstCombine/saturating-add-sub.ll =================================================================== --- llvm/test/Transforms/InstCombine/saturating-add-sub.ll +++ llvm/test/Transforms/InstCombine/saturating-add-sub.ll @@ -1722,8 +1722,10 @@ define i32 @swapped_select(i32 %x1, i32 %x2) { ; CHECK-LABEL: @swapped_select( -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X2:%.*]], i32 [[X1:%.*]]) -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: [[X14:%.*]] = add i32 [[X1:%.*]], [[X2:%.*]] +; CHECK-NEXT: [[X6:%.*]] = icmp ugt i32 [[X14]], [[X2]] +; CHECK-NEXT: [[X9:%.*]] = select i1 [[X6]], i32 [[X14]], i32 -1 +; CHECK-NEXT: ret i32 [[X9]] ; %x14 = add i32 %x1, %x2 %x6 = icmp ult i32 %x2, %x14 @@ -1733,8 +1735,10 @@ define i32 @swapped_both(i32 %x1, i32 %x2) { ; CHECK-LABEL: @swapped_both( -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.uadd.sat.i32(i32 [[X2:%.*]], i32 [[X1:%.*]]) -; CHECK-NEXT: ret i32 [[TMP1]] +; CHECK-NEXT: [[X14:%.*]] = add i32 [[X1:%.*]], [[X2:%.*]] +; CHECK-NEXT: [[X6:%.*]] = icmp ugt i32 [[X14]], [[X2]] +; CHECK-NEXT: [[X9:%.*]] = select i1 [[X6]], i32 [[X14]], i32 -1 +; CHECK-NEXT: ret i32 [[X9]] ; %x14 = add i32 %x1, %x2 %x6 = icmp ugt i32 %x14, %x2