re PR middle-end/70434 (adding an extraneous cast to vector type results in inferior...
authorRichard Biener <rguenther@suse.de>
Tue, 24 May 2016 07:55:56 +0000 (07:55 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 24 May 2016 07:55:56 +0000 (07:55 +0000)
2016-05-24  Richard Biener  <rguenther@suse.de>

PR middle-end/70434
PR c/69504
c-family/
* c-common.h (convert_vector_to_pointer_for_subscript): Rename to ...
(convert_vector_to_array_for_subscript): ... this.
* c-common.c (convert_vector_to_pointer_for_subscript): Use a
VIEW_CONVERT_EXPR to an array type.  Rename to ...
(convert_vector_to_array_for_subscript): ... this.

cp/
* expr.c (mark_exp_read): Handle VIEW_CONVERT_EXPR.
* constexpr.c (cxx_eval_array_reference): Handle indexed
vectors.
* typeck.c (cp_build_array_ref): Adjust.

c/
* c-typeck.c (build_array_ref): Do not complain about indexing
non-lvalue vectors.  Adjust for function name change.

* tree-ssa.c (non_rewritable_mem_ref_base): Make sure to mark
bases which are accessed with non-invariant indices.
* gimple-fold.c (maybe_canonicalize_mem_ref_addr): Re-write
constant index ARRAY_REFs of vectors into BIT_FIELD_REFs.

* c-c++-common/vector-subscript-4.c: New testcase.
* c-c++-common/vector-subscript-5.c: Likewise.

From-SVN: r236630

15 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/cp/expr.c
gcc/cp/typeck.c
gcc/gimple-fold.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/vector-subscript-4.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/vector-subscript-5.c [new file with mode: 0644]
gcc/tree-ssa.c

index d4d12b140526b6d79ce3cf3e16ba1be44409c7f3..d94460e9419d843af1932d2eac16491441a8d2b9 100644 (file)
@@ -1,3 +1,12 @@
+2016-05-24  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70434
+       PR c/69504
+       * tree-ssa.c (non_rewritable_mem_ref_base): Make sure to mark
+       bases which are accessed with non-invariant indices.
+       * gimple-fold.c (maybe_canonicalize_mem_ref_addr): Re-write
+       constant index ARRAY_REFs of vectors into BIT_FIELD_REFs.
+
 2016-05-24  Kugan Vivekanandarajah  <kuganv@linaro.org>
 
        PR middle-end/71170
index f6ba9410200dfef21a485af5cd7b4727b8f07500..7f0ca2d805735a716b40fb72e54fcbab5eb624f4 100644 (file)
@@ -1,3 +1,13 @@
+2016-05-24  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70434
+       PR c/69504
+       * c-common.h (convert_vector_to_pointer_for_subscript): Rename to ...
+       (convert_vector_to_array_for_subscript): ... this.
+       * c-common.c (convert_vector_to_pointer_for_subscript): Use a
+       VIEW_CONVERT_EXPR to an array type.  Rename to ...
+       (convert_vector_to_array_for_subscript): ... this.
+
 2016-05-12  Marek Polacek  <polacek@redhat.com>
 
        PR c/70756
index 146e8059c1a06a50f387e6811d2328f65e1d2142..4568cf62a98b72af30d4c148c6f638799cdd30cd 100644 (file)
@@ -12496,66 +12496,34 @@ build_userdef_literal (tree suffix_id, tree value,
   return literal;
 }
 
-/* For vector[index], convert the vector to a
-   pointer of the underlying type.  Return true if the resulting
-   ARRAY_REF should not be an lvalue.  */
+/* For vector[index], convert the vector to an array of the underlying type.
+   Return true if the resulting ARRAY_REF should not be an lvalue.  */
 
 bool
-convert_vector_to_pointer_for_subscript (location_t loc,
-                                        tree *vecp, tree index)
+convert_vector_to_array_for_subscript (location_t loc,
+                                      tree *vecp, tree index)
 {
   bool ret = false;
   if (VECTOR_TYPE_P (TREE_TYPE (*vecp)))
     {
       tree type = TREE_TYPE (*vecp);
-      tree type1;
 
       ret = !lvalue_p (*vecp);
+
       if (TREE_CODE (index) == INTEGER_CST)
         if (!tree_fits_uhwi_p (index)
             || tree_to_uhwi (index) >= TYPE_VECTOR_SUBPARTS (type))
           warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
 
-      if (ret)
-       {
-         tree tmp = create_tmp_var_raw (type);
-         DECL_SOURCE_LOCATION (tmp) = loc;
-         *vecp = c_save_expr (*vecp);
-         if (TREE_CODE (*vecp) == C_MAYBE_CONST_EXPR)
-           {
-             bool non_const = C_MAYBE_CONST_EXPR_NON_CONST (*vecp);
-             *vecp = C_MAYBE_CONST_EXPR_EXPR (*vecp);
-             *vecp
-               = c_wrap_maybe_const (build4 (TARGET_EXPR, type, tmp,
-                                             *vecp, NULL_TREE, NULL_TREE),
-                                     non_const);
-           }
-         else
-           *vecp = build4 (TARGET_EXPR, type, tmp, *vecp,
-                           NULL_TREE, NULL_TREE);
-         SET_EXPR_LOCATION (*vecp, loc);
-         c_common_mark_addressable_vec (tmp);
-       }
-      else
-       c_common_mark_addressable_vec (*vecp);
-      type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
-      type1 = build_pointer_type (TREE_TYPE (*vecp));
-      bool ref_all = TYPE_REF_CAN_ALIAS_ALL (type1);
-      if (!ref_all
-         && !DECL_P (*vecp))
-       {
-         /* If the original vector isn't declared may_alias and it
-            isn't a bare vector look if the subscripting would
-            alias the vector we subscript, and if not, force ref-all.  */
-         alias_set_type vecset = get_alias_set (*vecp);
-         alias_set_type sset = get_alias_set (type);
-         if (!alias_sets_must_conflict_p (sset, vecset)
-             && !alias_set_subset_of (sset, vecset))
-           ref_all = true;
-       }
-      type = build_pointer_type_for_mode (type, ptr_mode, ref_all);
-      *vecp = build1 (ADDR_EXPR, type1, *vecp);
-      *vecp = convert (type, *vecp);
+      /* We are building an ARRAY_REF so mark the vector as addressable
+         to not run into the gimplifiers premature setting of DECL_GIMPLE_REG_P
+        for function parameters.  */
+      c_common_mark_addressable_vec (*vecp);
+
+      *vecp = build1 (VIEW_CONVERT_EXPR,
+                     build_array_type_nelts (TREE_TYPE (type),
+                                             TYPE_VECTOR_SUBPARTS (type)),
+                     *vecp);
     }
   return ret;
 }
index 0ee9f56712357653479162795011d2c13155a23a..0295532d3ea5671fd2e244e4e96e3b864050680d 100644 (file)
@@ -1368,7 +1368,7 @@ extern tree build_userdef_literal (tree suffix_id, tree value,
                                   enum overflow_type overflow,
                                   tree num_string);
 
-extern bool convert_vector_to_pointer_for_subscript (location_t, tree *, tree);
+extern bool convert_vector_to_array_for_subscript (location_t, tree *, tree);
 
 /* Possibe cases of scalar_to_vector conversion.  */
 enum stv_conv {
index c65f2e9e5e04ceb8f8319629e363c27ece7b31a8..9bb5ec1dfceb9f9a385b8e0d5f9ddbf2d0fcfbd3 100644 (file)
@@ -1,3 +1,10 @@
+2016-05-24  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70434
+       PR c/69504
+       * c-typeck.c (build_array_ref): Do not complain about indexing
+       non-lvalue vectors.  Adjust for function name change.
+
 2016-05-20  Martin Sebor  <msebor@redhat.com>
 
        PR c/71115
index 7c9b078ed1b04dbb4d2b9778aa762f60e5c50084..74bad2acc5d5e95fd39e59f7a14b302e54e3e44e 100644 (file)
@@ -2583,8 +2583,8 @@ build_array_ref (location_t loc, tree array, tree index)
 
   gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
 
-  bool non_lvalue
-    = convert_vector_to_pointer_for_subscript (loc, &array, index);
+  bool was_vector = VECTOR_TYPE_P (TREE_TYPE (array));
+  bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, index);
 
   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
     {
@@ -2613,7 +2613,8 @@ build_array_ref (location_t loc, tree array, tree index)
            return error_mark_node;
        }
 
-      if (pedantic || warn_c90_c99_compat)
+      if ((pedantic || warn_c90_c99_compat)
+         && ! was_vector)
        {
          tree foo = array;
          while (TREE_CODE (foo) == COMPONENT_REF)
index 9095576dd4af6f893b15b1b08fad8ae102116ca5..eaf42b83f1c67350b438969b8c3b5b3d78a9ade8 100644 (file)
@@ -1,3 +1,12 @@
+2016-05-24  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70434
+       PR c/69504
+       * expr.c (mark_exp_read): Handle VIEW_CONVERT_EXPR.
+       * constexpr.c (cxx_eval_array_reference): Handle indexed
+       vectors.
+       * typeck.c (cp_build_array_ref): Adjust.
+
 2016-05-23  Jason Merrill  <jason@redhat.com>
 
        PR c++/70344
index bb723f45b09ea4a45ae1658d3d332519e8d9ca37..482f8afaeb6d07a967434c964c9bbc178a4dd44b 100644 (file)
@@ -1983,6 +1983,10 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
   else if (lval)
     return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
   elem_type = TREE_TYPE (TREE_TYPE (ary));
+  if (TREE_CODE (ary) == VIEW_CONVERT_EXPR
+      && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
+      && TREE_TYPE (t) == TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0))))
+    ary = TREE_OPERAND (ary, 0);
   if (TREE_CODE (ary) == CONSTRUCTOR)
     len = CONSTRUCTOR_NELTS (ary);
   else if (TREE_CODE (ary) == STRING_CST)
@@ -1991,6 +1995,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
                     / TYPE_PRECISION (char_type_node));
       len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
     }
+  else if (TREE_CODE (ary) == VECTOR_CST)
+    len = VECTOR_CST_NELTS (ary);
   else
     {
       /* We can't do anything with other tree codes, so use
@@ -2007,7 +2013,14 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
       return t;
     }
 
-  tree nelts = array_type_nelts_top (TREE_TYPE (ary));
+  tree nelts;
+  if (TREE_CODE (TREE_TYPE (ary)) == ARRAY_TYPE)
+    nelts = array_type_nelts_top (TREE_TYPE (ary));
+  else if (VECTOR_TYPE_P (TREE_TYPE (ary)))
+    nelts = size_int (TYPE_VECTOR_SUBPARTS (TREE_TYPE (ary)));
+  else
+    gcc_unreachable ();
+
   /* For VLAs, the number of elements won't be an integer constant.  */
   nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
                                        overflow_p);
@@ -2053,6 +2066,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
 
   if (TREE_CODE (ary) == CONSTRUCTOR)
     return (*CONSTRUCTOR_ELTS (ary))[i].value;
+  else if (TREE_CODE (ary) == VECTOR_CST)
+    return VECTOR_CST_ELT (ary, i);
   else if (elem_nchars == 1)
     return build_int_cst (cv_unqualified (TREE_TYPE (TREE_TYPE (ary))),
                          TREE_STRING_POINTER (ary)[i]);
index 61b395300e60e49cbf578b8b6dc9a839dfa4dd59..e879f3c5e8db079f8879834f4abaf0e6985423cb 100644 (file)
@@ -146,6 +146,7 @@ mark_exp_read (tree exp)
     case INDIRECT_REF:
     case FLOAT_EXPR:
     case NON_DEPENDENT_EXPR:
+    case VIEW_CONVERT_EXPR:
       mark_exp_read (TREE_OPERAND (exp, 0));
       break;
     case COMPOUND_EXPR:
index cd058fa258ec43f4a63b6b4a365adff5ca56bcd4..8b3fec66250913875d5cdd3e182eba0e01f7bd0d 100644 (file)
@@ -3161,8 +3161,7 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
       break;
     }
 
-  bool non_lvalue
-    = convert_vector_to_pointer_for_subscript (loc, &array, idx);
+  bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, idx);
 
   if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
     {
index 858f484442635090c7c625b313aed80a430769d6..83b7150998861fe916312578b42d5420a54ca4b2 100644 (file)
@@ -3459,6 +3459,44 @@ maybe_canonicalize_mem_ref_addr (tree *t)
   if (TREE_CODE (*t) == ADDR_EXPR)
     t = &TREE_OPERAND (*t, 0);
 
+  /* The C and C++ frontends use an ARRAY_REF for indexing with their
+     generic vector extension.  The actual vector referenced is
+     view-converted to an array type for this purpose.  If the index
+     is constant the canonical representation in the middle-end is a
+     BIT_FIELD_REF so re-write the former to the latter here.  */
+  if (TREE_CODE (*t) == ARRAY_REF
+      && TREE_CODE (TREE_OPERAND (*t, 0)) == VIEW_CONVERT_EXPR
+      && TREE_CODE (TREE_OPERAND (*t, 1)) == INTEGER_CST
+      && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0))))
+    {
+      tree vtype = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*t, 0), 0));
+      if (VECTOR_TYPE_P (vtype))
+       {
+         tree low = array_ref_low_bound (*t);
+         if (TREE_CODE (low) == INTEGER_CST)
+           {
+             if (tree_int_cst_le (low, TREE_OPERAND (*t, 1)))
+               {
+                 widest_int idx = wi::sub (wi::to_widest (TREE_OPERAND (*t, 1)),
+                                           wi::to_widest (low));
+                 idx = wi::mul (idx, wi::to_widest
+                                        (TYPE_SIZE (TREE_TYPE (*t))));
+                 widest_int ext
+                   = wi::add (idx, wi::to_widest (TYPE_SIZE (TREE_TYPE (*t))));
+                 if (wi::les_p (ext, wi::to_widest (TYPE_SIZE (vtype))))
+                   {
+                     *t = build3_loc (EXPR_LOCATION (*t), BIT_FIELD_REF,
+                                      TREE_TYPE (*t),
+                                      TREE_OPERAND (TREE_OPERAND (*t, 0), 0),
+                                      TYPE_SIZE (TREE_TYPE (*t)),
+                                      wide_int_to_tree (sizetype, idx));
+                     res = true;
+                   }
+               }
+           }
+       }
+    }
+
   while (handled_component_p (*t))
     t = &TREE_OPERAND (*t, 0);
 
index 32e95227be29d55575ac08d8bf355a4a361b27d1..65589fa4effe87a94c5358850bafc5bf60f0afe5 100644 (file)
@@ -1,3 +1,10 @@
+2016-05-24  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/70434
+       PR c/69504
+       * c-c++-common/vector-subscript-4.c: New testcase.
+       * c-c++-common/vector-subscript-5.c: Likewise.
+
 2016-05-23  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR fortran/71123
diff --git a/gcc/testsuite/c-c++-common/vector-subscript-4.c b/gcc/testsuite/c-c++-common/vector-subscript-4.c
new file mode 100644 (file)
index 0000000..2c2481f
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -w -Wno-psabi" } */
+
+#define foobar(n) \
+    typedef int v##n##si __attribute__ ((vector_size (4 * n))); \
+\
+int \
+foo##n(int x, v##n##si v) \
+{ \
+  v[0] ^= v[1]; \
+  return ((v##n##si)v)[x]; \
+} \
+\
+int \
+bar##n(int x, v##n##si v) \
+{ \
+  v[0] ^= v[1]; \
+  return v[x]; \
+}
+
+foobar(2)
+foobar(4)
+foobar(8)
+foobar(16)
+foobar(32)
+foobar(64)
+
+/* Verify we don't have any vector temporaries in the IL.  */
+/* { dg-final { scan-tree-dump-not "vector" "optimized" } } */
diff --git a/gcc/testsuite/c-c++-common/vector-subscript-5.c b/gcc/testsuite/c-c++-common/vector-subscript-5.c
new file mode 100644 (file)
index 0000000..58a94f0
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+
+typedef int U __attribute__ ((vector_size (16)));
+
+int
+foo (int i)
+{
+  register U u
+#if __SSE2__
+      asm ("xmm0");
+#endif
+  return u[i];
+}
index cf6e76405b3f8bd1563ee97c8a4afbb8c44d95a7..a53322d9837ed1b683fb3350df11b85151973f44 100644 (file)
@@ -1222,14 +1222,19 @@ maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming)
 static tree
 non_rewritable_mem_ref_base (tree ref)
 {
-  tree base = ref;
+  tree base;
 
   /* A plain decl does not need it set.  */
   if (DECL_P (ref))
     return NULL_TREE;
 
-  while (handled_component_p (base))
-    base = TREE_OPERAND (base, 0);
+  if (! (base = CONST_CAST_TREE (strip_invariant_refs (ref))))
+    {
+      base = get_base_address (ref);
+      if (DECL_P (base))
+       return base;
+      return NULL_TREE;
+    }
 
   /* But watch out for MEM_REFs we cannot lower to a
      VIEW_CONVERT_EXPR or a BIT_FIELD_REF.  */