From patchwork Fri Jun 11 14:56:42 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Shinkarov X-Patchwork-Id: 55334 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id F2641B7D8A for ; Sat, 12 Jun 2010 00:57:22 +1000 (EST) Received: (qmail 11612 invoked by alias); 11 Jun 2010 14:57:20 -0000 Received: (qmail 11582 invoked by uid 22791); 11 Jun 2010 14:57:16 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mail-bw0-f47.google.com (HELO mail-bw0-f47.google.com) (209.85.214.47) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 11 Jun 2010 14:57:05 +0000 Received: by bwz14 with SMTP id 14so470517bwz.20 for ; Fri, 11 Jun 2010 07:57:02 -0700 (PDT) Received: by 10.204.46.201 with SMTP id k9mr1377899bkf.89.1276268222624; Fri, 11 Jun 2010 07:57:02 -0700 (PDT) MIME-Version: 1.0 Received: by 10.204.56.20 with HTTP; Fri, 11 Jun 2010 07:56:42 -0700 (PDT) From: Artem Shinkarov Date: Fri, 11 Jun 2010 15:56:42 +0100 Message-ID: Subject: Vector subscription patch To: gcc-patches@gcc.gnu.org Cc: Richard Guenther X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This is a reworked version of Andrew Pinski's vector subscription patch. The work done in terms of GSoC 2010 project. Improvements: The C and C++ parts now separated, the current patch is a C part. The commonly used function is moved to c-common.c. Bound-checking is enabled when -Warray-bounds are on. The patch was approved by C maintainers, but the code was never commited because of unapproved C++ parts. ChangeLog: 2010-06-10 Artem Shinkarov Andrew Pinski * c-family/c-common.h (c_common_mark_addressable_vec): Declare. * c-family/c-common.c (c_common_mark_addressable_vec): New function. * c-typeck.c (build_array_ref): Handle subscripting of vectors. 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.c-torture/execute/vector-subscript-4.c: New testcase. * gcc.dg/vector-subscript-1.c: Likewise. * gcc.dg/vector-subscript-2.c: Likewise. * gcc.dg/array-8.c: Adjust. doc/ * extend.texi: New paragraph bootstrapped and tested on x86_64_unknown-linux Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 160551) +++ gcc/doc/extend.texi (working copy) @@ -6141,6 +6141,11 @@ elements are the negative or complemented values of the corresponding elements in the operand. +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 Index: gcc/c-family/c-common.c =================================================================== --- gcc/c-family/c-common.c (revision 160551) +++ gcc/c-family/c-common.c (working copy) @@ -8577,6 +8577,18 @@ 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. Index: gcc/c-family/c-common.h =================================================================== --- gcc/c-family/c-common.h (revision 160551) +++ gcc/c-family/c-common.h (working copy) @@ -877,6 +877,8 @@ 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, Index: gcc/testsuite/gcc.c-torture/execute/vector-subscript-3.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/vector-subscript-3.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/vector-subscript-3.c (revision 0) @@ -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" } */ +} + Index: gcc/testsuite/gcc.c-torture/execute/vector-subscript-2.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/vector-subscript-2.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/vector-subscript-2.c (revision 0) @@ -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; +} + Index: gcc/testsuite/gcc.c-torture/execute/vector-subscript-4.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/vector-subscript-4.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/vector-subscript-4.c (revision 0) @@ -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; +} Index: gcc/testsuite/gcc.c-torture/execute/vector-subscript-1.c =================================================================== --- gcc/testsuite/gcc.c-torture/execute/vector-subscript-1.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/vector-subscript-1.c (revision 0) @@ -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; +} + Index: gcc/testsuite/gcc.dg/array-8.c =================================================================== --- gcc/testsuite/gcc.dg/array-8.c (revision 160551) +++ gcc/testsuite/gcc.dg/array-8.c (working copy) @@ -35,7 +35,7 @@ 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" } */ Index: gcc/testsuite/gcc.dg/vector-subscript-1.c =================================================================== --- gcc/testsuite/gcc.dg/vector-subscript-1.c (revision 0) +++ gcc/testsuite/gcc.dg/vector-subscript-1.c (revision 0) @@ -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 "" } */ +} + + +float fv(vector float a) +{ + return a[0]; +} + Index: gcc/testsuite/gcc.dg/vector-subscript-2.c =================================================================== --- gcc/testsuite/gcc.dg/vector-subscript-2.c (revision 0) +++ gcc/testsuite/gcc.dg/vector-subscript-2.c (revision 0) @@ -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]; +} + Index: gcc/c-typeck.c =================================================================== --- gcc/c-typeck.c (revision 160551) +++ gcc/c-typeck.c (working copy) @@ -2290,6 +2290,9 @@ 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 @@ -2302,13 +2305,17 @@ 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; @@ -2338,7 +2345,28 @@ 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) { tree rval, type;