aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 4d90058..b139960 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -911,6 +911,22 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
}
}
+ // smax(X, -X) --> abs(X)
+ // smin(X, -X) --> -abs(X)
+ // umax(X, -X) --> -abs(X)
+ // umin(X, -X) --> abs(X)
+ if (isKnownNegation(I0, I1)) {
+ // This is some variant of abs(). See if we can propagate 'nsw' to the abs
+ // operation and potentially its negation.
+ bool IntMinIsPoison = isKnownNegation(I0, I1, /* NeedNSW */ true);
+ Value *Abs = Builder.CreateBinaryIntrinsic(
+ Intrinsic::abs, I0,
+ ConstantInt::getBool(II->getContext(), IntMinIsPoison));
+ if (IID == Intrinsic::smin || IID == Intrinsic::umax)
+ Abs = Builder.CreateNeg(Abs, "nabs", /* NUW */ false, IntMinIsPoison);
+ return replaceInstUsesWith(CI, Abs);
+ }
+
break;
}
case Intrinsic::bswap: {