Index: llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp =================================================================== --- llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ llvm/trunk/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -329,13 +329,15 @@ // See if we can prove that the given overflow intrinsic will not overflow. static bool willNotOverflow(IntrinsicInst *II, LazyValueInfo *LVI) { using OBO = OverflowingBinaryOperator; - auto NoWrapOnAddition = [&] (Value *LHS, Value *RHS, unsigned NoWrapKind) { + auto NoWrap = [&] (Instruction::BinaryOps BinOp, unsigned NoWrapKind) { + Value *RHS = II->getOperand(1); ConstantRange RRange = LVI->getConstantRange(RHS, II->getParent(), II); ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion( - BinaryOperator::Add, RRange, NoWrapKind); + BinOp, RRange, NoWrapKind); // As an optimization, do not compute LRange if we do not need it. if (NWRegion.isEmptySet()) return false; + Value *LHS = II->getOperand(0); ConstantRange LRange = LVI->getConstantRange(LHS, II->getParent(), II); return NWRegion.contains(LRange); }; @@ -343,11 +345,13 @@ default: break; case Intrinsic::uadd_with_overflow: - return NoWrapOnAddition(II->getOperand(0), II->getOperand(1), - OBO::NoUnsignedWrap); + return NoWrap(Instruction::Add, OBO::NoUnsignedWrap); case Intrinsic::sadd_with_overflow: - return NoWrapOnAddition(II->getOperand(0), II->getOperand(1), - OBO::NoSignedWrap); + return NoWrap(Instruction::Add, OBO::NoSignedWrap); + case Intrinsic::usub_with_overflow: + return NoWrap(Instruction::Sub, OBO::NoUnsignedWrap); + case Intrinsic::ssub_with_overflow: + return NoWrap(Instruction::Sub, OBO::NoSignedWrap); } return false; } @@ -356,12 +360,17 @@ Value *NewOp = nullptr; switch (II->getIntrinsicID()) { default: - llvm_unreachable("Illegal instruction."); + llvm_unreachable("Unexpected instruction."); case Intrinsic::uadd_with_overflow: case Intrinsic::sadd_with_overflow: NewOp = BinaryOperator::CreateAdd(II->getOperand(0), II->getOperand(1), II->getName(), II); break; + case Intrinsic::usub_with_overflow: + case Intrinsic::ssub_with_overflow: + NewOp = BinaryOperator::CreateSub(II->getOperand(0), II->getOperand(1), + II->getName(), II); + break; } ++NumOverflows; IRBuilder<> B(II); @@ -376,7 +385,7 @@ SmallVector ArgNos; unsigned ArgNo = 0; - if (IntrinsicInst *II = dyn_cast(CS.getInstruction())) { + if (auto *II = dyn_cast(CS.getInstruction())) { if (willNotOverflow(II, LVI)) { processOverflowIntrinsic(II); return true; Index: llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll =================================================================== --- llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll +++ llvm/trunk/test/Transforms/CorrelatedValuePropagation/overflows.ll @@ -13,8 +13,7 @@ define i32 @signed_add(i32 %x, i32 %y) { ; CHECK-LABEL: @signed_add( -; CHECK: @llvm.ssub.with.overflow.i32 -; CHECK: @llvm.ssub.with.overflow.i32 +; CHECK-NOT: @llvm.ssub.with.overflow.i32 ; CHECK: @llvm.sadd.with.overflow.i32 entry: %cmp = icmp sgt i32 %y, 0 @@ -61,7 +60,7 @@ define i32 @unsigned_add(i32 %x, i32 %y) { ; CHECK-LABEL: @unsigned_add( -; CHECK: @llvm.usub.with.overflow.i32 +; CHECK-NOT: @llvm.usub.with.overflow.i32 ; CHECK: @llvm.uadd.with.overflow.i32 entry: %0 = tail call { i32, i1 } @llvm.usub.with.overflow.i32(i32 -1, i32 %y) @@ -203,7 +202,7 @@ define i32 @signed_sub_r1(i32 %x) { ; CHECK-LABEL: @signed_sub_r1( -; CHECK: @llvm.ssub.with.overflow.i32 +; CHECK-NOT: @llvm.ssub.with.overflow.i32 entry: %cmp = icmp eq i32 %x, -2147483648 br i1 %cmp, label %cond.end, label %cond.false @@ -225,7 +224,7 @@ define i32 @unsigned_sub_r1(i32 %x) { ; CHECK-LABEL: @unsigned_sub_r1( -; CHECK: @llvm.usub.with.overflow.i32 +; CHECK-NOT: @llvm.usub.with.overflow.i32 entry: %cmp = icmp eq i32 %x, 0 br i1 %cmp, label %cond.end, label %cond.false @@ -269,7 +268,7 @@ define i32 @signed_sub_rn1(i32 %x) { ; CHECK-LABEL: @signed_sub_rn1( -; CHECK: @llvm.ssub.with.overflow.i32 +; CHECK-NOT: @llvm.ssub.with.overflow.i32 entry: %cmp = icmp eq i32 %x, 2147483647 br i1 %cmp, label %cond.end, label %cond.false @@ -293,7 +292,7 @@ define void @unsigned_loop(i32 %i) { ; CHECK-LABEL: @unsigned_loop( -; CHECK: @llvm.usub.with.overflow.i32 +; CHECK-NOT: @llvm.usub.with.overflow.i32 entry: %cmp3 = icmp eq i32 %i, 0 br i1 %cmp3, label %while.end, label %while.body.preheader