Commit f17a223d by Richard Biener Committed by Richard Biener

re PR middle-end/70434 (adding an extraneous cast to vector type results in inferior code)

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
parent 64fc0cd9
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> 2016-05-24 Kugan Vivekanandarajah <kuganv@linaro.org>
PR middle-end/71170 PR middle-end/71170
......
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> 2016-05-12 Marek Polacek <polacek@redhat.com>
PR c/70756 PR c/70756
......
...@@ -12496,66 +12496,34 @@ build_userdef_literal (tree suffix_id, tree value, ...@@ -12496,66 +12496,34 @@ build_userdef_literal (tree suffix_id, tree value,
return literal; return literal;
} }
/* For vector[index], convert the vector to a /* For vector[index], convert the vector to an array of the underlying type.
pointer of the underlying type. Return true if the resulting Return true if the resulting ARRAY_REF should not be an lvalue. */
ARRAY_REF should not be an lvalue. */
bool bool
convert_vector_to_pointer_for_subscript (location_t loc, convert_vector_to_array_for_subscript (location_t loc,
tree *vecp, tree index) tree *vecp, tree index)
{ {
bool ret = false; bool ret = false;
if (VECTOR_TYPE_P (TREE_TYPE (*vecp))) if (VECTOR_TYPE_P (TREE_TYPE (*vecp)))
{ {
tree type = TREE_TYPE (*vecp); tree type = TREE_TYPE (*vecp);
tree type1;
ret = !lvalue_p (*vecp); ret = !lvalue_p (*vecp);
if (TREE_CODE (index) == INTEGER_CST) if (TREE_CODE (index) == INTEGER_CST)
if (!tree_fits_uhwi_p (index) if (!tree_fits_uhwi_p (index)
|| tree_to_uhwi (index) >= TYPE_VECTOR_SUBPARTS (type)) || tree_to_uhwi (index) >= TYPE_VECTOR_SUBPARTS (type))
warning_at (loc, OPT_Warray_bounds, "index value is out of bound"); warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
if (ret) /* 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
tree tmp = create_tmp_var_raw (type); for function parameters. */
DECL_SOURCE_LOCATION (tmp) = loc; c_common_mark_addressable_vec (*vecp);
*vecp = c_save_expr (*vecp);
if (TREE_CODE (*vecp) == C_MAYBE_CONST_EXPR) *vecp = build1 (VIEW_CONVERT_EXPR,
{ build_array_type_nelts (TREE_TYPE (type),
bool non_const = C_MAYBE_CONST_EXPR_NON_CONST (*vecp); TYPE_VECTOR_SUBPARTS (type)),
*vecp = C_MAYBE_CONST_EXPR_EXPR (*vecp); *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);
} }
return ret; return ret;
} }
......
...@@ -1368,7 +1368,7 @@ extern tree build_userdef_literal (tree suffix_id, tree value, ...@@ -1368,7 +1368,7 @@ extern tree build_userdef_literal (tree suffix_id, tree value,
enum overflow_type overflow, enum overflow_type overflow,
tree num_string); 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. */ /* Possibe cases of scalar_to_vector conversion. */
enum stv_conv { enum stv_conv {
......
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> 2016-05-20 Martin Sebor <msebor@redhat.com>
PR c/71115 PR c/71115
......
...@@ -2583,8 +2583,8 @@ build_array_ref (location_t loc, tree array, tree index) ...@@ -2583,8 +2583,8 @@ build_array_ref (location_t loc, tree array, tree index)
gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE); gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
bool non_lvalue bool was_vector = VECTOR_TYPE_P (TREE_TYPE (array));
= convert_vector_to_pointer_for_subscript (loc, &array, index); bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, index);
if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE) if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
{ {
...@@ -2613,7 +2613,8 @@ build_array_ref (location_t loc, tree array, tree index) ...@@ -2613,7 +2613,8 @@ build_array_ref (location_t loc, tree array, tree index)
return error_mark_node; return error_mark_node;
} }
if (pedantic || warn_c90_c99_compat) if ((pedantic || warn_c90_c99_compat)
&& ! was_vector)
{ {
tree foo = array; tree foo = array;
while (TREE_CODE (foo) == COMPONENT_REF) while (TREE_CODE (foo) == COMPONENT_REF)
......
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> 2016-05-23 Jason Merrill <jason@redhat.com>
PR c++/70344 PR c++/70344
......
...@@ -1983,6 +1983,10 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, ...@@ -1983,6 +1983,10 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
else if (lval) else if (lval)
return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL); return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
elem_type = TREE_TYPE (TREE_TYPE (ary)); 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) if (TREE_CODE (ary) == CONSTRUCTOR)
len = CONSTRUCTOR_NELTS (ary); len = CONSTRUCTOR_NELTS (ary);
else if (TREE_CODE (ary) == STRING_CST) else if (TREE_CODE (ary) == STRING_CST)
...@@ -1991,6 +1995,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, ...@@ -1991,6 +1995,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
/ TYPE_PRECISION (char_type_node)); / TYPE_PRECISION (char_type_node));
len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars; len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
} }
else if (TREE_CODE (ary) == VECTOR_CST)
len = VECTOR_CST_NELTS (ary);
else else
{ {
/* We can't do anything with other tree codes, so use /* 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, ...@@ -2007,7 +2013,14 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
return 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. */ /* For VLAs, the number of elements won't be an integer constant. */
nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p, nelts = cxx_eval_constant_expression (ctx, nelts, false, non_constant_p,
overflow_p); overflow_p);
...@@ -2053,6 +2066,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, ...@@ -2053,6 +2066,8 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
if (TREE_CODE (ary) == CONSTRUCTOR) if (TREE_CODE (ary) == CONSTRUCTOR)
return (*CONSTRUCTOR_ELTS (ary))[i].value; return (*CONSTRUCTOR_ELTS (ary))[i].value;
else if (TREE_CODE (ary) == VECTOR_CST)
return VECTOR_CST_ELT (ary, i);
else if (elem_nchars == 1) else if (elem_nchars == 1)
return build_int_cst (cv_unqualified (TREE_TYPE (TREE_TYPE (ary))), return build_int_cst (cv_unqualified (TREE_TYPE (TREE_TYPE (ary))),
TREE_STRING_POINTER (ary)[i]); TREE_STRING_POINTER (ary)[i]);
......
...@@ -146,6 +146,7 @@ mark_exp_read (tree exp) ...@@ -146,6 +146,7 @@ mark_exp_read (tree exp)
case INDIRECT_REF: case INDIRECT_REF:
case FLOAT_EXPR: case FLOAT_EXPR:
case NON_DEPENDENT_EXPR: case NON_DEPENDENT_EXPR:
case VIEW_CONVERT_EXPR:
mark_exp_read (TREE_OPERAND (exp, 0)); mark_exp_read (TREE_OPERAND (exp, 0));
break; break;
case COMPOUND_EXPR: case COMPOUND_EXPR:
......
...@@ -3161,8 +3161,7 @@ cp_build_array_ref (location_t loc, tree array, tree idx, ...@@ -3161,8 +3161,7 @@ cp_build_array_ref (location_t loc, tree array, tree idx,
break; break;
} }
bool non_lvalue bool non_lvalue = convert_vector_to_array_for_subscript (loc, &array, idx);
= convert_vector_to_pointer_for_subscript (loc, &array, idx);
if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE) if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
{ {
......
...@@ -3459,6 +3459,44 @@ maybe_canonicalize_mem_ref_addr (tree *t) ...@@ -3459,6 +3459,44 @@ maybe_canonicalize_mem_ref_addr (tree *t)
if (TREE_CODE (*t) == ADDR_EXPR) if (TREE_CODE (*t) == ADDR_EXPR)
t = &TREE_OPERAND (*t, 0); 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)) while (handled_component_p (*t))
t = &TREE_OPERAND (*t, 0); t = &TREE_OPERAND (*t, 0);
......
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> 2016-05-23 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/71123 PR fortran/71123
......
/* { 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" } } */
/* { 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];
}
...@@ -1222,14 +1222,19 @@ maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming) ...@@ -1222,14 +1222,19 @@ maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming)
static tree static tree
non_rewritable_mem_ref_base (tree ref) non_rewritable_mem_ref_base (tree ref)
{ {
tree base = ref; tree base;
/* A plain decl does not need it set. */ /* A plain decl does not need it set. */
if (DECL_P (ref)) if (DECL_P (ref))
return NULL_TREE; return NULL_TREE;
while (handled_component_p (base)) if (! (base = CONST_CAST_TREE (strip_invariant_refs (ref))))
base = TREE_OPERAND (base, 0); {
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 /* But watch out for MEM_REFs we cannot lower to a
VIEW_CONVERT_EXPR or a BIT_FIELD_REF. */ VIEW_CONVERT_EXPR or a BIT_FIELD_REF. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment