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  <richard.sandif...@arm.com>

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 +0000
+++ gcc/tree-sra.c      2019-11-08 09:20:22.853050602 +0000
@@ -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, &poffset, &psize, &pmax_size,
                                  &reverse);
-  if (!poffset.is_constant (&offset)
-      || !psize.is_constant (&size)
-      || !pmax_size.is_constant (&max_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 (&offset)
+      || !psize.is_constant (&size)
+      || !pmax_size.is_constant (&max_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 +0000
@@ -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 *) &tmp;
+}
+
+void
+foo (TYPE *a)
+{
+  copy (a, a + 1);
+}

Reply via email to