poly_int: folding BIT_FIELD_REFs on vectors
authorRichard Sandiford <richard.sandiford@linaro.org>
Wed, 3 Jan 2018 07:17:18 +0000 (07:17 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 3 Jan 2018 07:17:18 +0000 (07:17 +0000)
This patch makes the:

  (BIT_FIELD_REF CONSTRUCTOR@0 @1 @2)

folder cope with polynomial numbers of elements.

2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
    Alan Hayward  <alan.hayward@arm.com>
    David Sherwood  <david.sherwood@arm.com>

gcc/
* match.pd: Cope with polynomial numbers of vector elements.

Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256147

gcc/ChangeLog
gcc/match.pd

index 28998830858dc457ad65b2986ec43839e1688f75..ae13a2f68d393df3d7c2c29a1e24eb48583f512f 100644 (file)
@@ -1,3 +1,9 @@
+2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
+           Alan Hayward  <alan.hayward@arm.com>
+           David Sherwood  <david.sherwood@arm.com>
+
+       * match.pd: Cope with polynomial numbers of vector elements.
+
 2018-01-03  Richard Sandiford  <richard.sandiford@linaro.org>
            Alan Hayward  <alan.hayward@arm.com>
            David Sherwood  <david.sherwood@arm.com>
index 06af2a72213316b8fe31d7a1ea8c0d658ef96e84..a2a1b8f4c9517ef6e1ef00f0834e0cc4e5009d9b 100644 (file)
@@ -4530,46 +4530,43 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
        idx = idx / width;
        n = n / width;
        /* Constructor elements can be subvectors.  */
-       unsigned HOST_WIDE_INT k = 1;
+       poly_uint64 k = 1;
        if (CONSTRUCTOR_NELTS (ctor) != 0)
          {
            tree cons_elem = TREE_TYPE (CONSTRUCTOR_ELT (ctor, 0)->value);
           if (TREE_CODE (cons_elem) == VECTOR_TYPE)
             k = TYPE_VECTOR_SUBPARTS (cons_elem);
         }
+       unsigned HOST_WIDE_INT elt, count, const_k;
      }
      (switch
       /* We keep an exact subset of the constructor elements.  */
-      (if ((idx % k) == 0 && (n % k) == 0)
+      (if (multiple_p (idx, k, &elt) && multiple_p (n, k, &count))
        (if (CONSTRUCTOR_NELTS (ctor) == 0)
         { build_constructor (type, NULL); }
-       (with
+       (if (count == 1)
+        (if (elt < CONSTRUCTOR_NELTS (ctor))
+         { CONSTRUCTOR_ELT (ctor, elt)->value; }
+         { build_zero_cst (type); })
         {
-          idx /= k;
-          n /= k;
-        }
-        (if (n == 1)
-         (if (idx < CONSTRUCTOR_NELTS (ctor))
-          { CONSTRUCTOR_ELT (ctor, idx)->value; }
-          { build_zero_cst (type); })
-         {
-           vec<constructor_elt, va_gc> *vals;
-           vec_alloc (vals, n);
-           for (unsigned i = 0;
-                i < n && idx + i < CONSTRUCTOR_NELTS (ctor); ++i)
-             CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,
-                                     CONSTRUCTOR_ELT (ctor, idx + i)->value);
-           build_constructor (type, vals);
-         }))))
+          vec<constructor_elt, va_gc> *vals;
+          vec_alloc (vals, count);
+          for (unsigned i = 0;
+               i < count && elt + i < CONSTRUCTOR_NELTS (ctor); ++i)
+            CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,
+                                    CONSTRUCTOR_ELT (ctor, elt + i)->value);
+          build_constructor (type, vals);
+        })))
       /* The bitfield references a single constructor element.  */
-      (if (idx + n <= (idx / k + 1) * k)
+      (if (k.is_constant (&const_k)
+          && idx + n <= (idx / const_k + 1) * const_k)
        (switch
-        (if (CONSTRUCTOR_NELTS (ctor) <= idx / k)
+       (if (CONSTRUCTOR_NELTS (ctor) <= idx / const_k)
         { build_zero_cst (type); })
-       (if (n == k)
-        { CONSTRUCTOR_ELT (ctor, idx / k)->value; })
-       (BIT_FIELD_REF { CONSTRUCTOR_ELT (ctor, idx / k)->value; }
-                      @1 { bitsize_int ((idx % k) * width); })))))))))
+       (if (n == const_k)
+        { CONSTRUCTOR_ELT (ctor, idx / const_k)->value; })
+       (BIT_FIELD_REF { CONSTRUCTOR_ELT (ctor, idx / const_k)->value; }
+                      @1 { bitsize_int ((idx % const_k) * width); })))))))))
 
 /* Simplify a bit extraction from a bit insertion for the cases with
    the inserted element fully covering the extraction or the insertion