[llvm] [InstCombine] Fold select with signbit idiom into fabs (PR #76342)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 22 03:53:48 PST 2024


================
@@ -2763,6 +2763,41 @@ static Instruction *foldSelectWithFCmpToFabs(SelectInst &SI,
     }
   }
 
+  // Match select with (icmp slt (bitcast X to int), 0)
+  //                or (icmp sgt (bitcast X to int), -1)
+  if (ICmpInst::makeCmpResultType(SI.getType()) != CondVal->getType())
+    return ChangedFMF ? &SI : nullptr;
+
+  for (bool Swap : {false, true}) {
+    Value *TrueVal = SI.getTrueValue();
+    Value *X = SI.getFalseValue();
+
+    if (Swap)
+      std::swap(TrueVal, X);
+
+    CmpInst::Predicate Pred;
+    const APInt *C;
+    bool TrueIfSigned;
+    if (!match(CondVal, m_ICmp(Pred, m_BitCast(m_Specific(X)), m_APInt(C))) ||
+        !IC.isSignBitCheck(Pred, *C, TrueIfSigned))
+      continue;
+    if (!match(TrueVal, m_FNeg(m_Specific(X))))
+      return nullptr;
+    if (!CondVal->hasOneUse() && !TrueVal->hasOneUse())
+      return nullptr;
+
+    // Fold (IsSigned ? -X : X) or (!IsSigned ? X : -X) to fabs(X)
+    // Fold (IsSigned ? X : -X) or (!IsSigned ? -X : X) to -fabs(X)
+    Value *Fabs = IC.Builder.CreateUnaryIntrinsic(Intrinsic::fabs, X, &SI);
+    if (Swap != TrueIfSigned)
+      return IC.replaceInstUsesWith(SI, Fabs);
+    else {
----------------
dtcxzyw wrote:

Done.

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


More information about the llvm-commits mailing list