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:
parent
5c958bdaed
commit
30cd1c5d04
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
60
gcc/testsuite/gcc.c-torture/execute/vector-subscript-1.c
Normal file
60
gcc/testsuite/gcc.c-torture/execute/vector-subscript-1.c
Normal 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;
|
||||
}
|
||||
|
67
gcc/testsuite/gcc.c-torture/execute/vector-subscript-2.c
Normal file
67
gcc/testsuite/gcc.c-torture/execute/vector-subscript-2.c
Normal 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;
|
||||
}
|
||||
|
26
gcc/testsuite/gcc.c-torture/execute/vector-subscript-3.c
Normal file
26
gcc/testsuite/gcc.c-torture/execute/vector-subscript-3.c
Normal 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;
|
||||
}
|
@ -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" } */
|
||||
|
17
gcc/testsuite/gcc.dg/vector-subscript-1.c
Normal file
17
gcc/testsuite/gcc.dg/vector-subscript-1.c
Normal 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];
|
||||
}
|
||||
|
13
gcc/testsuite/gcc.dg/vector-subscript-2.c
Normal file
13
gcc/testsuite/gcc.dg/vector-subscript-2.c
Normal 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];
|
||||
}
|
||||
|
19
gcc/testsuite/gcc.dg/vector-subscript-3.c
Normal file
19
gcc/testsuite/gcc.dg/vector-subscript-3.c
Normal 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" } */
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user