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