This patch makes the:

  (BIT_FIELD_REF CONSTRUCTOR@0 @1 @2)

folder cope with polynomial numbers of elements.


2017-10-23  Richard Sandiford  <richard.sandif...@linaro.org>
            Alan Hayward  <alan.hayw...@arm.com>
            David Sherwood  <david.sherw...@arm.com>

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

Index: gcc/match.pd
===================================================================
--- gcc/match.pd        2017-10-23 17:22:18.230825454 +0100
+++ gcc/match.pd        2017-10-23 17:22:50.031432167 +0100
@@ -4307,46 +4307,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

Reply via email to