aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorSanjay Patel <spatel@rotateright.com>2021-04-08 14:29:33 -0400
committerSanjay Patel <spatel@rotateright.com>2021-04-08 14:37:39 -0400
commit5094e1279eb2e168bf6818b368bf6ff4835de2bc (patch)
tree2a1bd752d18f7a94b2a05d4e2cceee9e8fd4e9a6 /llvm/lib
parentc52dbdbc33b998e43edbc21b6c150bda5f5516a2 (diff)
downloadllvm-5094e1279eb2e168bf6818b368bf6ff4835de2bc.zip
llvm-5094e1279eb2e168bf6818b368bf6ff4835de2bc.tar.gz
llvm-5094e1279eb2e168bf6818b368bf6ff4835de2bc.tar.bz2
[InstCombine] fold min/max intrinsic with negated operand to abs
The smax case shows up in https://llvm.org/PR49885 . The others seem unlikely, but we might as well try for uniformity (although that could mean an extra instruction to create "nabs"). smax -- https://alive2.llvm.org/ce/z/8yYaGy smin -- https://alive2.llvm.org/ce/z/0_7zc_ umax -- https://alive2.llvm.org/ce/z/EcsZWs umin -- https://alive2.llvm.org/ce/z/Xw6WvB
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: {