[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;
case Intrinsic::usub_sat:
case Intrinsic::ssub_sat: {
Value *Arg0 = II->getArgOperand(0);
Value *Arg1 = II->getArgOperand(1);
SaturatingInst *SI = cast<SaturatingInst>(II);
Value *Arg0 = SI->getLHS();
Value *Arg1 = SI->getRHS();
// Make use of known overflow information.
OverflowResult OR;
switch (IID) {
default:
llvm_unreachable("Unexpected intrinsic!");
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()));
OverflowResult OR = computeOverflow(SI->getBinaryOp(), SI->isSigned(),
Arg0, Arg1, SI);
switch (OR) {
case OverflowResult::MayOverflow:
break;
case Intrinsic::usub_sat:
OR = computeOverflowForUnsignedSub(Arg0, Arg1, II);
if (OR == OverflowResult::NeverOverflows)
return BinaryOperator::CreateNUWSub(Arg0, Arg1);
if (OR == OverflowResult::AlwaysOverflowsLow)
return replaceInstUsesWith(*II,
case OverflowResult::NeverOverflows:
if (SI->isSigned())
return BinaryOperator::CreateNSW(SI->getBinaryOp(), Arg0, Arg1);
else
return BinaryOperator::CreateNUW(SI->getBinaryOp(), Arg0, Arg1);
case OverflowResult::AlwaysOverflowsLow:
if (SI->isSigned()) break; // TODO: Support signed.
return replaceInstUsesWith(*SI,
ConstantInt::getNullValue(II->getType()));
break;
case Intrinsic::sadd_sat:
if (willNotOverflowSignedAdd(Arg0, Arg1, *II))
return BinaryOperator::CreateNSWAdd(Arg0, Arg1);
break;
case Intrinsic::ssub_sat:
if (willNotOverflowSignedSub(Arg0, Arg1, *II))
return BinaryOperator::CreateNSWSub(Arg0, Arg1);
break;
case OverflowResult::AlwaysOverflowsHigh:
if (SI->isSigned()) break; // TODO: Support signed.
return replaceInstUsesWith(*SI,
ConstantInt::getAllOnesValue(II->getType()));
}
// ssub.sat(X, C) -> sadd.sat(X, -C) if C != MIN