re PR target/80162 (ICE on invalid code (address of register variable))
authorJakub Jelinek <jakub@redhat.com>
Mon, 27 Mar 2017 21:07:21 +0000 (23:07 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 27 Mar 2017 21:07:21 +0000 (23:07 +0200)
PR middle-end/80162
c-family/
* c-common.c (c_common_mark_addressable_vec): Don't set
TREE_ADDRESSABLE on DECL_HARD_REGISTER.
c/
* c-tree.h (c_mark_addressable): Add array_ref_p argument.
* c-typeck.c (c_mark_addressable): Likewise.  Look through
VIEW_CONVERT_EXPR unless array_ref_p and VCE is from VECTOR_TYPE
to ARRAY_TYPE.
(build_array_ref): Pass true as array_ref_p to c_mark_addressable.
cp/
* cp-tree.h (cxx_mark_addressable): Add array_ref_p argument.
* typeck.c (cxx_mark_addressable): Likewise.  Look through
VIEW_CONVERT_EXPR unless array_ref_p and VCE is from VECTOR_TYPE
to ARRAY_TYPE.
(cp_build_array_ref): Pass true as array_ref_p to cxx_mark_addressable.
testsuite/
* c-c++-common/pr80162-1.c: New test.
* c-c++-common/pr80162-2.c: New test.
* c-c++-common/pr80162-3.c: New test.

From-SVN: r246512

12 files changed:
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c/ChangeLog
gcc/c/c-tree.h
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/pr80162-1.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr80162-2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/pr80162-3.c [new file with mode: 0644]

index 4afb4b8af6ec6d391494d01e1da6495a0f99cc04..0b543ec52f6ebf945df3a1a1de249df11e8f4148 100644 (file)
@@ -1,3 +1,9 @@
+2017-03-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/80162
+       * c-common.c (c_common_mark_addressable_vec): Don't set
+       TREE_ADDRESSABLE on DECL_HARD_REGISTER.
+
 2017-03-21  Martin Sebor  <msebor@redhat.com>
 
        PR c++/79548
index 65ffd8cd7bdb3510f2d67809483828777456ca56..07af384cd6b9f1c049bdf780bdbc57a1aa99a4ee 100644 (file)
@@ -6542,7 +6542,8 @@ c_common_mark_addressable_vec (tree t)
       && TREE_CODE (t) != PARM_DECL
       && TREE_CODE (t) != COMPOUND_LITERAL_EXPR)
     return;
-  TREE_ADDRESSABLE (t) = 1;
+  if (!VAR_P (t) || !DECL_HARD_REGISTER (t))
+    TREE_ADDRESSABLE (t) = 1;
 }
 
 
index f4dbeeb1b09bb2a1102cafc10a0ecb2b9786d3f0..08a5b9ae2d7773f95fb7019ba13738ea6dc2bcbb 100644 (file)
@@ -1,3 +1,12 @@
+2017-03-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/80162
+       * c-tree.h (c_mark_addressable): Add array_ref_p argument.
+       * c-typeck.c (c_mark_addressable): Likewise.  Look through
+       VIEW_CONVERT_EXPR unless array_ref_p and VCE is from VECTOR_TYPE
+       to ARRAY_TYPE.
+       (build_array_ref): Pass true as array_ref_p to c_mark_addressable.
+
 2017-03-23  Marek Polacek  <polacek@redhat.com>
 
        * c-tree.h: Remove a C_RID_YYCODE reference.
index 9428d74d05114c33b12bf9dabd0a96411f421a27..5fa32a48f294e0a465f764ba1f30393240464115 100644 (file)
@@ -615,7 +615,7 @@ extern int same_translation_unit_p (const_tree, const_tree);
 extern int comptypes (tree, tree);
 extern int comptypes_check_different_types (tree, tree, bool *);
 extern bool c_vla_type_p (const_tree);
-extern bool c_mark_addressable (tree);
+extern bool c_mark_addressable (tree, bool = false);
 extern void c_incomplete_type_error (location_t, const_tree, const_tree);
 extern tree c_type_promotes_to (tree);
 extern struct c_expr default_function_array_conversion (location_t,
index b283a211a0365152c79ca76d66a2307ab36ec61c..ff239e2d6282025d855bcd1c39a0bfaab904a26e 100644 (file)
@@ -2654,7 +2654,7 @@ build_array_ref (location_t loc, tree array, tree index)
          || (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
              && TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
        {
-         if (!c_mark_addressable (array))
+         if (!c_mark_addressable (array, true))
            return error_mark_node;
        }
       /* An array that is indexed by a constant value which is not within
@@ -4755,16 +4755,26 @@ lvalue_or_else (location_t loc, const_tree ref, enum lvalue_use use)
 \f
 /* Mark EXP saying that we need to be able to take the
    address of it; it should not be allocated in a register.
-   Returns true if successful.  */
+   Returns true if successful.  ARRAY_REF_P is true if this
+   is for ARRAY_REF construction - in that case we don't want
+   to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE,
+   it is fine to use ARRAY_REFs for vector subscripts on vector
+   register variables.  */
 
 bool
-c_mark_addressable (tree exp)
+c_mark_addressable (tree exp, bool array_ref_p)
 {
   tree x = exp;
 
   while (1)
     switch (TREE_CODE (x))
       {
+      case VIEW_CONVERT_EXPR:
+       if (array_ref_p
+           && TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
+           && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))))
+         return true;
+       /* FALLTHRU */
       case COMPONENT_REF:
       case ADDR_EXPR:
       case ARRAY_REF:
index ea1eaa771a5b450e581bc9295d579cae009ba3e5..1d75be5a2d4679399894c9555918dda58ca6b438 100644 (file)
@@ -1,3 +1,12 @@
+2017-03-27  Jakub Jelinek  <jakub@redhat.com>
+
+       PR middle-end/80162
+       * cp-tree.h (cxx_mark_addressable): Add array_ref_p argument.
+       * typeck.c (cxx_mark_addressable): Likewise.  Look through
+       VIEW_CONVERT_EXPR unless array_ref_p and VCE is from VECTOR_TYPE
+       to ARRAY_TYPE.
+       (cp_build_array_ref): Pass true as array_ref_p to cxx_mark_addressable.
+
 2017-03-24  Jason Merrill  <jason@redhat.com>
 
        PR c++/77339 - ICE with invalid use of alias template.
index 9f02a97619afdbf2a0b404fd455ce2b0b3e0a8ce..daa1a81103e6583a8681e3d8c910763a62051bf8 100644 (file)
@@ -6715,7 +6715,7 @@ extern void cxx_print_error_function              (diagnostic_context *,
                                                 struct diagnostic_info *);
 
 /* in typeck.c */
-extern bool cxx_mark_addressable               (tree);
+extern bool cxx_mark_addressable               (tree, bool = false);
 extern int string_conv_p                       (const_tree, const_tree, int);
 extern tree cp_truthvalue_conversion           (tree);
 extern tree condition_conversion               (tree);
index 4e9a1c0b6e768d3d1f777f800b917528a350241f..79391c04fd6452dfadfa8b75d51dab1c0b66861d 100644 (file)
@@ -3217,7 +3217,7 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
              && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))))
                  != INTEGER_CST)))
        {
-         if (!cxx_mark_addressable (array))
+         if (!cxx_mark_addressable (array, true))
            return error_mark_node;
        }
 
@@ -6269,18 +6269,28 @@ unary_complex_lvalue (enum tree_code code, tree arg)
 \f
 /* Mark EXP saying that we need to be able to take the
    address of it; it should not be allocated in a register.
-   Value is true if successful.
+   Value is true if successful.  ARRAY_REF_P is true if this
+   is for ARRAY_REF construction - in that case we don't want
+   to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE,
+   it is fine to use ARRAY_REFs for vector subscripts on vector
+   register variables.
 
    C++: we do not allow `current_class_ptr' to be addressable.  */
 
 bool
-cxx_mark_addressable (tree exp)
+cxx_mark_addressable (tree exp, bool array_ref_p)
 {
   tree x = exp;
 
   while (1)
     switch (TREE_CODE (x))
       {
+      case VIEW_CONVERT_EXPR:
+       if (array_ref_p
+           && TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE
+           && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))))
+         return true;
+       /* FALLTHRU */
       case ADDR_EXPR:
       case COMPONENT_REF:
       case ARRAY_REF:
index 8146499de3f4999d144905cf9e3486280f0abdf9..14f6d6b5408b2b3b173879f4c435233d50dd2656 100644 (file)
@@ -1,5 +1,10 @@
 2017-03-27  Jakub Jelinek  <jakub@redhat.com>
 
+       PR middle-end/80162
+       * c-c++-common/pr80162-1.c: New test.
+       * c-c++-common/pr80162-2.c: New test.
+       * c-c++-common/pr80162-3.c: New test.
+
        PR target/80102
        * g++.dg/opt/pr80102.C: New test.
 
diff --git a/gcc/testsuite/c-c++-common/pr80162-1.c b/gcc/testsuite/c-c++-common/pr80162-1.c
new file mode 100644 (file)
index 0000000..7d442b3
--- /dev/null
@@ -0,0 +1,13 @@
+/* PR middle-end/80162 */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-msse2 -ffixed-xmm7" } */
+
+typedef int v8 __attribute__ ((vector_size (8)));
+struct U { v8 a; v8 b; };
+register struct U u asm ("xmm7");
+
+int *
+foo (int i)
+{
+  return &u.a[i];      /* { dg-error "address of \[^ \n\r]* register variable" } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr80162-2.c b/gcc/testsuite/c-c++-common/pr80162-2.c
new file mode 100644 (file)
index 0000000..cb2c899
--- /dev/null
@@ -0,0 +1,18 @@
+/* PR middle-end/80162 */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-mavx2 -ffixed-xmm7" } */
+
+typedef int V __attribute__ ((vector_size (32)));
+register V u asm ("xmm7");
+
+int
+foo (int i)
+{
+  return u[i];
+}
+
+int
+bar (void)
+{
+  return u[5];
+}
diff --git a/gcc/testsuite/c-c++-common/pr80162-3.c b/gcc/testsuite/c-c++-common/pr80162-3.c
new file mode 100644 (file)
index 0000000..a600fde
--- /dev/null
@@ -0,0 +1,18 @@
+/* PR middle-end/80162 */
+/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && lp64 } } } */
+/* { dg-options "-mavx2 -ffixed-xmm7" } */
+
+typedef int V __attribute__ ((vector_size (32)));
+register V u asm ("xmm7");
+
+int *
+foo (int i)
+{
+  return &u[i];                /* { dg-error "address of \[^ \n\r]* register variable" } */
+}
+
+int *
+bar (void)
+{
+  return &u[5];                /* { dg-error "address of \[^ \n\r]* register variable" } */
+}