From 5094e1279eb2e168bf6818b368bf6ff4835de2bc Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Thu, 8 Apr 2021 14:29:33 -0400 Subject: [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 --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp') 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: { -- cgit v1.1