This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: broken arithmetic operations on vectors (c and c++)
On Tue, Jun 14, 2005 at 02:50:40PM -0700, Richard Henderson wrote:
> On Tue, Jun 14, 2005 at 05:25:21PM -0400, Aldy Hernandez wrote:
> > The *_DIV_EXPR cases change code0/code1, which means we don't trigger
> > the error message anymore. So we either have to put the error message
> > before the switch or move the complex and vector handling of *_DIV_EXPR
> > after the switch.
> >
> > What is your preference?
>
> Change the DIV_EXPR cases to avoid clobbering code[01]. Use new
> local variables.
Aight... This is what I'm testing again.
Let me know...
* c-common.h (same_scalar_type_ignoring_signedness): Protoize.
* c-common.c (same_scalar_type_ignoring_signedness): New.
* c-typeck.c (build_binary_op): Check compatability of vector
types. Move error report after switch.
Do not clobber code[01] on *_DIV_EXPR case.
* cp/typeck.c (build_binary_op): Same.
* testsuite/g++.dg/conversion/simd3.C: New.
* testsuite/gcc.dg/simd-1.c: Update error messages.
* testsuite/gcc.dg/simd-1b.c: Re-enable tests. Update error
messages.
* testsuite/gcc.dg/simd-2.c: Update error messages.
* testsuite/gcc.dg/simd-3.c: New.
Index: c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.294
diff -c -p -r1.294 c-common.h
*** c-common.h 28 May 2005 01:38:07 -0000 1.294
--- c-common.h 15 Jun 2005 01:01:23 -0000
*************** extern tree convert_and_check (tree, tre
*** 657,662 ****
--- 657,663 ----
extern void overflow_warning (tree);
extern void unsigned_conversion_warning (tree, tree);
extern bool c_determine_visibility (tree);
+ extern bool same_scalar_type_ignoring_signedness (tree, tree);
#define c_sizeof(T) c_sizeof_or_alignof_type (T, true, 1)
#define c_alignof(T) c_sizeof_or_alignof_type (T, false, 1)
Index: c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.634
diff -c -p -r1.634 c-common.c
*** c-common.c 6 Jun 2005 19:31:24 -0000 1.634
--- c-common.c 15 Jun 2005 01:01:26 -0000
*************** resolve_overloaded_builtin (tree functio
*** 6030,6033 ****
--- 6030,6048 ----
}
}
+ /* Ignoring their sign, return true if two scalar types are the same. */
+ bool
+ same_scalar_type_ignoring_signedness (tree t1, tree t2)
+ {
+ enum tree_code c1 = TREE_CODE (t1), c2 = TREE_CODE (t2);
+
+ gcc_assert ((c1 == INTEGER_TYPE || c1 == REAL_TYPE)
+ && (c2 == INTEGER_TYPE || c2 == REAL_TYPE));
+
+ /* Equality works here because c_common_signed_type uses
+ TYPE_MAIN_VARIANT. */
+ return lang_hooks.types.signed_type (t1)
+ == lang_hooks.types.signed_type (t2);
+ }
+
#include "gt-c-common.h"
Index: c-typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-typeck.c,v
retrieving revision 1.450
diff -c -p -r1.450 c-typeck.c
*** c-typeck.c 7 Jun 2005 10:10:22 -0000 1.450
--- c-typeck.c 15 Jun 2005 01:01:29 -0000
*************** build_binary_op (enum tree_code code, tr
*** 7536,7547 ****
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
{
if (code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
! code0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
! code1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
! if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE))
resultcode = RDIV_EXPR;
else
/* Although it would be tempting to shorten always here, that
--- 7536,7549 ----
&& (code1 == INTEGER_TYPE || code1 == REAL_TYPE
|| code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE))
{
+ enum tree_code tcode0 = code0, tcode1 = code1;
+
if (code0 == COMPLEX_TYPE || code0 == VECTOR_TYPE)
! tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
if (code1 == COMPLEX_TYPE || code1 == VECTOR_TYPE)
! tcode1 = TREE_CODE (TREE_TYPE (TREE_TYPE (op1)));
! if (!(tcode0 == INTEGER_TYPE && tcode1 == INTEGER_TYPE))
resultcode = RDIV_EXPR;
else
/* Although it would be tempting to shorten always here, that
*************** build_binary_op (enum tree_code code, tr
*** 7781,7786 ****
--- 7783,7797 ----
if (code0 == ERROR_MARK || code1 == ERROR_MARK)
return error_mark_node;
+ if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
+ && (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
+ || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
+ TREE_TYPE (type1))))
+ {
+ binary_op_error (code);
+ return error_mark_node;
+ }
+
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE
|| code0 == VECTOR_TYPE)
&&
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.634
diff -c -p -r1.634 typeck.c
*** cp/typeck.c 10 Jun 2005 17:35:35 -0000 1.634
--- cp/typeck.c 15 Jun 2005 01:01:32 -0000
*************** build_binary_op (enum tree_code code, tr
*** 3181,3188 ****
/* Vector arithmetic is only allowed when both sides are vectors. */
if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
{
! if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1)))
! error ("can't convert between vector values of different size");
arithmetic_types_p = 1;
}
}
--- 3181,3193 ----
/* Vector arithmetic is only allowed when both sides are vectors. */
if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
{
! if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
! || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
! TREE_TYPE (type1)))
! {
! binary_op_error (code);
! return error_mark_node;
! }
arithmetic_types_p = 1;
}
}
Index: testsuite/g++.dg/conversion/simd3.C
===================================================================
RCS file: testsuite/g++.dg/conversion/simd3.C
diff -N testsuite/g++.dg/conversion/simd3.C
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/conversion/simd3.C 15 Jun 2005 01:01:32 -0000
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do compile } */
+
+ typedef int myint;
+
+ float __attribute__((vector_size(16))) b;
+ int __attribute__((vector_size(16))) d;
+ myint __attribute__((vector_size(16))) d2;
+ unsigned int __attribute__((vector_size(16))) e;
+
+ void foo()
+ {
+ b + d; /* { dg-error "invalid operands to binary" } */
+ d += e;
+ d2 += d;
+ }
Index: testsuite/gcc.dg/simd-1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/simd-1.c,v
retrieving revision 1.3
diff -c -p -r1.3 simd-1.c
*** testsuite/gcc.dg/simd-1.c 9 Jul 2004 23:20:35 -0000 1.3
--- testsuite/gcc.dg/simd-1.c 15 Jun 2005 01:01:32 -0000
*************** hanneke ()
*** 54,61 ****
a = -b;
/* Operators on incompatible SIMD types. */
! a = b + c; /* { dg-error "can't convert between vector values of different size" } */
! a = b - c; /* { dg-error "can't convert between vector values of different size" } */
! a = b * c; /* { dg-error "can't convert between vector values of different size" } */
! a = b / c; /* { dg-error "can't convert between vector values of different size" } */
}
--- 54,61 ----
a = -b;
/* Operators on incompatible SIMD types. */
! a = b + c; /* { dg-error "invalid operands to binary +" } */
! a = b - c; /* { dg-error "invalid operands to binary -" } */
! a = b * c; /* { dg-error "invalid operands to binary *" } */
! a = b / c; /* { dg-error "invalid operands to binary /" } */
}
Index: testsuite/gcc.dg/simd-1b.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/simd-1b.c,v
retrieving revision 1.1
diff -c -p -r1.1 simd-1b.c
*** testsuite/gcc.dg/simd-1b.c 9 Jul 2004 23:20:36 -0000 1.1
--- testsuite/gcc.dg/simd-1b.c 15 Jun 2005 01:01:32 -0000
*************** void
*** 14,36 ****
hanneke ()
{
/* Operators on compatible SIMD types. */
! a %= b; /* { dg-bogus "invalid operands to binary %" "" { xfail *-*-* } } */
c &= d;
a |= b;
c ^= d;
! a >>= b; /* { dg-bogus "invalid operands to binary >>" "" { xfail *-*-* } } */
! c <<= d; /* { dg-bogus "invalid operands to binary <<" "" { xfail *-*-* } } */
a = +b;
c = ~d;
/* Operators on incompatible SIMD types. */
! /* a = b % c; { dg*error "can't convert between vector values of different size" } */
! a = b % c; /* { dg-bogus "invalid operands to binary %" "" { xfail *-*-* } } */
! d = c & b; /* { dg-error "can't convert between vector values of different size" } */
! a = b | c; /* { dg-error "can't convert between vector values of different size" } */
! d = c ^ b; /* { dg-error "can't convert between vector values of different size" } */
! /* a = b >> c; { dg*error "can't convert between vector values of different size" } */
! a = b >> c; /* { dg-bogus "invalid operands to binary >>" "" { xfail *-*-* } } */
! /* d = c << b; { dg*error "can't convert between vector values of different size" } */
! d = c << b; /* { dg-bogus "invalid operands to binary <<" "" { xfail *-*-* } } */
}
--- 14,36 ----
hanneke ()
{
/* Operators on compatible SIMD types. */
! a %= b; /* { dg-error "invalid operands to binary %" } */
c &= d;
a |= b;
c ^= d;
! a >>= b; /* { dg-error "invalid operands to binary >>" } */
! c <<= d; /* { dg-error "invalid operands to binary <<" } */
a = +b;
c = ~d;
/* Operators on incompatible SIMD types. */
! a = b % c; /* { dg-error "invalid operands to binary" } */
! a = b % c; /* { dg-error "invalid operands to binary" } */
! d = c & b; /* { dg-error "invalid operands to binary" } */
! a = b | c; /* { dg-error "invalid operands to binary" } */
! d = c ^ b; /* { dg-error "invalid operands to binary" } */
! a = b >> c; /* { dg-error "invalid operands to binary" } */
! a = b >> c; /* { dg-error "invalid operands to binary" } */
! d = c << b; /* { dg-error "invalid operands to binary" } */
! d = c << b; /* { dg-error "invalid operands to binary" } */
}
Index: testsuite/gcc.dg/simd-2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gcc.dg/simd-2.c,v
retrieving revision 1.1
diff -c -p -r1.1 simd-2.c
*** testsuite/gcc.dg/simd-2.c 9 Jul 2004 23:20:36 -0000 1.1
--- testsuite/gcc.dg/simd-2.c 15 Jun 2005 01:01:32 -0000
*************** hanneke ()
*** 33,43 ****
foo = a; /* { dg-error "incompatible types in assignment" } */
/* Casted assignment between scalar and SIMD of same size. */
! foo = (typeof (foo)) foo2; /* { dg-bogus "aggregate value used where a float was expected" "" { xfail *-*-* } } */
/* Casted assignment between scalar and SIMD of different size. */
! /* foo1 = (typeof (foo1)) foo2; { dg*error "can't convert between vector values of different size" } */
! foo1 = (typeof (foo1)) foo2; /* { dg-bogus "aggregate value used where a float was expected" "" { xfail *-*-* } } */
/* Operators on compatible SIMD types. */
a += b + b;
--- 33,42 ----
foo = a; /* { dg-error "incompatible types in assignment" } */
/* Casted assignment between scalar and SIMD of same size. */
! foo = (typeof (foo)) foo2; /* { dg-error "aggregate value used where a float was expected" } */
/* Casted assignment between scalar and SIMD of different size. */
! foo1 = (typeof (foo1)) foo2; /* { dg-error "aggregate value used where a float was expected" } */
/* Operators on compatible SIMD types. */
a += b + b;
*************** hanneke ()
*** 48,55 ****
c = -d;
/* Operators on incompatible SIMD types. */
! a = b + c; /* { dg-error "can't convert between vector values of different size" } */
! a = b - c; /* { dg-error "can't convert between vector values of different size" } */
! a = b * c; /* { dg-error "can't convert between vector values of different size" } */
! a = b / c; /* { dg-error "can't convert between vector values of different size" } */
}
--- 47,54 ----
c = -d;
/* Operators on incompatible SIMD types. */
! a = b + c; /* { dg-error "invalid operands to binary" } */
! a = b - c; /* { dg-error "invalid operands to binary" } */
! a = b * c; /* { dg-error "invalid operands to binary" } */
! a = b / c; /* { dg-error "invalid operands to binary" } */
}
Index: testsuite/gcc.dg/simd-3.c
===================================================================
RCS file: testsuite/gcc.dg/simd-3.c
diff -N testsuite/gcc.dg/simd-3.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- testsuite/gcc.dg/simd-3.c 15 Jun 2005 01:01:32 -0000
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do compile } */
+
+ typedef int myint;
+
+ float __attribute__((vector_size(16))) b;
+ int __attribute__((vector_size(16))) d;
+ myint __attribute__((vector_size(16))) d2;
+ unsigned int __attribute__((vector_size(16))) e;
+
+ void foo()
+ {
+ b + d; /* { dg-error "invalid operands to binary" } */
+ d += e;
+ d2 += d;
+ }