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
This commit is contained in:
parent
64fc0cd9b2
commit
f17a223de8
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" } } */
|
|
@ -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];
|
||||
}
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue