c-typeck.c (build_array_ref): Handle subscripting of vectors.

2010-10-22  Artjoms Sinkarovs <artyom.shinakroff@gmail.com>
	Andrew Pinski <pinskia@gmail.com>

	* c-typeck.c (build_array_ref): Handle subscripting of vectors.
	* doc/extend.texi: New paragraph

	c-family/
	* c-common.h (c_common_mark_addressable_vec): Declare.
	* c-common.c (c_common_mark_addressable_vec): New function.

	testsuite/
	* gcc.c-torture/execute/vector-subscript-1.c: Likewise.
	* gcc.c-torture/execute/vector-subscript-2.c: Likewise.
	* gcc.c-torture/execute/vector-subscript-3.c: New testcase.
	* gcc.dg/vector-subscript-1.c: Likewise.
	* gcc.dg/vector-subscript-2.c: Likewise.
	* gcc.dg/vector-subscript-3.c: New testcase.
	* gcc.dg/array-8.c: Adjust.

Co-Authored-By: Andrew Pinski <pinskia@gmail.com>

From-SVN: r165861
This commit is contained in:
Artjoms Sinkarovs 2010-10-22 20:03:33 +00:00 committed by Richard Biener
parent 5c958bdaed
commit 30cd1c5d04
14 changed files with 276 additions and 3 deletions

View File

@ -1,3 +1,9 @@
2010-10-22 Artjoms Sinkarovs <artyom.shinakroff@gmail.com>
Andrew Pinski <pinskia@gmail.com>
* c-typeck.c (build_array_ref): Handle subscripting of vectors.
* doc/extend.texi: New paragraph
2010-10-22 Paul Koning <ni1d@arrl.net>
* config.pdp11/pdp11.h (DBX_DEBUGGING_INFO): Define.

View File

@ -1,3 +1,9 @@
2010-10-22 Artjoms Sinkarovs <artyom.shinakroff@gmail.com>
Andrew Pinski <pinskia@gmail.com>
* c-common.h (c_common_mark_addressable_vec): Declare.
* c-common.c (c_common_mark_addressable_vec): New function.
2010-10-20 Nicola Pero <nicola.pero@meta-innovation.com>
* c-common.h (objc_set_method_type): Removed.

View File

@ -8703,6 +8703,18 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
return failure;
}
/* Like c_mark_addressable but don't check register qualifier. */
void
c_common_mark_addressable_vec (tree t)
{
while (handled_component_p (t))
t = TREE_OPERAND (t, 0);
if (TREE_CODE (t) != VAR_DECL && TREE_CODE (t) != PARM_DECL)
return;
TREE_ADDRESSABLE (t) = 1;
}
/* Used to help initialize the builtin-types.def table. When a type of
the correct size doesn't exist, use error_mark_node instead of NULL.

View File

@ -931,6 +931,8 @@ extern int complete_array_type (tree *, tree, bool);
extern tree builtin_type_for_size (int, bool);
extern void c_common_mark_addressable_vec (tree);
extern void warn_array_subscript_with_type_char (tree);
extern void warn_about_parentheses (enum tree_code,
enum tree_code, tree,

View File

@ -2305,6 +2305,9 @@ build_indirect_ref (location_t loc, tree ptr, ref_operator errstring)
arrays that are not lvalues (for example, members of structures returned
by functions).
For vector types, allow vector[i] but not i[vector], and create
*(((type*)&vectortype) + i) for the expression.
LOC is the location to use for the returned expression. */
tree
@ -2317,13 +2320,17 @@ build_array_ref (location_t loc, tree array, tree index)
return error_mark_node;
if (TREE_CODE (TREE_TYPE (array)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE)
&& TREE_CODE (TREE_TYPE (array)) != POINTER_TYPE
/* Allow vector[index] but not index[vector]. */
&& TREE_CODE (TREE_TYPE (array)) != VECTOR_TYPE)
{
tree temp;
if (TREE_CODE (TREE_TYPE (index)) != ARRAY_TYPE
&& TREE_CODE (TREE_TYPE (index)) != POINTER_TYPE)
{
error_at (loc, "subscripted value is neither array nor pointer");
error_at (loc,
"subscripted value is neither array nor pointer nor vector");
return error_mark_node;
}
temp = array;
@ -2353,6 +2360,27 @@ build_array_ref (location_t loc, tree array, tree index)
index = default_conversion (index);
gcc_assert (TREE_CODE (TREE_TYPE (index)) == INTEGER_TYPE);
/* For vector[index], convert the vector to a
pointer of the underlying type. */
if (TREE_CODE (TREE_TYPE (array)) == VECTOR_TYPE)
{
tree type = TREE_TYPE (array);
tree type1;
if (TREE_CODE (index) == INTEGER_CST)
if (!host_integerp (index, 1)
|| ((unsigned HOST_WIDE_INT) tree_low_cst (index, 1)
>= TYPE_VECTOR_SUBPARTS (TREE_TYPE (array))))
warning_at (loc, OPT_Warray_bounds, "index value is out of bound");
c_common_mark_addressable_vec (array);
type = build_qualified_type (TREE_TYPE (type), TYPE_QUALS (type));
type = build_pointer_type (type);
type1 = build_pointer_type (TREE_TYPE (array));
array = build1 (ADDR_EXPR, type1, array);
array = convert (type, array);
}
if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE)
{

View File

@ -6310,6 +6310,12 @@ minus or complement operators on a vector type is a vector whose
elements are the negative or complemented values of the corresponding
elements in the operand.
In C vectors can be subscripted as if the vector were an array with
the same number of elements and base type. Out of bound accesses
invoke undefined behavior at runtime. Warnings for out of bound
accesses for vector subscription can be enabled with
@option{-Warray-bounds}.
You can declare variables and use them in function calls and returns, as
well as in assignments and some casts. You can specify a vector type as
a return type for a function. Vector types can also be used as function

View File

@ -1,3 +1,14 @@
2010-10-22 Artjoms Sinkarovs <artyom.shinakroff@gmail.com>
Andrew Pinski <pinskia@gmail.com>
* gcc.c-torture/execute/vector-subscript-1.c: Likewise.
* gcc.c-torture/execute/vector-subscript-2.c: Likewise.
* gcc.c-torture/execute/vector-subscript-3.c: New testcase.
* gcc.dg/vector-subscript-1.c: Likewise.
* gcc.dg/vector-subscript-2.c: Likewise.
* gcc.dg/vector-subscript-3.c: New testcase.
* gcc.dg/array-8.c: Adjust.
2010-10-22 Richard Guenther <rguenther@suse.de>
PR middle-end/46137

View File

@ -0,0 +1,60 @@
/* dg-do run */
#define vector __attribute__((vector_size(sizeof(int)*4) ))
/* Check to make sure that we extract and insert the vector at the same
location for vector subscripting and that vectors layout are the same
as arrays. */
struct TV4
{
vector int v;
};
typedef struct TV4 MYV4;
static inline int *f(MYV4 *a, int i)
{
return &(a->v[i]);
}
static inline MYV4 myfunc2( int x, int y, int z, int w )
{
MYV4 temp;
*f(&temp, 0 ) = x;
*f(&temp, 1 ) = y;
*f(&temp, 2 ) = z;
*f(&temp, 3 ) = w;
return temp;
}
MYV4 val3;
__attribute__((noinline)) void modify (void)
{
val3 = myfunc2( 1, 2, 3, 4 );
}
int main( int argc, char* argv[] )
{
int a[4];
int i;
modify();
if (*f(&val3, 0 ) != 1)
__builtin_abort ();
if (*f(&val3, 1 ) != 2)
__builtin_abort ();
if (*f(&val3, 2 ) != 3)
__builtin_abort ();
if (*f(&val3, 3 ) != 4)
__builtin_abort ();
__builtin_memcpy(a, &val3, 16);
for(i = 0; i < 4; i++)
if (a[i] != i+1)
__builtin_abort ();
return 0;
}

View File

@ -0,0 +1,67 @@
#define vector __attribute__((vector_size(sizeof(int)*4) ))
/* Check to make sure that we extract and insert the vector at the same
location for vector subscripting (with constant indexes) and
that vectors layout are the same as arrays. */
struct TV4
{
vector int v;
};
typedef struct TV4 MYV4;
static inline MYV4 myfunc2( int x, int y, int z, int w )
{
MYV4 temp;
temp.v[0] = x;
temp.v[1] = y;
temp.v[2] = z;
temp.v[3] = w;
return temp;
}
MYV4 val3;
__attribute__((noinline)) void modify (void)
{
val3 = myfunc2( 1, 2, 3, 4 );
}
int main( int argc, char* argv[] )
{
int a[4];
int i;
/* Set up the vector. */
modify();
/* Check the vector via the global variable. */
if (val3.v[0] != 1)
__builtin_abort ();
if (val3.v[1] != 2)
__builtin_abort ();
if (val3.v[2] != 3)
__builtin_abort ();
if (val3.v[3] != 4)
__builtin_abort ();
vector int a1 = val3.v;
/* Check the vector via a local variable. */
if (a1[0] != 1)
__builtin_abort ();
if (a1[1] != 2)
__builtin_abort ();
if (a1[2] != 3)
__builtin_abort ();
if (a1[3] != 4)
__builtin_abort ();
__builtin_memcpy(a, &val3, sizeof(a));
/* Check the vector via copying it to an array. */
for(i = 0; i < 4; i++)
if (a[i] != i+1)
__builtin_abort ();
return 0;
}

View File

@ -0,0 +1,26 @@
/* dg-do run */
#define vector __attribute__((vector_size(16) ))
/* Check whether register declaration of vector type still
allow us to subscript this type. */
typedef vector short myvec_t;
struct vec_s {
vector short member;
};
int main () {
register short vector v0 = {1,2,3,4,5,6,7};
register myvec_t v1 = {1,2,3,4,5,6,7};
register struct vec_s v2;
v2.member = v1;
short r = v0[0] + v1[1] + v2.member[2];
if (r != 6)
__builtin_abort ();
return 0;
}

View File

@ -35,7 +35,7 @@ g (void)
f().c[0];
0[f().c];
/* Various invalid cases. */
c[c]; /* { dg-error "subscripted value is neither array nor pointer" } */
c[c]; /* { dg-error "subscripted value is neither array nor pointer nor vector" } */
p[1.0]; /* { dg-error "array subscript is not an integer" } */
1.0[a]; /* { dg-error "array subscript is not an integer" } */
fp[0]; /* { dg-error "subscripted value is pointer to function" } */

View File

@ -0,0 +1,17 @@
/* { dg-do compile } */
/* { dg-options "-w" } */
#define vector __attribute__((vector_size(16) ))
/* Check that vector[index] works and index[vector] is rejected. */
float vf(vector float a)
{
return 0[a]; /* { dg-error "subscripted value is neither array nor pointer nor vector" } */
}
float fv(vector float a)
{
return a[0];
}

View File

@ -0,0 +1,13 @@
/* { dg-do compile } */
/* Check that subscripting of vectors work with register storage class decls. */
#define vector __attribute__((vector_size(16) ))
float vf(int i)
{
register vector float a;
return a[0];
}

View File

@ -0,0 +1,19 @@
/* Check the case when index is out of bound */
/* { dg-do compile } */
/* { dg-options "-Warray-bounds" } */
#define vector __attribute__((vector_size(16) ))
int test0(void)
{
vector int a;
return a[10]; /* { dg-warning "index value is out of bound" } */
}
int test1(void)
{
vector int a;
return a[-1]; /* { dg-warning "index value is out of bound" } */
}