[llvm] [InstCombine] Canonicalize the fcmp range check idiom into `fabs + fcmp` (PR #76367)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 22 05:31:17 PST 2024


================
@@ -1419,6 +1419,45 @@ Value *InstCombinerImpl::foldLogicOfFCmps(FCmpInst *LHS, FCmpInst *RHS,
     }
   }
 
+  // Canonicalize the range check idiom:
+  // and (fcmp olt/ole/ult/ule x, C), (fcmp ogt/oge/ugt/uge x, -C)
+  // --> fabs(x) olt/ole/ult/ule C
+  // or  (fcmp ogt/oge/ugt/uge x, C), (fcmp olt/ole/ult/ule x, -C)
+  // --> fabs(x) ogt/oge/ugt/uge C
+  // TODO: Generalize to handle a negated variable operand?
+  const APFloat *LHSC, *RHSC;
+  if (LHS0 == RHS0 && LHS->hasOneUse() && RHS->hasOneUse() &&
+      FCmpInst::getSwappedPredicate(PredL) == PredR &&
+      match(LHS1, m_APFloatAllowUndef(LHSC)) &&
+      match(RHS1, m_APFloatAllowUndef(RHSC)) &&
+      LHSC->bitwiseIsEqual(neg(*RHSC))) {
----------------
dtcxzyw wrote:

Alive2 doesn't complain about NaNs.
If both constants are QNaNs:
```
and/or (ordered fcmp1 X, QNaN), (ordered fcmp2 X, -QNaN)
== and/or false, false
== false == ordered fcmp fabs(X), QNaN

and/or (unordered fcmp1 X, QNaN), (unordered fcmp2 X, -QNaN)
== and/or true, true
== true == unordered fcmp fabs(X), QNaN
```


  


https://github.com/llvm/llvm-project/pull/76367


More information about the llvm-commits mailing list