[llvm] [DAGCombiner] Turn `(neg (max x, (neg x)))` into `(min x, (neg x))` (PR #120666)

Min-Yih Hsu via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 20 10:53:11 PST 2024


================
@@ -3949,6 +3949,20 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
       if (SDValue Result = TLI.expandABS(N1.getNode(), DAG, true))
         return Result;
 
+    // Similar to the previous rule, but this time targeting an expanded abs.
+    // (sub 0, (max X, (sub 0, X))) --> (min X, (sub 0, X))
+    // Note that this is applicable to both signed and unsigned min/max.
+    SDValue X;
+    if (LegalOperations &&
+        sd_match(N1,
+                 m_OneUse(m_AnyOf(m_SMax(m_Value(X), m_Neg(m_Deferred(X))),
+                                  m_UMax(m_Value(X), m_Neg(m_Deferred(X))))))) {
+      unsigned MinOpc = N1->getOpcode() == ISD::SMAX ? ISD::SMIN : ISD::UMIN;
+      if (hasOperation(MinOpc, VT))
+        return DAG.getNode(MinOpc, DL, VT, X,
+                           DAG.getNode(ISD::SUB, DL, VT, N0, X));
----------------
mshockwave wrote:

Good catch. I simply capture and reuse the SDValue of the first sub. It's done now.

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


More information about the llvm-commits mailing list