diff options
author | Sanjay Patel <spatel@rotateright.com> | 2021-04-08 14:29:33 -0400 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2021-04-08 14:37:39 -0400 |
commit | 5094e1279eb2e168bf6818b368bf6ff4835de2bc (patch) | |
tree | 2a1bd752d18f7a94b2a05d4e2cceee9e8fd4e9a6 /llvm/lib | |
parent | c52dbdbc33b998e43edbc21b6c150bda5f5516a2 (diff) | |
download | llvm-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.cpp | 16 |
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: { |