From 30cd1c5d04c18770e8688d7199c20c2d528df1cd Mon Sep 17 00:00:00 2001 From: Artjoms Sinkarovs Date: Fri, 22 Oct 2010 20:03:33 +0000 Subject: [PATCH] c-typeck.c (build_array_ref): Handle subscripting of vectors. 2010-10-22 Artjoms Sinkarovs Andrew Pinski * 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 From-SVN: r165861 --- gcc/ChangeLog | 6 ++ gcc/c-family/ChangeLog | 6 ++ gcc/c-family/c-common.c | 12 ++++ gcc/c-family/c-common.h | 2 + gcc/c-typeck.c | 32 ++++++++- gcc/doc/extend.texi | 6 ++ gcc/testsuite/ChangeLog | 11 +++ .../execute/vector-subscript-1.c | 60 +++++++++++++++++ .../execute/vector-subscript-2.c | 67 +++++++++++++++++++ .../execute/vector-subscript-3.c | 26 +++++++ gcc/testsuite/gcc.dg/array-8.c | 2 +- gcc/testsuite/gcc.dg/vector-subscript-1.c | 17 +++++ gcc/testsuite/gcc.dg/vector-subscript-2.c | 13 ++++ gcc/testsuite/gcc.dg/vector-subscript-3.c | 19 ++++++ 14 files changed, 276 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/vector-subscript-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/vector-subscript-2.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/vector-subscript-3.c create mode 100644 gcc/testsuite/gcc.dg/vector-subscript-1.c create mode 100644 gcc/testsuite/gcc.dg/vector-subscript-2.c create mode 100644 gcc/testsuite/gcc.dg/vector-subscript-3.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e93c6c49fff..313ad111080 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-10-22 Artjoms Sinkarovs + Andrew Pinski + + * c-typeck.c (build_array_ref): Handle subscripting of vectors. + * doc/extend.texi: New paragraph + 2010-10-22 Paul Koning * config.pdp11/pdp11.h (DBX_DEBUGGING_INFO): Define. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 2893062b119..93664f35337 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,9 @@ +2010-10-22 Artjoms Sinkarovs + Andrew Pinski + + * c-common.h (c_common_mark_addressable_vec): Declare. + * c-common.c (c_common_mark_addressable_vec): New function. + 2010-10-20 Nicola Pero * c-common.h (objc_set_method_type): Removed. diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 3716b5b14c4..2f205adf3ec 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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. diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 5aff415ff7e..f882a8f87f8 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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, diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 9a7cdc51c46..1476b6d4ffc 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -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) { diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index d39ab487b97..0828ff1d2de 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1aa51a459bf..41020f8bbbf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2010-10-22 Artjoms Sinkarovs + Andrew Pinski + + * 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 PR middle-end/46137 diff --git a/gcc/testsuite/gcc.c-torture/execute/vector-subscript-1.c b/gcc/testsuite/gcc.c-torture/execute/vector-subscript-1.c new file mode 100644 index 00000000000..03647fd5074 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vector-subscript-1.c @@ -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; +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/vector-subscript-2.c b/gcc/testsuite/gcc.c-torture/execute/vector-subscript-2.c new file mode 100644 index 00000000000..d0e5b889c66 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vector-subscript-2.c @@ -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; +} + diff --git a/gcc/testsuite/gcc.c-torture/execute/vector-subscript-3.c b/gcc/testsuite/gcc.c-torture/execute/vector-subscript-3.c new file mode 100644 index 00000000000..97d531c1733 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/vector-subscript-3.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/array-8.c b/gcc/testsuite/gcc.dg/array-8.c index f50fe6db06e..d469a80eaf2 100644 --- a/gcc/testsuite/gcc.dg/array-8.c +++ b/gcc/testsuite/gcc.dg/array-8.c @@ -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" } */ diff --git a/gcc/testsuite/gcc.dg/vector-subscript-1.c b/gcc/testsuite/gcc.dg/vector-subscript-1.c new file mode 100644 index 00000000000..7cc50af999b --- /dev/null +++ b/gcc/testsuite/gcc.dg/vector-subscript-1.c @@ -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]; +} + diff --git a/gcc/testsuite/gcc.dg/vector-subscript-2.c b/gcc/testsuite/gcc.dg/vector-subscript-2.c new file mode 100644 index 00000000000..3a8d522ad42 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vector-subscript-2.c @@ -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]; +} + diff --git a/gcc/testsuite/gcc.dg/vector-subscript-3.c b/gcc/testsuite/gcc.dg/vector-subscript-3.c new file mode 100644 index 00000000000..55ed2b37025 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vector-subscript-3.c @@ -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" } */ +} +