[InstCombine] Clean up saturing math overflow optimizations; NFC

Reduce duplication and make it easier to handle signed
always-overflows conditions in the future.

llvm-svn: 361863
This commit is contained in:
Nikita Popov 2019-05-28 18:59:21 +00:00
parent 2076fb28f1
commit c51cdacab9
1 changed files with 20 additions and 29 deletions

View File

@ -2052,38 +2052,29 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
LLVM_FALLTHROUGH; LLVM_FALLTHROUGH;
case Intrinsic::usub_sat: case Intrinsic::usub_sat:
case Intrinsic::ssub_sat: { case Intrinsic::ssub_sat: {
Value *Arg0 = II->getArgOperand(0); SaturatingInst *SI = cast<SaturatingInst>(II);
Value *Arg1 = II->getArgOperand(1); Value *Arg0 = SI->getLHS();
Value *Arg1 = SI->getRHS();
// Make use of known overflow information. // Make use of known overflow information.
OverflowResult OR; OverflowResult OR = computeOverflow(SI->getBinaryOp(), SI->isSigned(),
switch (IID) { Arg0, Arg1, SI);
default: switch (OR) {
llvm_unreachable("Unexpected intrinsic!"); case OverflowResult::MayOverflow:
case Intrinsic::uadd_sat:
OR = computeOverflowForUnsignedAdd(Arg0, Arg1, II);
if (OR == OverflowResult::NeverOverflows)
return BinaryOperator::CreateNUWAdd(Arg0, Arg1);
if (OR == OverflowResult::AlwaysOverflowsHigh)
return replaceInstUsesWith(*II,
ConstantInt::getAllOnesValue(II->getType()));
break; break;
case Intrinsic::usub_sat: case OverflowResult::NeverOverflows:
OR = computeOverflowForUnsignedSub(Arg0, Arg1, II); if (SI->isSigned())
if (OR == OverflowResult::NeverOverflows) return BinaryOperator::CreateNSW(SI->getBinaryOp(), Arg0, Arg1);
return BinaryOperator::CreateNUWSub(Arg0, Arg1); else
if (OR == OverflowResult::AlwaysOverflowsLow) return BinaryOperator::CreateNUW(SI->getBinaryOp(), Arg0, Arg1);
return replaceInstUsesWith(*II, case OverflowResult::AlwaysOverflowsLow:
if (SI->isSigned()) break; // TODO: Support signed.
return replaceInstUsesWith(*SI,
ConstantInt::getNullValue(II->getType())); ConstantInt::getNullValue(II->getType()));
break; case OverflowResult::AlwaysOverflowsHigh:
case Intrinsic::sadd_sat: if (SI->isSigned()) break; // TODO: Support signed.
if (willNotOverflowSignedAdd(Arg0, Arg1, *II)) return replaceInstUsesWith(*SI,
return BinaryOperator::CreateNSWAdd(Arg0, Arg1); ConstantInt::getAllOnesValue(II->getType()));
break;
case Intrinsic::ssub_sat:
if (willNotOverflowSignedSub(Arg0, Arg1, *II))
return BinaryOperator::CreateNSWSub(Arg0, Arg1);
break;
} }
// ssub.sat(X, C) -> sadd.sat(X, -C) if C != MIN // ssub.sat(X, C) -> sadd.sat(X, -C) if C != MIN