]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
amdgcn: Disallow unsupported permute on RDNA devices
authorAndrew Stubbs <ams@baylibre.com>
Wed, 14 Feb 2024 15:12:43 +0000 (15:12 +0000)
committerAndrew Stubbs <ams@baylibre.com>
Thu, 15 Feb 2024 13:01:39 +0000 (13:01 +0000)
The RDNA architecture has limited support for permute operations.  This should
allow use of the permutations that do work, and fall back to linear code for
other cases.

gcc/ChangeLog:

* config/gcn/gcn-valu.md
(vec_extract<V_MOV:mode><V_MOV_ALT:mode>): Add conditions for RDNA.
* config/gcn/gcn.cc (gcn_vectorize_vec_perm_const): Check permutation
details are supported on RDNA devices.

gcc/config/gcn/gcn-valu.md
gcc/config/gcn/gcn.cc

index 23b441f8e8b6ae23c31fd281bd17a285aeb0b1ca..59e27d0aed790eadb39cd0673658206b5e85562e 100644 (file)
    (match_operand:V_MOV 1 "register_operand")
    (match_operand 2 "immediate_operand")]
   "MODE_VF (<V_MOV_ALT:MODE>mode) < MODE_VF (<V_MOV:MODE>mode)
-   && <V_MOV_ALT:SCALAR_MODE>mode == <V_MOV:SCALAR_MODE>mode"
+   && <V_MOV_ALT:SCALAR_MODE>mode == <V_MOV:SCALAR_MODE>mode
+   && (!TARGET_RDNA2_PLUS || MODE_VF (<V_MOV:MODE>mode) <= 32)"
   {
     int numlanes = GET_MODE_NUNITS (<V_MOV_ALT:MODE>mode);
     int firstlane = INTVAL (operands[2]) * numlanes;
index 20be45565462b6d399de8e9444682dd7a74c8790..4559d6932d4a0c5a6dd42df0afcc9c13dad8e478 100644 (file)
@@ -5110,19 +5110,24 @@ gcn_vectorize_vec_perm_const (machine_mode vmode, machine_mode op_mode,
   gcc_assert (nelt <= 64);
   gcc_assert (sel.length () == nelt);
 
-  if (!dst)
-    {
-      /* All vector permutations are possible on this architecture,
-         with varying degrees of efficiency depending on the permutation. */
-      return true;
-    }
-
   unsigned int perm[64];
   for (unsigned int i = 0; i < nelt; ++i)
     perm[i] = sel[i] & (2 * nelt - 1);
   for (unsigned int i = nelt; i < 64; ++i)
     perm[i] = 0;
 
+  /* RDNA devices can only do permutations within each group of 32-lanes.
+     Reject permutations that cross the boundary.  */
+  if (TARGET_RDNA2_PLUS)
+    for (unsigned int i = 0; i < nelt; i++)
+      if (i < 31 ? perm[i] > 31 : perm[i] < 32)
+       return false;
+
+  /* All vector permutations are possible on other architectures,
+     with varying degrees of efficiency depending on the permutation. */
+  if (!dst)
+    return true;
+
   src0 = force_reg (vmode, src0);
   src1 = force_reg (vmode, src1);