+2012-09-14 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/54427
+ * fold-const.c (fold_unary_loc): Disable for VECTOR_TYPE.
+ (fold_binary_loc): Likewise.
+ * gimple-fold.c (and_comparisons_1): Handle VECTOR_TYPE.
+ (or_comparisons_1): Likewise.
+
2012-09-14 Richard Earnshaw <rearnsha@arm.com>
PR target/54516
+2012-09-14 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/54427
+ * typeck.c (cp_build_binary_op) [LSHIFT_EXPR, RSHIFT_EXPR, EQ_EXPR,
+ NE_EXPR, LE_EXPR, GE_EXPR, LT_EXPR, GT_EXPR]: Handle VECTOR_TYPE.
+
2012-09-14 Paolo Carlini <paolo.carlini@oracle.com>
* decl.c (make_typename_type): Only error out if tf_error is set
Also set SHORT_SHIFT if shifting rightward. */
case RSHIFT_EXPR:
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
+ && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1))
+ {
+ result_type = type0;
+ converted = 1;
+ }
+ else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;
if (TREE_CODE (op1) == INTEGER_CST)
break;
case LSHIFT_EXPR:
- if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && TREE_CODE (TREE_TYPE (type0)) == INTEGER_TYPE
+ && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE
+ && TYPE_VECTOR_SUBPARTS (type0) == TYPE_VECTOR_SUBPARTS (type1))
+ {
+ result_type = type0;
+ converted = 1;
+ }
+ else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
result_type = type0;
if (TREE_CODE (op1) == INTEGER_CST)
case EQ_EXPR:
case NE_EXPR:
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+ goto vector_compare;
if ((complain & tf_warning)
&& (FLOAT_TYPE_P (type0) || FLOAT_TYPE_P (type1)))
warning (OPT_Wfloat_equal,
warning (OPT_Waddress, "comparison with string literal results in unspecified behaviour");
}
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
+ {
+ vector_compare:
+ tree intt;
+ if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
+ TREE_TYPE (type1)))
+ {
+ error_at (location, "comparing vectors with different "
+ "element types");
+ inform (location, "operand types are %qT and %qT", type0, type1);
+ return error_mark_node;
+ }
+
+ if (TYPE_VECTOR_SUBPARTS (type0) != TYPE_VECTOR_SUBPARTS (type1))
+ {
+ error_at (location, "comparing vectors with different "
+ "number of elements");
+ inform (location, "operand types are %qT and %qT", type0, type1);
+ return error_mark_node;
+ }
+
+ /* Always construct signed integer vector type. */
+ intt = c_common_type_for_size (GET_MODE_BITSIZE
+ (TYPE_MODE (TREE_TYPE (type0))), 0);
+ result_type = build_opaque_vector_type (intt,
+ TYPE_VECTOR_SUBPARTS (type0));
+ converted = 1;
+ break;
+ }
build_type = boolean_type_node;
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
|| code0 == ENUMERAL_TYPE)
return build2_loc (loc, TREE_CODE (op0), type,
TREE_OPERAND (op0, 0),
TREE_OPERAND (op0, 1));
- else if (!INTEGRAL_TYPE_P (type))
+ else if (!INTEGRAL_TYPE_P (type) && TREE_CODE (type) != VECTOR_TYPE)
return build3_loc (loc, COND_EXPR, type, op0,
constant_boolean_node (true, type),
constant_boolean_node (false, type));
if ((code == BIT_AND_EXPR || code == BIT_IOR_EXPR
|| code == EQ_EXPR || code == NE_EXPR)
+ && TREE_CODE (type) != VECTOR_TYPE
&& ((truth_value_p (TREE_CODE (arg0))
&& (truth_value_p (TREE_CODE (arg1))
|| (TREE_CODE (arg1) == BIT_AND_EXPR
#include "tree-ssa-propagate.h"
#include "target.h"
#include "gimple-fold.h"
+#include "langhooks.h"
/* Return true when DECL can be referenced from current unit.
FROM_DECL (if non-null) specify constructor of variable DECL was taken from.
and_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
enum tree_code code2, tree op2a, tree op2b)
{
+ tree truth_type = boolean_type_node;
+ if (TREE_CODE (TREE_TYPE (op1a)) == VECTOR_TYPE)
+ {
+ tree vec_type = TREE_TYPE (op1a);
+ tree elem = lang_hooks.types.type_for_size
+ (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vec_type))), 0);
+ truth_type = build_opaque_vector_type (elem,
+ TYPE_VECTOR_SUBPARTS (vec_type));
+ }
+
/* First check for ((x CODE1 y) AND (x CODE2 y)). */
if (operand_equal_p (op1a, op2a, 0)
&& operand_equal_p (op1b, op2b, 0))
/* Result will be either NULL_TREE, or a combined comparison. */
tree t = combine_comparisons (UNKNOWN_LOCATION,
TRUTH_ANDIF_EXPR, code1, code2,
- boolean_type_node, op1a, op1b);
+ truth_type, op1a, op1b);
if (t)
return t;
}
tree t = combine_comparisons (UNKNOWN_LOCATION,
TRUTH_ANDIF_EXPR, code1,
swap_tree_comparison (code2),
- boolean_type_node, op1a, op1b);
+ truth_type, op1a, op1b);
if (t)
return t;
}
or_comparisons_1 (enum tree_code code1, tree op1a, tree op1b,
enum tree_code code2, tree op2a, tree op2b)
{
+ tree truth_type = boolean_type_node;
+ if (TREE_CODE (TREE_TYPE (op1a)) == VECTOR_TYPE)
+ {
+ tree vec_type = TREE_TYPE (op1a);
+ tree elem = lang_hooks.types.type_for_size
+ (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (vec_type))), 0);
+ truth_type = build_opaque_vector_type (elem,
+ TYPE_VECTOR_SUBPARTS (vec_type));
+ }
+
/* First check for ((x CODE1 y) OR (x CODE2 y)). */
if (operand_equal_p (op1a, op2a, 0)
&& operand_equal_p (op1b, op2b, 0))
/* Result will be either NULL_TREE, or a combined comparison. */
tree t = combine_comparisons (UNKNOWN_LOCATION,
TRUTH_ORIF_EXPR, code1, code2,
- boolean_type_node, op1a, op1b);
+ truth_type, op1a, op1b);
if (t)
return t;
}
tree t = combine_comparisons (UNKNOWN_LOCATION,
TRUTH_ORIF_EXPR, code1,
swap_tree_comparison (code2),
- boolean_type_node, op1a, op1b);
+ truth_type, op1a, op1b);
if (t)
return t;
}
+2012-09-14 Marc Glisse <marc.glisse@inria.fr>
+
+ PR c++/54427
+ * g++.dg/other/vector-compare.C: New testcase.
+ * gcc/testsuite/c-c++-common/vector-compare-3.c: New testcase.
+ * gcc.dg/vector-shift.c: Move ...
+ * c-c++-common/vector-shift.c: ... here.
+ * gcc.dg/vector-shift1.c: Move ...
+ * c-c++-common/vector-shift1.c: ... here.
+ * gcc.dg/vector-shift3.c: Move ...
+ * c-c++-common/vector-shift3.c: ... here.
+ * gcc.dg/vector-compare-1.c: Move ...
+ * c-c++-common/vector-compare-1.c: ... here.
+ * gcc.dg/vector-compare-2.c: Move ...
+ * c-c++-common/vector-compare-2.c: ... here.
+ * gcc.c-torture/execute/vector-compare-1.c: Move ...
+ * c-c++-common/torture/vector-compare-1.c: ... here.
+ * gcc.c-torture/execute/vector-compare-2.x: Delete.
+ * gcc.c-torture/execute/vector-compare-2.c: Move ...
+ * c-c++-common/torture/vector-compare-2.c: ... here.
+ * gcc.c-torture/execute/vector-shift.c: Move ...
+ * c-c++-common/torture/vector-shift.c: ... here.
+ * gcc.c-torture/execute/vector-shift2.c: Move ...
+ * c-c++-common/torture/vector-shift2.c: ... here.
+ * gcc.c-torture/execute/vector-subscript-1.c: Move ...
+ * c-c++-common/torture/vector-subscript-1.c: ... here.
+ * gcc.c-torture/execute/vector-subscript-2.c: Move ...
+ * c-c++-common/torture/vector-subscript-2.c: ... here.
+ * gcc.c-torture/execute/vector-subscript-3.c: Move ...
+ * c-c++-common/torture/vector-subscript-3.c: ... here.
+
2012-09-14 Joseph Myers <joseph@codesourcery.com>
PR c/54103
--- /dev/null
+/* { dg-do run } */
+#define vector(elcount, type) \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+#define check_compare(count, res, i0, i1, op, fmt) \
+do { \
+ int __i; \
+ for (__i = 0; __i < count; __i ++) { \
+ if ((res)[__i] != ((i0)[__i] op (i1)[__i] ? -1 : 0)) \
+ { \
+ __builtin_printf ("%i != ((" fmt " " #op " " fmt " ? -1 : 0) ", \
+ (res)[__i], (i0)[__i], (i1)[__i]); \
+ __builtin_abort (); \
+ } \
+ } \
+} while (0)
+
+#define test(count, v0, v1, res, fmt); \
+do { \
+ res = (v0 > v1); \
+ check_compare (count, res, v0, v1, >, fmt); \
+ res = (v0 < v1); \
+ check_compare (count, res, v0, v1, <, fmt); \
+ res = (v0 >= v1); \
+ check_compare (count, res, v0, v1, >=, fmt); \
+ res = (v0 <= v1); \
+ check_compare (count, res, v0, v1, <=, fmt); \
+ res = (v0 == v1); \
+ check_compare (count, res, v0, v1, ==, fmt); \
+ res = (v0 != v1); \
+ check_compare (count, res, v0, v1, !=, fmt); \
+} while (0)
+
+
+int main (int argc, char *argv[]) {
+#define INT int
+ vector (4, INT) i0;
+ vector (4, INT) i1;
+ vector (4, int) ires;
+ int i;
+
+ i0 = (vector (4, INT)){(INT)argc, 1, 2, 10};
+ i1 = (vector (4, INT)){0, 3, 2, (INT)-23};
+ test (4, i0, i1, ires, "%i");
+#undef INT
+
+#define INT unsigned int
+ vector (4, int) ures;
+ vector (4, INT) u0;
+ vector (4, INT) u1;
+
+ u0 = (vector (4, INT)){(INT)argc, 1, 2, 10};
+ u1 = (vector (4, INT)){0, 3, 2, (INT)-23};
+ test (4, u0, u1, ures, "%u");
+#undef INT
+
+
+#define SHORT short
+ vector (8, SHORT) s0;
+ vector (8, SHORT) s1;
+ vector (8, short) sres;
+
+ s0 = (vector (8, SHORT)){(SHORT)argc, 1, 2, 10, 6, 87, (SHORT)-5, 2};
+ s1 = (vector (8, SHORT)){0, 3, 2, (SHORT)-23, 12, 10, (SHORT)-2, 0};
+ test (8, s0, s1, sres, "%i");
+#undef SHORT
+
+#define SHORT unsigned short
+ vector (8, SHORT) us0;
+ vector (8, SHORT) us1;
+ vector (8, short) usres;
+
+ us0 = (vector (8, SHORT)){(SHORT)argc, 1, 2, 10, 6, 87, (SHORT)-5, 2};
+ us1 = (vector (8, SHORT)){0, 3, 2, (SHORT)-23, 12, 10, (SHORT)-2, 0};
+ test (8, us0, us1, usres, "%u");
+#undef SHORT
+
+#define CHAR signed char
+ vector (16, CHAR) c0;
+ vector (16, CHAR) c1;
+ vector (16, signed char) cres;
+
+ c0 = (vector (16, CHAR)){(CHAR)argc, 1, 2, 10, 6, 87, (CHAR)-5, 2, \
+ (CHAR)argc, 1, 2, 10, 6, 87, (CHAR)-5, 2 };
+
+ c1 = (vector (16, CHAR)){0, 3, 2, (CHAR)-23, 12, 10, (CHAR)-2, 0, \
+ 0, 3, 2, (CHAR)-23, 12, 10, (CHAR)-2, 0};
+ test (16, c0, c1, cres, "%i");
+#undef CHAR
+
+#define CHAR unsigned char
+ vector (16, CHAR) uc0;
+ vector (16, CHAR) uc1;
+ vector (16, signed char) ucres;
+
+ uc0 = (vector (16, CHAR)){(CHAR)argc, 1, 2, 10, 6, 87, (CHAR)-5, 2, \
+ (CHAR)argc, 1, 2, 10, 6, 87, (CHAR)-5, 2 };
+
+ uc1 = (vector (16, CHAR)){0, 3, 2, (CHAR)-23, 12, 10, (CHAR)-2, 0, \
+ 0, 3, 2, (CHAR)-23, 12, 10, (CHAR)-2, 0};
+ test (16, uc0, uc1, ucres, "%u");
+#undef CHAR
+/* Float comparison. */
+ vector (4, float) f0;
+ vector (4, float) f1;
+ __typeof (f0 == f1) ifres;
+
+ f0 = (vector (4, float)){(float)argc, 1., 2., 10.};
+ f1 = (vector (4, float)){0., 3., 2., (float)-23};
+ test (4, f0, f1, ifres, "%f");
+
+/* Double comparison. */
+ vector (2, double) d0;
+ vector (2, double) d1;
+ __typeof (d0 == d1) idres;
+
+ d0 = (vector (2, double)){(double)argc, 10.};
+ d1 = (vector (2, double)){0., (double)-23};
+ test (2, d0, d1, idres, "%f");
+
+
+ return 0;
+}
+
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-Wno-psabi" } */
+#define vector(elcount, type) \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+/* Check that constant folding in
+ these simple cases works. */
+vector (4, int)
+foo (vector (4, int) x)
+{
+ return (x == x) + (x != x) + (x > x)
+ + (x < x) + (x >= x) + (x <= x);
+}
+
+int
+main (int argc, char *argv[])
+{
+ vector (4, int) t = {argc, 2, argc, 42};
+ vector (4, int) r;
+ int i;
+
+ r = foo (t);
+
+ for (i = 0; i < 4; i++)
+ if (r[i] != -3)
+ __builtin_abort ();
+
+ return 0;
+}
--- /dev/null
+/* { dg-do run } */
+
+#define vector __attribute__((vector_size(sizeof(int)*4) ))
+
+static vector int allones = {1, 1, 1, 1};
+static vector int allzeros = {0, 0, 0, 0};
+static vector int numbers = {0, 1, 2, 3};
+static vector int numbersleftshiftallones = {0, 2, 4, 6};
+static vector int numbersrightshiftallones = {0, 0, 1, 1};
+
+
+static vector unsigned int uallones = {1, 1, 1, 1};
+static vector unsigned int uallzeros = {0, 0, 0, 0};
+static vector unsigned int unumbers = {0, 1, 2, 3};
+static vector unsigned int unumbersleftshiftallones = {0, 2, 4, 6};
+static vector unsigned int unumbersrightshiftallones = {0, 0, 1, 1};
+
+#define TEST(result, expected) \
+do { \
+ __typeof__(result) result1 = result; \
+ if(sizeof (result1) != sizeof (expected)) \
+ __builtin_abort (); \
+ if (__builtin_memcmp (&result1, &expected, sizeof(result1)) != 0) \
+ __builtin_abort (); \
+}while (0);
+
+int main(void)
+{
+ vector int result;
+ TEST ((numbers << allzeros), numbers);
+ TEST ((numbers >> allzeros), numbers);
+ TEST((numbers << allones), numbersleftshiftallones);
+ TEST((numbers >> allones), numbersrightshiftallones);
+ /* Test left shift followed by a right shift, numbers should be back as
+ numbers are all small numbers and no lose of precision happens. */
+ TEST((numbers << allones) >> allones, numbers);
+
+
+
+ TEST ((unumbers << uallzeros), unumbers);
+ TEST ((unumbers >> uallzeros), unumbers);
+ TEST((unumbers << uallones), unumbersleftshiftallones);
+ TEST((unumbers >> uallones), unumbersrightshiftallones);
+ /* Test left shift followed by a right shift, numbers should be back as
+ numbers are all small numbers and no lose of precision happens. */
+ TEST((unumbers << uallones) >> uallones, unumbers);
+
+ return 0;
+}
--- /dev/null
+/* { dg-do run } */
+#define vector(elcount, type) \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+#define vidx(type, vec, idx) (*((type *) &(vec) + idx))
+#define uint unsigned int
+
+int main (int argc, char *argv[]) {
+ vector(4, uint) vuint = { 1, 2, 3, 4};
+ vector(4, int) vint0 = { 1, 1, 1, 1};
+ vector(4, int) vint1 = {-1, -1, -1, -1};
+
+ vector(4, int) i1, i2, i3;
+ vector(4, uint) u1, u2, u3;
+
+ i1 = vint1<< vint0;
+
+ if (vidx(int, i1, 0) != ((int)-1 << (int)1))
+ __builtin_abort ();
+ if (vidx(int, i1, 1) != ((int)-1 << (int)1))
+ __builtin_abort ();
+ if (vidx(int, i1, 2) != ((int)-1 << (int)1))
+ __builtin_abort ();
+ if (vidx(int, i1, 3) != ((int)-1 << (int)1))
+ __builtin_abort ();
+
+ u1 = vuint << vint0;
+
+ if (vidx(int, u1, 0) != ((uint)1 << (int)1))
+ __builtin_abort ();
+ if (vidx(int, u1, 1) != ((uint)2 << (int)1))
+ __builtin_abort ();
+ if (vidx(int, u1, 2) != ((uint)3 << (int)1))
+ __builtin_abort ();
+ if (vidx(int, u1, 3) != ((uint)4 << (int)1))
+ __builtin_abort ();
+
+
+ i2 = vint1 >> vuint;
+
+ if (vidx(int, i2, 0) != ((int)-1 >> (uint)1))
+ __builtin_abort ();
+ if (vidx(int, i2, 1) != ((int)-1 >> (uint)2))
+ __builtin_abort ();
+ if (vidx(int, i2, 2) != ((int)-1 >> (uint)3))
+ __builtin_abort ();
+ if (vidx(int, i2, 3) != ((int)-1 >> (uint)4))
+ __builtin_abort ();
+
+
+ vint1 >>= vuint;
+
+ vuint <<= vint0;
+ vuint <<= vint1;
+
+
+ return 0;
+}
+
+
--- /dev/null
+/* { 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, sizeof(a));
+ for(i = 0; i < 4; i++)
+ if (a[i] != i+1)
+ __builtin_abort ();
+
+
+ return 0;
+}
+
--- /dev/null
+/* { 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 (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;
+}
+
--- /dev/null
+/* { 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;
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-mabi=altivec" { target { { powerpc*-*-linux* } && ilp32 } } } */
+/* { dg-prune-output "operand types are" } */
+
+#define vector(elcount, type) \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+void
+foo (vector (4, int) x, vector (4, float) y)
+{
+ vector (4, int) p4;
+ vector (4, int) r4;
+ vector (4, unsigned int) q4;
+ vector (8, int) r8;
+ vector (4, float) f4;
+
+ r4 = x > y; /* { dg-error "comparing vectors with different element types" } */
+ r8 = (x != p4); /* { dg-error "incompatible types when assigning to type|cannot convert" } */
+ r8 == r4; /* { dg-error "comparing vectors with different number of elements" } */
+}
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-fno-common" { target hppa*-*-hpux* } } */
+/* { dg-options "-mabi=altivec" { target { { powerpc*-*-linux* } && ilp32 } } } */
+
+/* Test if C_MAYBE_CONST are folded correctly when
+ creating VEC_COND_EXPR. */
+
+typedef int vec __attribute__((vector_size(16)));
+
+vec i,j;
+extern vec a, b, c;
+
+extern int p, q, z;
+extern vec foo (int);
+
+vec
+foo (int x)
+{
+ return foo (p ? q :z) > a;
+}
+
+vec
+bar (int x)
+{
+ return b > foo (p ? q :z);
+}
+
+
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef int v4i __attribute__((vector_size(4*sizeof(int))));
+
+// fold should not turn (vec_other)(x<y) into (x<y)?vec_other(-1):vec_other(0).
+
+void use (v4i const *z);
+
+void
+f (v4i *x, v4i *y)
+{
+ v4i const zz = *x < *y;
+ use (&zz);
+}
+
+// Optimizations shouldn't introduce a boolean type in there
+
+void
+g (v4i *x, v4i const *y, v4i *z, v4i *t)
+{
+ *z = *x < *y | *x == *y;
+ *t = *x < *y & *x > *y;
+}
+
--- /dev/null
+/* { dg-do compile } */
+/* { dg-prune-output "in evaluation of" } */
+#define vector(elcount, type) \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+int main (int argc, char *argv[]) {
+ vector(4,char) vchar = {1,2,3,4};
+ vector(4, int) vint = {1,1,1,1};
+
+ vint <<= vchar; /* { dg-error "nvalid operands to binary <<" } */
+ vchar >>= vint; /* { dg-error "nvalid operands to binary >>" } */
+
+ return 0;
+}
+
--- /dev/null
+/* { dg-do compile } */
+/* { dg-prune-output "in evaluation of" } */
+#define vector(elcount, type) \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+int main (int argc, char *argv[]) {
+ vector(4, float) vfloat0 = {1., 2., 3., 4.};
+ vector(4, float) vfloat1 = {1., 2., 3., 4.};
+
+ vector(4, int) vint = {1, 1, 1, 1 };
+
+ vint <<= vfloat0; /* { dg-error "nvalid operands to binary <<" } */
+ vfloat0 >>= vint; /* { dg-error "nvalid operands to binary >>" } */
+
+ vfloat0 <<= vfloat1; /* { dg-error "nvalid operands" } */
+
+ return 0;
+}
+
--- /dev/null
+/* { dg-do compile } */
+
+#define vector(elcount, type) \
+__attribute__((vector_size((elcount)*sizeof(type)))) type
+
+
+int main (int argc, char *argv[]) {
+ vector(8, short) v0 = {(short)argc,2,3,4,5,6,7};
+ short sc;
+
+
+ scalar1 <<= v0; /* { dg-error "scalar1.*(undeclared|was not declared)" } */
+
+ return 0;
+}
+
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-std=gnu++11 -Wall" } */
+
+// Check that we can compare vector types that really are the same through
+// typedefs.
+
+typedef float v4f __attribute__((vector_size(4*sizeof(float))));
+
+template <class T> void eat (T&&) {}
+
+template <class T, int n>
+struct Vec
+{
+ typedef T type __attribute__((vector_size(4*sizeof(T))));
+
+ template <class U>
+ static void fun (type const& t, U& u) { eat (t > u); }
+};
+
+long long
+f (v4f *x, v4f const *y)
+{
+ return ((*x < *y) | (*x <= *y))[2];
+}
+
+int main ()
+{
+ v4f x = {0,1,2,3};
+ Vec<const volatile float,4>::type f = {-1,5,2,3.1};
+ auto c = (x == f) == (x >= x);
+ eat (c[3]);
+ Vec<const volatile float,4>::fun (f, x);
+ Vec<const volatile float,4>::fun (x, f);
+ Vec<const volatile float,4>::fun (f, f);
+ Vec<const volatile float,4>::fun (x, x);
+}
+++ /dev/null
-#define vector(elcount, type) \
-__attribute__((vector_size((elcount)*sizeof(type)))) type
-
-#define check_compare(count, res, i0, i1, op, fmt) \
-do { \
- int __i; \
- for (__i = 0; __i < count; __i ++) { \
- if ((res)[__i] != ((i0)[__i] op (i1)[__i] ? -1 : 0)) \
- { \
- __builtin_printf ("%i != ((" fmt " " #op " " fmt " ? -1 : 0) ", \
- (res)[__i], (i0)[__i], (i1)[__i]); \
- __builtin_abort (); \
- } \
- } \
-} while (0)
-
-#define test(count, v0, v1, res, fmt); \
-do { \
- res = (v0 > v1); \
- check_compare (count, res, v0, v1, >, fmt); \
- res = (v0 < v1); \
- check_compare (count, res, v0, v1, <, fmt); \
- res = (v0 >= v1); \
- check_compare (count, res, v0, v1, >=, fmt); \
- res = (v0 <= v1); \
- check_compare (count, res, v0, v1, <=, fmt); \
- res = (v0 == v1); \
- check_compare (count, res, v0, v1, ==, fmt); \
- res = (v0 != v1); \
- check_compare (count, res, v0, v1, !=, fmt); \
-} while (0)
-
-
-int main (int argc, char *argv[]) {
-#define INT int
- vector (4, INT) i0;
- vector (4, INT) i1;
- vector (4, int) ires;
- int i;
-
- i0 = (vector (4, INT)){argc, 1, 2, 10};
- i1 = (vector (4, INT)){0, 3, 2, (INT)-23};
- test (4, i0, i1, ires, "%i");
-#undef INT
-
-#define INT unsigned int
- vector (4, int) ures;
- vector (4, INT) u0;
- vector (4, INT) u1;
-
- u0 = (vector (4, INT)){argc, 1, 2, 10};
- u1 = (vector (4, INT)){0, 3, 2, (INT)-23};
- test (4, u0, u1, ures, "%u");
-#undef INT
-
-
-#define SHORT short
- vector (8, SHORT) s0;
- vector (8, SHORT) s1;
- vector (8, short) sres;
-
- s0 = (vector (8, SHORT)){argc, 1, 2, 10, 6, 87, (SHORT)-5, 2};
- s1 = (vector (8, SHORT)){0, 3, 2, (SHORT)-23, 12, 10, (SHORT)-2, 0};
- test (8, s0, s1, sres, "%i");
-#undef SHORT
-
-#define SHORT unsigned short
- vector (8, SHORT) us0;
- vector (8, SHORT) us1;
- vector (8, short) usres;
-
- us0 = (vector (8, SHORT)){argc, 1, 2, 10, 6, 87, (SHORT)-5, 2};
- us1 = (vector (8, SHORT)){0, 3, 2, (SHORT)-23, 12, 10, (SHORT)-2, 0};
- test (8, us0, us1, usres, "%u");
-#undef SHORT
-
-#define CHAR signed char
- vector (16, CHAR) c0;
- vector (16, CHAR) c1;
- vector (16, signed char) cres;
-
- c0 = (vector (16, CHAR)){argc, 1, 2, 10, 6, 87, (CHAR)-5, 2, \
- argc, 1, 2, 10, 6, 87, (CHAR)-5, 2 };
-
- c1 = (vector (16, CHAR)){0, 3, 2, (CHAR)-23, 12, 10, (CHAR)-2, 0, \
- 0, 3, 2, (CHAR)-23, 12, 10, (CHAR)-2, 0};
- test (16, c0, c1, cres, "%i");
-#undef CHAR
-
-#define CHAR unsigned char
- vector (16, CHAR) uc0;
- vector (16, CHAR) uc1;
- vector (16, signed char) ucres;
-
- uc0 = (vector (16, CHAR)){argc, 1, 2, 10, 6, 87, (CHAR)-5, 2, \
- argc, 1, 2, 10, 6, 87, (CHAR)-5, 2 };
-
- uc1 = (vector (16, CHAR)){0, 3, 2, (CHAR)-23, 12, 10, (CHAR)-2, 0, \
- 0, 3, 2, (CHAR)-23, 12, 10, (CHAR)-2, 0};
- test (16, uc0, uc1, ucres, "%u");
-#undef CHAR
-/* Float comparison. */
- vector (4, float) f0;
- vector (4, float) f1;
- __typeof (f0 == f1) ifres;
-
- f0 = (vector (4, float)){(float)argc, 1., 2., 10.};
- f1 = (vector (4, float)){0., 3., 2., (float)-23};
- test (4, f0, f1, ifres, "%f");
-
-/* Double comparison. */
- vector (2, double) d0;
- vector (2, double) d1;
- __typeof (d0 == d1) idres;
-
- d0 = (vector (2, double)){(double)argc, 10.};
- d1 = (vector (2, double)){0., (double)-23};
- test (2, d0, d1, idres, "%f");
-
-
- return 0;
-}
-
+++ /dev/null
-#define vector(elcount, type) \
-__attribute__((vector_size((elcount)*sizeof(type)))) type
-
-/* Check that constant folding in
- these simple cases works. */
-vector (4, int)
-foo (vector (4, int) x)
-{
- return (x == x) + (x != x) + (x > x)
- + (x < x) + (x >= x) + (x <= x);
-}
-
-int
-main (int argc, char *argv[])
-{
- vector (4, int) t = {argc, 2, argc, 42};
- vector (4, int) r;
- int i;
-
- r = foo (t);
-
- for (i = 0; i < 4; i++)
- if (r[i] != -3)
- __builtin_abort ();
-
- return 0;
-}
+++ /dev/null
-set additional_flags "-Wno-psabi"
-return 0
+++ /dev/null
-
-#define vector __attribute__((vector_size(sizeof(int)*4) ))
-
-static vector int allones = {1, 1, 1, 1};
-static vector int allzeros = {0, 0, 0, 0};
-static vector int numbers = {0, 1, 2, 3};
-static vector int numbersleftshiftallones = {0, 2, 4, 6};
-static vector int numbersrightshiftallones = {0, 0, 1, 1};
-
-
-static vector unsigned int uallones = {1, 1, 1, 1};
-static vector unsigned int uallzeros = {0, 0, 0, 0};
-static vector unsigned int unumbers = {0, 1, 2, 3};
-static vector unsigned int unumbersleftshiftallones = {0, 2, 4, 6};
-static vector unsigned int unumbersrightshiftallones = {0, 0, 1, 1};
-
-#define TEST(result, expected) \
-do { \
- typeof(result) result1 = result; \
- if(sizeof (result1) != sizeof (expected)) \
- __builtin_abort (); \
- if (__builtin_memcmp (&result1, &expected, sizeof(result1)) != 0) \
- __builtin_abort (); \
-}while (0);
-
-int main(void)
-{
- vector int result;
- TEST ((numbers << allzeros), numbers);
- TEST ((numbers >> allzeros), numbers);
- TEST((numbers << allones), numbersleftshiftallones);
- TEST((numbers >> allones), numbersrightshiftallones);
- /* Test left shift followed by a right shift, numbers should be back as
- numbers are all small numbers and no lose of precision happens. */
- TEST((numbers << allones) >> allones, numbers);
-
-
-
- TEST ((unumbers << uallzeros), unumbers);
- TEST ((unumbers >> uallzeros), unumbers);
- TEST((unumbers << uallones), unumbersleftshiftallones);
- TEST((unumbers >> uallones), unumbersrightshiftallones);
- /* Test left shift followed by a right shift, numbers should be back as
- numbers are all small numbers and no lose of precision happens. */
- TEST((unumbers << uallones) >> uallones, unumbers);
-
- return 0;
-}
+++ /dev/null
-#define vector(elcount, type) \
-__attribute__((vector_size((elcount)*sizeof(type)))) type
-
-#define vidx(type, vec, idx) (*((type *) &(vec) + idx))
-#define uint unsigned int
-
-int main (int argc, char *argv[]) {
- vector(4, uint) vuint = { 1, 2, 3, 4};
- vector(4, int) vint0 = { 1, 1, 1, 1};
- vector(4, int) vint1 = {-1, -1, -1, -1};
-
- vector(4, int) i1, i2, i3;
- vector(4, uint) u1, u2, u3;
-
- i1 = vint1<< vint0;
-
- if (vidx(int, i1, 0) != ((int)-1 << (int)1))
- __builtin_abort ();
- if (vidx(int, i1, 1) != ((int)-1 << (int)1))
- __builtin_abort ();
- if (vidx(int, i1, 2) != ((int)-1 << (int)1))
- __builtin_abort ();
- if (vidx(int, i1, 3) != ((int)-1 << (int)1))
- __builtin_abort ();
-
- u1 = vuint << vint0;
-
- if (vidx(int, u1, 0) != ((uint)1 << (int)1))
- __builtin_abort ();
- if (vidx(int, u1, 1) != ((uint)2 << (int)1))
- __builtin_abort ();
- if (vidx(int, u1, 2) != ((uint)3 << (int)1))
- __builtin_abort ();
- if (vidx(int, u1, 3) != ((uint)4 << (int)1))
- __builtin_abort ();
-
-
- i2 = vint1 >> vuint;
-
- if (vidx(int, i2, 0) != ((int)-1 >> (uint)1))
- __builtin_abort ();
- if (vidx(int, i2, 1) != ((int)-1 >> (uint)2))
- __builtin_abort ();
- if (vidx(int, i2, 2) != ((int)-1 >> (uint)3))
- __builtin_abort ();
- if (vidx(int, i2, 3) != ((int)-1 >> (uint)4))
- __builtin_abort ();
-
-
- vint1 >>= vuint;
-
- vuint <<= vint0;
- vuint <<= vint1;
-
-
- return 0;
-}
-
-
+++ /dev/null
-/* 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, sizeof(a));
- for(i = 0; i < 4; i++)
- if (a[i] != i+1)
- __builtin_abort ();
-
-
- return 0;
-}
-
+++ /dev/null
-#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;
-}
-
+++ /dev/null
-/* 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;
-}
+++ /dev/null
-/* { dg-do compile } */
-/* { dg-options "-mabi=altivec" { target { { powerpc*-*-linux* } && ilp32 } } } */
-
-#define vector(elcount, type) \
-__attribute__((vector_size((elcount)*sizeof(type)))) type
-
-void
-foo (vector (4, int) x, vector (4, float) y)
-{
- vector (4, int) p4;
- vector (4, int) r4;
- vector (4, unsigned int) q4;
- vector (8, int) r8;
- vector (4, float) f4;
-
- r4 = x > y; /* { dg-error "comparing vectors with different element types" } */
- r8 = (x != p4); /* { dg-error "incompatible types when assigning to type" } */
- r8 == r4; /* { dg-error "comparing vectors with different number of elements" } */
-}
+++ /dev/null
-/* { dg-do compile } */
-/* { dg-options "-fno-common" { target hppa*-*-hpux* } } */
-/* { dg-options "-mabi=altivec" { target { { powerpc*-*-linux* } && ilp32 } } } */
-
-/* Test if C_MAYBE_CONST are folded correctly when
- creating VEC_COND_EXPR. */
-
-typedef int vec __attribute__((vector_size(16)));
-
-vec i,j;
-extern vec a, b, c;
-
-extern int p, q, z;
-extern vec foo (int);
-
-vec
-foo (int x)
-{
- return foo (p ? q :z) > a;
-}
-
-vec
-bar (int x)
-{
- return b > foo (p ? q :z);
-}
-
-
+++ /dev/null
-/* { dg-do compile } */
-#define vector(elcount, type) \
-__attribute__((vector_size((elcount)*sizeof(type)))) type
-
-int main (int argc, char *argv[]) {
- vector(4,char) vchar = {1,2,3,4};
- vector(4, int) vint = {1,1,1,1};
-
- vint <<= vchar; /* { dg-error "nvalid operands to binary <<" } */
- vchar >>= vint; /* { dg-error "nvalid operands to binary >>" } */
-
- return 0;
-}
-
+++ /dev/null
-/* { dg-do compile } */
-#define vector(elcount, type) \
-__attribute__((vector_size((elcount)*sizeof(type)))) type
-
-int main (int argc, char *argv[]) {
- vector(4, float) vfloat0 = {1., 2., 3., 4.};
- vector(4, float) vfloat1 = {1., 2., 3., 4.};
-
- vector(4, int) vint = {1, 1, 1, 1 };
-
- vint <<= vfloat0; /* { dg-error "nvalid operands to binary <<" } */
- vfloat0 >>= vint; /* { dg-error "nvalid operands to binary >>" } */
-
- vfloat0 <<= vfloat1; /* { dg-error "nvalid operands to binary <<" } */
-
- return 0;
-}
-
+++ /dev/null
-/* { dg-do compile } */
-
-#define vector(elcount, type) \
-__attribute__((vector_size((elcount)*sizeof(type)))) type
-
-
-int main (int argc, char *argv[]) {
- vector(8, short) v0 = {argc,2,3,4,5,6,7};
- short sc;
-
-
- scalar1 <<= v0; /* { dg-error ".*scalar1.*undeclared" } */
-
- return 0;
-}
-