If get_ref_base_and_extent returns poly_int offsets or sizes,
tree-sra.c:create_access prevents SRA from being applied to the base.
However, we haven't verified by that point that we have a valid base
to disqualify.
This originally led to an ICE on the attached testcase, but it
no longer triggers there after the introduction of IPA SRA.
Tested on aarch64-linux-gnu and x86_64-linux-gnu. OK to install?
Richard
2019-11-08 Richard Sandiford
gcc/
* tree-sra.c (create_access): Delay disqualifying the base
for poly_int values until we know we have a base.
gcc/testsuite/
* gcc.target/aarch64/sve/acle/general/inline_2.c: New test.
Index: gcc/tree-sra.c
===
--- gcc/tree-sra.c 2019-11-06 12:29:17.870674022 +
+++ gcc/tree-sra.c 2019-11-08 09:20:22.853050602 +
@@ -789,19 +789,11 @@ create_access (tree expr, gimple *stmt,
{
struct access *access;
poly_int64 poffset, psize, pmax_size;
- HOST_WIDE_INT offset, size, max_size;
tree base = expr;
bool reverse, unscalarizable_region = false;
base = get_ref_base_and_extent (expr, , , _size,
);
- if (!poffset.is_constant ()
- || !psize.is_constant ()
- || !pmax_size.is_constant (_size))
-{
- disqualify_candidate (base, "Encountered a polynomial-sized access.");
- return NULL;
-}
/* For constant-pool entries, check we can substitute the constant value. */
if (constant_decl_p (base))
@@ -824,6 +816,15 @@ create_access (tree expr, gimple *stmt,
if (!DECL_P (base) || !bitmap_bit_p (candidate_bitmap, DECL_UID (base)))
return NULL;
+ HOST_WIDE_INT offset, size, max_size;
+ if (!poffset.is_constant ()
+ || !psize.is_constant ()
+ || !pmax_size.is_constant (_size))
+{
+ disqualify_candidate (base, "Encountered a polynomial-sized access.");
+ return NULL;
+}
+
if (size != max_size)
{
size = max_size;
Index: gcc/testsuite/gcc.target/aarch64/sve/acle/general/inline_2.c
===
--- /dev/null 2019-09-17 11:41:18.176664108 +0100
+++ gcc/testsuite/gcc.target/aarch64/sve/acle/general/inline_2.c
2019-11-08 09:20:22.849050630 +
@@ -0,0 +1,16 @@
+/* { dg-options "-O2" } */
+
+typedef struct s { double d[4]; } TYPE;
+
+static inline void
+copy (TYPE *dst, TYPE *src)
+{
+ __SVFloat64_t tmp = *(__SVFloat64_t *) src;
+ *dst = *(TYPE *)
+}
+
+void
+foo (TYPE *a)
+{
+ copy (a, a + 1);
+}