diff mbox series

[084/nnn] poly_int: folding BIT_FIELD_REFs on vectors

Message ID 87po9dg454.fsf@linaro.org
State New
Headers show
Series [084/nnn] poly_int: folding BIT_FIELD_REFs on vectors | expand

Commit Message

Richard Sandiford Oct. 23, 2017, 5:33 p.m. UTC
This patch makes the:

  (BIT_FIELD_REF CONSTRUCTOR@0 @1 @2)

folder cope with polynomial numbers of elements.


2017-10-23  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.

Comments

Jeff Law Nov. 28, 2017, 4:31 p.m. UTC | #1
On 10/23/2017 11:33 AM, Richard Sandiford wrote:
> This patch makes the:

> 

>   (BIT_FIELD_REF CONSTRUCTOR@0 @1 @2)

> 

> folder cope with polynomial numbers of elements.

> 

> 

> 2017-10-23  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.

ARgh.  It took me a moment of wondering why it didn't look like C code.
It's match.pd :-)

OK.

jeff
diff mbox series

Patch

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