Add mode_for_int_vector helper functions
authorRichard Sandiford <richard.sandiford@linaro.org>
Tue, 5 Sep 2017 19:57:28 +0000 (19:57 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Tue, 5 Sep 2017 19:57:28 +0000 (19:57 +0000)
There are at least a few places that want to create an integer vector
with a specified element size and element count, or to create the
integer equivalent of an existing mode.  This patch adds helpers
for doing that.

The require ()s are all used in functions that go on to emit
instructions that use the result as a vector mode.

2017-09-05  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
* machmode.h (mode_for_int_vector): New function.
* stor-layout.c (mode_for_int_vector): Likewise.
* config/aarch64/aarch64.c (aarch64_emit_approx_sqrt): Use it.
* config/powerpcspe/powerpcspe.c (rs6000_do_expand_vec_perm): Likewise.
* config/rs6000/rs6000.c (rs6000_do_expand_vec_perm): Likewise.
* config/s390/s390.c (s390_expand_vec_compare_cc): Likewise.
(s390_expand_vcond): Likewise.

From-SVN: r251729

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/powerpcspe/powerpcspe.c
gcc/config/rs6000/rs6000.c
gcc/config/s390/s390.c
gcc/machmode.h
gcc/stor-layout.c

index 4a7f676a1437080994f18c0d351b15f47c66cac4..03f690fecf4ca9eae3967ef5fe9fab47e187ced4 100644 (file)
@@ -1,3 +1,13 @@
+2017-09-05  Richard Sandiford  <richard.sandiford@linaro.org>
+
+       * machmode.h (mode_for_int_vector): New function.
+       * stor-layout.c (mode_for_int_vector): Likewise.
+       * config/aarch64/aarch64.c (aarch64_emit_approx_sqrt): Use it.
+       * config/powerpcspe/powerpcspe.c (rs6000_do_expand_vec_perm): Likewise.
+       * config/rs6000/rs6000.c (rs6000_do_expand_vec_perm): Likewise.
+       * config/s390/s390.c (s390_expand_vec_compare_cc): Likewise.
+       (s390_expand_vcond): Likewise.
+
 2017-09-05  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * machmode.h (opt_machine_mode): New type.
index d766307e6509d4575ee50f5c8db3486529d122e8..2a5a075e62bbe9d15b563b44569e6ff85066bd95 100644 (file)
@@ -8282,9 +8282,6 @@ aarch64_emit_approx_sqrt (rtx dst, rtx src, bool recp)
       return false;
     }
 
-  machine_mode mmsk
-    = mode_for_vector (int_mode_for_mode (GET_MODE_INNER (mode)).require (),
-                      GET_MODE_NUNITS (mode));
   if (!recp)
     {
       if (!(flag_mlow_precision_sqrt
@@ -8302,7 +8299,7 @@ aarch64_emit_approx_sqrt (rtx dst, rtx src, bool recp)
     /* Caller assumes we cannot fail.  */
     gcc_assert (use_rsqrt_p (mode));
 
-
+  machine_mode mmsk = mode_for_int_vector (mode).require ();
   rtx xmsk = gen_reg_rtx (mmsk);
   if (!recp)
     /* When calculating the approximate square root, compare the
index 9fd2d86abbf4ad9245fd9703ccd7236d1e9cdb1f..82c36dee6783bc38810304c0ed47e6a671e2aa1f 100644 (file)
@@ -38739,8 +38739,7 @@ rs6000_do_expand_vec_perm (rtx target, rtx op0, rtx op1,
 
   imode = vmode;
   if (GET_MODE_CLASS (vmode) != MODE_VECTOR_INT)
-    imode = mode_for_vector
-      (int_mode_for_mode (GET_MODE_INNER (vmode)).require (), nelt);
+    imode = mode_for_int_vector (vmode).require ();
 
   x = gen_rtx_CONST_VECTOR (imode, gen_rtvec_v (nelt, perm));
   x = expand_vec_perm (vmode, op0, op1, x, target);
index 1a934ec4dabe4d389caf48e346d7296d47ceb54b..5f3d36133b4287fdb72ee9b62ec08bf2bd90aae5 100644 (file)
@@ -35584,8 +35584,7 @@ rs6000_do_expand_vec_perm (rtx target, rtx op0, rtx op1,
 
   imode = vmode;
   if (GET_MODE_CLASS (vmode) != MODE_VECTOR_INT)
-    imode = mode_for_vector
-      (int_mode_for_mode (GET_MODE_INNER (vmode)).require (), nelt);
+    imode = mode_for_int_vector (vmode).require ();
 
   x = gen_rtx_CONST_VECTOR (imode, gen_rtvec_v (nelt, perm));
   x = expand_vec_perm (vmode, op0, op1, x, target);
index 3fd1ff618d9357ab223b778769b619accf56db7d..36bc67db1da6308597cb5130830c21597b587b0d 100644 (file)
@@ -6472,10 +6472,7 @@ s390_expand_vec_compare_cc (rtx target, enum rtx_code code,
        case LE:   cc_producer_mode = CCVFHEmode; code = GE; swap_p = true; break;
        default: gcc_unreachable ();
        }
-      scratch_mode = mode_for_vector
-       (int_mode_for_mode (GET_MODE_INNER (GET_MODE (cmp1))).require (),
-        GET_MODE_NUNITS (GET_MODE (cmp1)));
-      gcc_assert (scratch_mode != BLKmode);
+      scratch_mode = mode_for_int_vector (GET_MODE (cmp1)).require ();
 
       if (inv_p)
        all_p = !all_p;
@@ -6581,9 +6578,7 @@ s390_expand_vcond (rtx target, rtx then, rtx els,
 
   /* We always use an integral type vector to hold the comparison
      result.  */
-  result_mode = mode_for_vector
-    (int_mode_for_mode (GET_MODE_INNER (cmp_mode)).require (),
-     GET_MODE_NUNITS (cmp_mode));
+  result_mode = mode_for_int_vector (cmp_mode).require ();
   result_target = gen_reg_rtx (result_mode);
 
   /* We allow vector immediates as comparison operands that
index 956e2c086f164242678e043f9b8e938c2e97cabb..7dd71e90d3db7bec48c491100ffd5e924cd070d4 100644 (file)
@@ -706,6 +706,21 @@ extern machine_mode bitwise_mode_for_mode (machine_mode);
 
 extern machine_mode mode_for_vector (scalar_mode, unsigned);
 
+extern opt_machine_mode mode_for_int_vector (unsigned int, unsigned int);
+
+/* Return the integer vector equivalent of MODE, if one exists.  In other
+   words, return the mode for an integer vector that has the same number
+   of bits as MODE and the same number of elements as MODE, with the
+   latter being 1 if MODE is scalar.  The returned mode can be either
+   an integer mode or a vector mode.  */
+
+inline opt_machine_mode
+mode_for_int_vector (machine_mode mode)
+{
+  return mode_for_int_vector (GET_MODE_UNIT_BITSIZE (mode),
+                             GET_MODE_NUNITS (mode));
+}
+
 /* A class for iterating through possible bitfield modes.  */
 class bit_field_mode_iterator
 {
index f9a28e7c849636ea1bf0a14fb07d37be4c458f27..6bb7b246c25d03388e6506245aacb1ebdc593900 100644 (file)
@@ -517,6 +517,23 @@ mode_for_vector (scalar_mode innermode, unsigned nunits)
   return mode;
 }
 
+/* Return the mode for a vector that has NUNITS integer elements of
+   INT_BITS bits each, if such a mode exists.  The mode can be either
+   an integer mode or a vector mode.  */
+
+opt_machine_mode
+mode_for_int_vector (unsigned int int_bits, unsigned int nunits)
+{
+  scalar_int_mode int_mode;
+  if (int_mode_for_size (int_bits, 0).exists (&int_mode))
+    {
+      machine_mode vec_mode = mode_for_vector (int_mode, nunits);
+      if (vec_mode != BLKmode)
+       return vec_mode;
+    }
+  return opt_machine_mode ();
+}
+
 /* Return the alignment of MODE. This will be bounded by 1 and
    BIGGEST_ALIGNMENT.  */