[PATCH] D47831: [DAGCombiner] Recognize more patterns for ABS

Krzysztof Parzyszek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 6 09:07:33 PDT 2018


kparzysz created this revision.
kparzysz added reviewers: spatel, eli.friedman.

The Hexagon backend had these recognized in selection patterns.  Make the combiner get them instead.  One case was already covered, but it failed when the XOR operands were switched.


Repository:
  rL LLVM

https://reviews.llvm.org/D47831

Files:
  lib/CodeGen/SelectionDAG/DAGCombiner.cpp
  lib/Target/Hexagon/HexagonISelLowering.cpp
  lib/Target/Hexagon/HexagonPatterns.td


Index: lib/Target/Hexagon/HexagonPatterns.td
===================================================================
--- lib/Target/Hexagon/HexagonPatterns.td
+++ lib/Target/Hexagon/HexagonPatterns.td
@@ -1175,22 +1175,6 @@
                      (i32 (LoReg $Rs)))>;
 }
 
-let AddedComplexity = 50 in
-multiclass Abs_pat<InstHexagon MI, PatFrag RsPred, int Sh> {
-  // Let y = x >> 31 (for 32-bit), i.e. the sign bit repeated.
-  // abs(x) = (x + y) ^ y
-  def: Pat<(xor (add (sra RsPred:$Rs, (i32 Sh)), RsPred:$Rs),
-                (sra RsPred:$Rs, (i32 Sh))),
-           (MI RsPred:$Rs)>;
-  // abs(x) = (x ^ y) - y
-  def: Pat<(sub (xor RsPred:$Rs, (sra RsPred:$Rs, (i32 Sh))),
-                (sra RsPred:$Rs, (i32 Sh))),
-           (MI RsPred:$Rs)>;
-}
-
-defm: Abs_pat<A2_abs,  I32, 31>;
-defm: Abs_pat<A2_absp, I64, 63>;
-
 def: Pat<(add I32:$Rs, anyimm:$s16),   (A2_addi   I32:$Rs,  imm:$s16)>;
 def: Pat<(or  I32:$Rs, anyimm:$s10),   (A2_orir   I32:$Rs,  imm:$s10)>;
 def: Pat<(and I32:$Rs, anyimm:$s10),   (A2_andir  I32:$Rs,  imm:$s10)>;
Index: lib/Target/Hexagon/HexagonISelLowering.cpp
===================================================================
--- lib/Target/Hexagon/HexagonISelLowering.cpp
+++ lib/Target/Hexagon/HexagonISelLowering.cpp
@@ -1327,6 +1327,9 @@
     setMinimumJumpTableEntries(std::numeric_limits<int>::max());
   setOperationAction(ISD::BR_JT, MVT::Other, Expand);
 
+  setOperationAction(ISD::ABS, MVT::i32, Legal);
+  setOperationAction(ISD::ABS, MVT::i64, Legal);
+
   // Hexagon has A4_addp_c and A4_subp_c that take and generate a carry bit,
   // but they only operate on i64.
   for (MVT VT : MVT::integer_valuetypes()) {
Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -2544,6 +2544,16 @@
   if (N1.isUndef())
     return N1;
 
+  // fold Y = sra (X, size(X)-1); sub (xor (X, Y), Y) -> (abs X)
+  if (N0.getOpcode() == ISD::XOR && N0.getOperand(1) == N1 &&
+      N1.getOpcode() == ISD::SRA && N1.getOperand(0) == N0.getOperand(0) &&
+      TLI.isOperationLegalOrCustom(ISD::ABS, VT)) {
+    unsigned OpSizeInBits = VT.getScalarSizeInBits();
+    if (ConstantSDNode *C = isConstOrConstSplat(N1.getOperand(1)))
+      if (C->getAPIntValue() == (OpSizeInBits - 1))
+        return DAG.getNode(ISD::ABS, SDLoc(N), VT, N0.getOperand(0));
+  }
+
   // If the relocation model supports it, consider symbol offsets.
   if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N0))
     if (!LegalOperations && TLI.isOffsetFoldingLegal(GA)) {
@@ -5633,13 +5643,16 @@
   }
 
   // fold Y = sra (X, size(X)-1); xor (add (X, Y), Y) -> (abs X)
-  unsigned OpSizeInBits = VT.getScalarSizeInBits();
-  if (N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1 &&
-      N1.getOpcode() == ISD::SRA && N1.getOperand(0) == N0.getOperand(0) &&
-      TLI.isOperationLegalOrCustom(ISD::ABS, VT)) {
-    if (ConstantSDNode *C = isConstOrConstSplat(N1.getOperand(1)))
-      if (C->getAPIntValue() == (OpSizeInBits - 1))
-        return DAG.getNode(ISD::ABS, SDLoc(N), VT, N0.getOperand(0));
+  if (TLI.isOperationLegalOrCustom(ISD::ABS, VT)) {
+    SDValue A = N0.getOpcode() == ISD::ADD ? N0 : N1;
+    SDValue S = N0.getOpcode() == ISD::SRA ? N0 : N1;
+    if (A.getOpcode() == ISD::ADD && A.getOperand(1) == S &&
+        S.getOpcode() == ISD::SRA && S.getOperand(0) == A.getOperand(0)) {
+      unsigned OpSizeInBits = VT.getScalarSizeInBits();
+      if (ConstantSDNode *C = isConstOrConstSplat(S.getOperand(1)))
+        if (C->getAPIntValue() == (OpSizeInBits - 1))
+          return DAG.getNode(ISD::ABS, SDLoc(N), VT, A.getOperand(0));
+    }
   }
 
   // fold (xor x, x) -> 0


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47831.150151.patch
Type: text/x-patch
Size: 3776 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180606/a1b87227/attachment.bin>


More information about the llvm-commits mailing list