summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-family/ChangeLog10
-rw-r--r--gcc/c-family/c-common.c60
-rw-r--r--gcc/c-family/c-common.h2
-rw-r--r--gcc/c/ChangeLog7
-rw-r--r--gcc/c/c-typeck.c7
-rw-r--r--gcc/cp/ChangeLog9
-rw-r--r--gcc/cp/constexpr.c17
-rw-r--r--gcc/cp/expr.c1
-rw-r--r--gcc/cp/typeck.c3
-rw-r--r--gcc/gimple-fold.c38
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/c-c++-common/vector-subscript-4.c29
-rw-r--r--gcc/testsuite/c-c++-common/vector-subscript-5.c13
-rw-r--r--gcc/tree-ssa.c11
15 files changed, 167 insertions, 56 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d4d12b14052..d94460e9419 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index f6ba9410200..7f0ca2d8057 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 146e8059c1a..4568cf62a98 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -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;
}
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 0ee9f567123..0295532d3ea 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -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 {
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index c65f2e9e5e0..9bb5ec1dfce 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -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
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 7c9b078ed1b..74bad2acc5d 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -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)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 9095576dd4a..eaf42b83f1c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index bb723f45b09..482f8afaeb6 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -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]);
diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 61b395300e6..e879f3c5e8d 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -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:
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index cd058fa258e..8b3fec66250 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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)
{
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 858f4844426..83b71509988 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -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);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 32e95227be2..65589fa4eff 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..2c2481f88b7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/vector-subscript-4.c
@@ -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
index 00000000000..58a94f0fb15
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/vector-subscript-5.c
@@ -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];
+}
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index cf6e76405b3..a53322d9837 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -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. */