diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index dc1e904c3f57e8..dd03f98c5be785 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -3281,6 +3281,10 @@ InstCombinerImpl::foldExtractOfOverflowIntrinsic(ExtractValueInst &EV) { assert(*EV.idx_begin() == 1 && "Unexpected extract index for overflow inst"); + // (usub LHS, RHS) overflows when LHS is unsigned-less-than RHS. + if (OvID == Intrinsic::usub_with_overflow) + return new ICmpInst(ICmpInst::ICMP_ULT, WO->getLHS(), WO->getRHS()); + // If only the overflow result is used, and the right hand side is a // constant (or constant splat), we can remove the intrinsic by directly // checking for overflow. diff --git a/llvm/test/Transforms/InstCombine/usubo.ll b/llvm/test/Transforms/InstCombine/usubo.ll index dc21a4f5506446..d45c30a09ad382 100644 --- a/llvm/test/Transforms/InstCombine/usubo.ll +++ b/llvm/test/Transforms/InstCombine/usubo.ll @@ -6,8 +6,7 @@ declare { i8, i1 } @llvm.usub.with.overflow.i8(i8, i8) define i1 @test_generic(i64 %a, i64 %b) { ; CHECK-LABEL: @test_generic( -; CHECK-NEXT: [[RES:%.*]] = tail call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[A:%.*]], i64 [[B:%.*]]) -; CHECK-NEXT: [[OVERFLOW:%.*]] = extractvalue { i64, i1 } [[RES]], 1 +; CHECK-NEXT: [[OVERFLOW:%.*]] = icmp ult i64 [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: ret i1 [[OVERFLOW]] ; %res = tail call { i64, i1 } @llvm.usub.with.overflow.i64(i64 %a, i64 %b)