]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Canonicalize vec_merge when mask is constant.
authorliuhongt <hongtao.liu@intel.com>
Tue, 21 Mar 2023 05:35:06 +0000 (13:35 +0800)
committerliuhongt <hongtao.liu@intel.com>
Sat, 6 May 2023 01:01:18 +0000 (09:01 +0800)
Use swap_communattive_operands_p for canonicalization. When both value
has same operand precedence value, then first bit in the mask should
select first operand.

The canonicalization should help backends for pattern match. .i.e. x86
backend has lots of vec_merge patterns, combine will create any form
of vec_merge(mask, or inverted mask), then backend need to add 2
patterns to match exact 1 instruction. The canonicalization can
simplify 2 patterns to 1.

gcc/ChangeLog:

* combine.cc (maybe_swap_commutative_operands): Canonicalize
vec_merge when mask is constant.
* doc/md.texi: Document vec_merge canonicalization.

gcc/combine.cc
gcc/doc/md.texi

index 0106092e456895925740396c05d1813061aaed82..5aa0ec5c45ae542fdfd6f09ba4b285d50525a9cd 100644 (file)
@@ -5631,6 +5631,28 @@ maybe_swap_commutative_operands (rtx x)
       SUBST (XEXP (x, 0), XEXP (x, 1));
       SUBST (XEXP (x, 1), temp);
     }
+
+  unsigned n_elts = 0;
+  if (GET_CODE (x) == VEC_MERGE
+      && CONST_INT_P (XEXP (x, 2))
+      && GET_MODE_NUNITS (GET_MODE (x)).is_constant (&n_elts)
+      && (swap_commutative_operands_p (XEXP (x, 0), XEXP (x, 1))
+         /* Two operands have same precedence, then
+            first bit of mask select first operand.  */
+         || (!swap_commutative_operands_p (XEXP (x, 1), XEXP (x, 0))
+             && !(UINTVAL (XEXP (x, 2)) & 1))))
+    {
+      rtx temp = XEXP (x, 0);
+      unsigned HOST_WIDE_INT sel = UINTVAL (XEXP (x, 2));
+      unsigned HOST_WIDE_INT mask = HOST_WIDE_INT_1U;
+      if (n_elts == HOST_BITS_PER_WIDE_INT)
+       mask = -1;
+      else
+       mask = (HOST_WIDE_INT_1U << n_elts) - 1;
+      SUBST (XEXP (x, 0), XEXP (x, 1));
+      SUBST (XEXP (x, 1), temp);
+      SUBST (XEXP (x, 2), GEN_INT (~sel & mask));
+    }
 }
 
 /* Simplify X, a piece of RTL.  We just operate on the expression at the
index 37e537733c94347a4c9ae3cb8ad4afa94e1a66fc..8ebce31ba78f30f162c39018c14ed34821681426 100644 (file)
@@ -8224,6 +8224,13 @@ second operand.  If a machine only supports a constant as the second
 operand, only patterns that match a constant in the second operand need
 be supplied.
 
+@cindex @code{vec_merge}, canonicalization of
+@item
+For the @code{vec_merge} with constant mask(the third operand), the first
+and the second operand can be exchanged by inverting the mask. In such cases,
+a constant is always made the second operand, otherwise the least significant
+bit of the mask is always set(select the first operand first).
+
 @item
 For associative operators, a sequence of operators will always chain
 to the left; for instance, only the left operand of an integer @code{plus}