From patchwork Fri Aug 31 22:22:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 181063 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 14FFA2C035F for ; Sat, 1 Sep 2012 08:22:43 +1000 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1347056564; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Date:From:To:cc:Subject:In-Reply-To:Message-ID:References: User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence: List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=HvzEcL6N0KOZfusyrGaSnkJk+xQ=; b=iBUzfZpLUXwf2y+ aQDtriX4jqekt1YWkpVsfX8WP6f83B3inekkbrOztaHtH0Zyej8j+HqGViWLaaiB DePYBxJwAQsFne4WOivGGUcelENZSPT048SIybnhPEF3IgWauY91XIjf5TOermfv bDiZv+cj7fVWM7OFq6f6eEFIF2Fo= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Date:From:To:cc:Subject:In-Reply-To:Message-ID:References:User-Agent:MIME-Version:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=Gmr+arNhqcmrX0XyVwM48C761L2UOTPkm+xpmxwSAoh15Z9/3QUI/hgGjfxqOC LHK9Prlc5y1ZdILXkVTOjqeWT88VuvNl3CV06DwOhBc2EWThaoq2YKsSTMb3cB8H O8rkPCFh0X/CbJgReRWONKXIH1DM4KozTYOvchoa1G66Y=; Received: (qmail 28407 invoked by alias); 31 Aug 2012 22:22:39 -0000 Received: (qmail 28394 invoked by uid 22791); 31 Aug 2012 22:22:37 -0000 X-SWARE-Spam-Status: No, hits=-7.7 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, KHOP_THREADED, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, TW_VF X-Spam-Check-By: sourceware.org Received: from mail1-relais-roc.national.inria.fr (HELO mail1-relais-roc.national.inria.fr) (192.134.164.82) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 31 Aug 2012 22:22:22 +0000 Received: from stedding.saclay.inria.fr ([193.55.250.194]) by mail1-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES128-SHA; 01 Sep 2012 00:22:20 +0200 Received: from glisse (helo=localhost) by stedding.saclay.inria.fr with local-esmtp (Exim 4.80) (envelope-from ) id 1T7ZbY-00032k-Fc; Sat, 01 Sep 2012 00:22:20 +0200 Date: Sat, 1 Sep 2012 00:22:20 +0200 (CEST) From: Marc Glisse To: gcc-patches@gcc.gnu.org cc: jason@redhat.com Subject: Re: vector comparisons in C++ In-Reply-To: Message-ID: References: User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 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 With the patch... On Sat, 1 Sep 2012, Marc Glisse wrote: > Hello, > > this patch copies some more vector extensions from the C front-end to the C++ > front-end. There seemed to be some reluctance to add those, but I guess a > patch is the best way to ask. Note that I only added the vector x vector > operations, not the vector x scalar ones. > > I have some issues with the vector-compare-2.c torture test. It passes a > vector by value (argument and return type), which is likely to warn (although > for some reason it doesn't for me, with today's compiler). And it takes > -Wno-psabi through a .x file, but those are not read in c-c++-common, so I > put it in dg-options. I would have changed the function to use pointers, but > I don't know if it specifically wants to test passing by value... > > > > 2012-08-31 Marc Glisse > PR c++/54427 > > cp/ChangeLog > * 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. > > testsuite/ChangeLog > * 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. Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 190842) +++ cp/typeck.c (working copy) @@ -3977,21 +3977,29 @@ cp_build_binary_op (location_t location, case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: result_type = boolean_type_node; break; /* Shift operations: result has same type as first operand; always convert second operand to int. 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) { if (tree_int_cst_lt (op1, integer_zero_node)) { if ((complain & tf_warning) && c_inhibit_evaluation_warnings == 0) warning (0, "right shift count is negative"); } @@ -4006,21 +4014,29 @@ cp_build_binary_op (location_t location, /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) op1 = cp_convert (integer_type_node, op1, complain); /* Avoid converting op1 to result_type later. */ converted = 1; } 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) { if (tree_int_cst_lt (op1, integer_zero_node)) { if ((complain & tf_warning) && c_inhibit_evaluation_warnings == 0) warning (0, "left shift count is negative"); } @@ -4064,20 +4080,22 @@ cp_build_binary_op (location_t location, } /* Convert the shift-count to an integer, regardless of size of value being shifted. */ if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) op1 = cp_convert (integer_type_node, op1, complain); } break; 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, "comparing floating point with == or != is unsafe"); if ((complain & tf_warning) && ((TREE_CODE (orig_op0) == STRING_CST && !integer_zerop (op1)) || (TREE_CODE (orig_op1) == STRING_CST && !integer_zerop (op0)))) warning (OPT_Waddress, "comparison with string literal results in unspecified behaviour"); build_type = boolean_type_node; @@ -4306,20 +4324,46 @@ cp_build_binary_op (location_t location, case GE_EXPR: case LT_EXPR: case GT_EXPR: if (TREE_CODE (orig_op0) == STRING_CST || TREE_CODE (orig_op1) == STRING_CST) { if (complain & tf_warning) warning (OPT_Waddress, "comparison with string literal results in unspecified behaviour"); } + if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE) + { + vector_compare: + tree intt; + if (TREE_TYPE (type0) != TREE_TYPE (type1)) + { + error_at (location, "comparing vectors with different " + "element types"); + return error_mark_node; + } + + if (TYPE_VECTOR_SUBPARTS (type0) != TYPE_VECTOR_SUBPARTS (type1)) + { + error_at (location, "comparing vectors with different " + "number of elements"); + 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) && (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == ENUMERAL_TYPE)) short_compare = 1; else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) result_type = composite_pointer_type (type0, type1, op0, op1, CPO_COMPARISON, complain); else if (code0 == POINTER_TYPE && null_ptr_cst_p (op1)) Index: testsuite/c-c++-common/vector-compare-1.c =================================================================== --- testsuite/c-c++-common/vector-compare-1.c (revision 190834) +++ testsuite/c-c++-common/vector-compare-1.c (working copy) @@ -7,13 +7,13 @@ __attribute__((vector_size((elcount)*siz 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 = (x != p4); /* { dg-error "incompatible types when assigning to type|cannot convert" } */ r8 == r4; /* { dg-error "comparing vectors with different number of elements" } */ } Index: testsuite/c-c++-common/vector-shift.c =================================================================== --- testsuite/c-c++-common/vector-shift.c (revision 190834) +++ testsuite/c-c++-common/vector-shift.c (working copy) @@ -1,11 +1,12 @@ /* { 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 >>" } */ Index: testsuite/c-c++-common/torture/vector-subscript-1.c =================================================================== --- testsuite/c-c++-common/torture/vector-subscript-1.c (revision 190838) +++ testsuite/c-c++-common/torture/vector-subscript-1.c (working copy) @@ -1,11 +1,11 @@ -/* dg-do run */ +/* { 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; }; Index: testsuite/c-c++-common/torture/vector-subscript-2.c =================================================================== --- testsuite/c-c++-common/torture/vector-subscript-2.c (revision 190838) +++ testsuite/c-c++-common/torture/vector-subscript-2.c (working copy) @@ -1,10 +1,11 @@ +/* { 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; }; Index: testsuite/c-c++-common/torture/vector-shift.c =================================================================== --- testsuite/c-c++-common/torture/vector-shift.c (revision 190838) +++ testsuite/c-c++-common/torture/vector-shift.c (working copy) @@ -1,29 +1,30 @@ +/* { 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; \ + __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); Index: testsuite/c-c++-common/torture/vector-subscript-3.c =================================================================== --- testsuite/c-c++-common/torture/vector-subscript-3.c (revision 190838) +++ testsuite/c-c++-common/torture/vector-subscript-3.c (working copy) @@ -1,11 +1,11 @@ -/* dg-do run */ +/* { 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; }; Index: testsuite/c-c++-common/torture/vector-shift2.c =================================================================== --- testsuite/c-c++-common/torture/vector-shift2.c (revision 190838) +++ testsuite/c-c++-common/torture/vector-shift2.c (working copy) @@ -1,10 +1,11 @@ +/* { 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}; Index: testsuite/c-c++-common/torture/vector-compare-1.c =================================================================== --- testsuite/c-c++-common/torture/vector-compare-1.c (revision 190838) +++ testsuite/c-c++-common/torture/vector-compare-1.c (working copy) @@ -1,10 +1,11 @@ +/* { 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) ", \ @@ -31,76 +32,76 @@ do { \ } 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}; + 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)){argc, 1, 2, 10}; + 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)){argc, 1, 2, 10, 6, 87, (SHORT)-5, 2}; + 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)){argc, 1, 2, 10, 6, 87, (SHORT)-5, 2}; + 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)){argc, 1, 2, 10, 6, 87, (CHAR)-5, 2, \ - argc, 1, 2, 10, 6, 87, (CHAR)-5, 2 }; + 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)){argc, 1, 2, 10, 6, 87, (CHAR)-5, 2, \ - argc, 1, 2, 10, 6, 87, (CHAR)-5, 2 }; + 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; Index: testsuite/c-c++-common/torture/vector-compare-2.c =================================================================== --- testsuite/c-c++-common/torture/vector-compare-2.c (revision 190838) +++ testsuite/c-c++-common/torture/vector-compare-2.c (working copy) @@ -1,10 +1,12 @@ +/* { 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); Index: testsuite/c-c++-common/vector-shift1.c =================================================================== --- testsuite/c-c++-common/vector-shift1.c (revision 190834) +++ testsuite/c-c++-common/vector-shift1.c (working copy) @@ -1,18 +1,19 @@ /* { 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 to binary <<" } */ + vfloat0 <<= vfloat1; /* { dg-error "nvalid operands" } */ return 0; } Index: testsuite/c-c++-common/vector-shift3.c =================================================================== --- testsuite/c-c++-common/vector-shift3.c (revision 190834) +++ testsuite/c-c++-common/vector-shift3.c (working copy) @@ -1,16 +1,16 @@ /* { 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}; + vector(8, short) v0 = {(short)argc,2,3,4,5,6,7}; short sc; - scalar1 <<= v0; /* { dg-error ".*scalar1.*undeclared" } */ + scalar1 <<= v0; /* { dg-error "scalar1.*(undeclared|was not declared)" } */ return 0; }