aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtjoms Sinkarovs <artyom.shinkaroff@gmail.com>2010-10-22 20:03:33 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2010-10-22 20:03:33 +0000
commit30cd1c5d04c18770e8688d7199c20c2d528df1cd (patch)
tree172cd8381465be00018205c3573f8252e5a8a669
parent5c958bdaed6ab98447c6aa3bf6104086cd5954ce (diff)
downloadgcc-30cd1c5d04c18770e8688d7199c20c2d528df1cd.zip
gcc-30cd1c5d04c18770e8688d7199c20c2d528df1cd.tar.gz
gcc-30cd1c5d04c18770e8688d7199c20c2d528df1cd.tar.bz2
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/c-family/ChangeLog6
-rw-r--r--gcc/c-family/c-common.c12
-rw-r--r--gcc/c-family/c-common.h2
-rw-r--r--gcc/c-typeck.c32
-rw-r--r--gcc/doc/extend.texi6
-rw-r--r--gcc/testsuite/ChangeLog11
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/vector-subscript-1.c60
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/vector-subscript-2.c67
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/vector-subscript-3.c26
-rw-r--r--gcc/testsuite/gcc.dg/array-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/vector-subscript-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/vector-subscript-2.c13
-rw-r--r--gcc/testsuite/gcc.dg/vector-subscript-3.c19
14 files changed, 276 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e93c6c4..313ad11 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 2893062..93664f3 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -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.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 3716b5b..2f205ad 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 5aff415..f882a8f 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 9a7cdc5..1476b6d 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 d39ab48..0828ff1 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 1aa51a4..41020f8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
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 0000000..03647fd
--- /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 0000000..d0e5b88
--- /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 0000000..97d531c
--- /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 f50fe6d..d469a80 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 0000000..7cc50af
--- /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 0000000..3a8d522a
--- /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 0000000..55ed2b3
--- /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" } */
+}
+