[llvm] 167db7c - [InstCombine] Guard against FP min/max in select fold (PR64937)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 24 06:33:21 PDT 2023
Author: Nikita Popov
Date: 2023-08-24T15:29:59+02:00
New Revision: 167db7ce551b2c99fda6427449fb4361eade58bb
URL: https://github.com/llvm/llvm-project/commit/167db7ce551b2c99fda6427449fb4361eade58bb
DIFF: https://github.com/llvm/llvm-project/commit/167db7ce551b2c99fda6427449fb4361eade58bb.diff
LOG: [InstCombine] Guard against FP min/max in select fold (PR64937)
This is partial revert of cbca9ce91c6440f8815742b8a73a27aa81e806e6.
That commit removed the code guarding against min/max SPF patterns,
because those are now canonicalized to min/max intrinsics. However,
this is only true for integer min/max, while FP min/max can not
always be canonicalized to an intrinsic. As such, restore a
simplified version of the guard that handles only the FP case.
Fixes https://github.com/llvm/llvm-project/issues/64937.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
llvm/test/Transforms/InstCombine/minmax-fp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 7acee644dfc75f..9f690fb74872d2 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -1329,6 +1329,21 @@ Instruction *InstCombinerImpl::FoldOpIntoSelect(Instruction &Op, SelectInst *SI,
return nullptr;
}
+ // Test if a FCmpInst instruction is used exclusively by a select as
+ // part of a minimum or maximum operation. If so, refrain from doing
+ // any other folding. This helps out other analyses which understand
+ // non-obfuscated minimum and maximum idioms. And in this case, at
+ // least one of the comparison operands has at least one user besides
+ // the compare (the select), which would often largely negate the
+ // benefit of folding anyway.
+ if (auto *CI = dyn_cast<FCmpInst>(SI->getCondition())) {
+ if (CI->hasOneUse()) {
+ Value *Op0 = CI->getOperand(0), *Op1 = CI->getOperand(1);
+ if ((TV == Op0 && FV == Op1) || (FV == Op0 && TV == Op1))
+ return nullptr;
+ }
+ }
+
// Make sure that one of the select arms constant folds successfully.
Value *NewTV = constantFoldOperationIntoSelectOperand(Op, SI, /*IsTrueArm*/ true);
Value *NewFV = constantFoldOperationIntoSelectOperand(Op, SI, /*IsTrueArm*/ false);
diff --git a/llvm/test/Transforms/InstCombine/minmax-fp.ll b/llvm/test/Transforms/InstCombine/minmax-fp.ll
index 438219b53c27b3..f89e8a18e63440 100644
--- a/llvm/test/Transforms/InstCombine/minmax-fp.ll
+++ b/llvm/test/Transforms/InstCombine/minmax-fp.ll
@@ -453,8 +453,8 @@ define float @minnum_no_nnan(float %a, float %b) {
define float @pr64937_preserve_min_idiom(float %a) {
; CHECK-LABEL: @pr64937_preserve_min_idiom(
; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan olt float [[A:%.*]], 3.276700e+04
-; CHECK-NEXT: [[TMP1:%.*]] = fmul nnan float [[A]], 6.553600e+04
-; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], float [[TMP1]], float 0x41DFFFC000000000
+; CHECK-NEXT: [[SEL:%.*]] = select nnan i1 [[CMP]], float [[A]], float 3.276700e+04
+; CHECK-NEXT: [[RES:%.*]] = fmul nnan float [[SEL]], 6.553600e+04
; CHECK-NEXT: ret float [[RES]]
;
%cmp = fcmp nnan olt float %a, 3.276700e+04
More information about the llvm-commits
mailing list