aboutsummaryrefslogtreecommitdiff
path: root/gcc/match.pd
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-01-03 07:17:18 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-01-03 07:17:18 +0000
commitd34457c138d06e989c871e7b295c06a8b9873703 (patch)
treec6778566a2e3b2d38ff05041a41dc94a6d331a69 /gcc/match.pd
parentfece509bf196d58d9b31e04d816bb4ecd3f73e89 (diff)
downloadgcc-d34457c138d06e989c871e7b295c06a8b9873703.zip
gcc-d34457c138d06e989c871e7b295c06a8b9873703.tar.gz
gcc-d34457c138d06e989c871e7b295c06a8b9873703.tar.bz2
poly_int: folding BIT_FIELD_REFs on vectors
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
Diffstat (limited to 'gcc/match.pd')
-rw-r--r--gcc/match.pd47
1 files changed, 22 insertions, 25 deletions
diff --git a/gcc/match.pd b/gcc/match.pd
index 06af2a7..a2a1b8f 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -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