[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