This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]