From patchwork Sat Jul 13 19:19:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Glisse X-Patchwork-Id: 258837 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]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client CN "localhost", Issuer "www.qmailtoaster.com" (not verified)) by ozlabs.org (Postfix) with ESMTPS id 8B45D2C0157 for ; Sun, 14 Jul 2013 05:19:44 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; q=dns; s=default; b=QzM5RlEDCsHGeTRd 1ZPQDUkPvNRCp8tiPxaKl5uMFf0JIL2gDLYXeFNTQcVB897P+cLsGBmUWcW3H2Yr 9fJYQOJJiWsKs4RH69Vj00v18nRk4LhdLIrik7CWqKZ028dkeK1XKC+2gIR6Isp5 JN/2YmcQOa1G8CY3lmTW1/7VkFU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:in-reply-to:message-id:references :mime-version:content-type; s=default; bh=6VA6kVfsN5dT59c0cqkQBC nc9sU=; b=Sat47Jxf1KXtp2KX8MNXdhSVukVU0nA+BZ11QBdvbvTPzBq6HbYoqd D04tVq3HAxlb9rcVlwjxnKJp8E8VwCHlNGPiPWatTtxtKc013lxROdJgAEPcVFdX dmRF01BKjlkWRCuSn9l+b4RHefVKXEOXb5cBQ4OKteUIcX2Z41seo= Received: (qmail 28988 invoked by alias); 13 Jul 2013 19:19:38 -0000 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 Received: (qmail 28979 invoked by uid 89); 13 Jul 2013 19:19:37 -0000 X-Spam-SWARE-Status: No, score=-4.7 required=5.0 tests=AWL, BAYES_00, KHOP_THREADED, RDNS_NONE autolearn=no version=3.3.1 Received: from Unknown (HELO mail2-relais-roc.national.inria.fr) (192.134.164.83) by sourceware.org (qpsmtpd/0.84/v0.84-167-ge50287c) with ESMTP; Sat, 13 Jul 2013 19:19:35 +0000 Received: from stedding.saclay.inria.fr ([193.55.250.194]) by mail2-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES128-SHA; 13 Jul 2013 21:19:26 +0200 Received: from glisse (helo=localhost) by stedding.saclay.inria.fr with local-esmtp (Exim 4.80) (envelope-from ) id 1Uy5Lq-0004nj-He; Sat, 13 Jul 2013 21:19:26 +0200 Date: Sat, 13 Jul 2013 21:19:26 +0200 (CEST) From: Marc Glisse To: Jason Merrill cc: gcc-patches@gcc.gnu.org Subject: Re: vector conditional expression with scalar arguments In-Reply-To: <51DB7FA0.8090601@redhat.com> Message-ID: References: <51DAE2FE.1040707@redhat.com> <51DB7FA0.8090601@redhat.com> User-Agent: Alpine 2.02 (DEB 1266 2009-07-14) MIME-Version: 1.0 X-Virus-Found: No On Mon, 8 Jul 2013, Jason Merrill wrote: > On 07/08/2013 05:28 PM, Marc Glisse wrote: >> Perhaps the most conservative rule would be to only accept the case >> where the sizes match and reject the others for now, so whatever is >> decided later for other cases is unlikely to require a breaking change. >> Though I would like the general case to be accepted eventually, whatever >> it ends up meaning :) > > Makes sense to me. Here it is then. Bootstrap+testsuite on x86_64-unknown-linux-gnu. 2013-07-14 Marc Glisse gcc/cp/ * call.c (build_conditional_expr_1): Handle the case with 1 vector and 2 scalars. Call save_expr before building a vector. * typeck.c (cp_build_binary_op): Check complain before complaining. gcc/testsuite/ * g++.dg/ext/vector19.C: Adapt. * g++.dg/ext/vector23.C: New testcase. Index: testsuite/g++.dg/ext/vector19.C =================================================================== --- testsuite/g++.dg/ext/vector19.C (revision 200936) +++ testsuite/g++.dg/ext/vector19.C (working copy) @@ -30,22 +30,21 @@ void i2 (vec2 *x, vec2 *y, vec2u *z) { *x = *y ? *x : *y; *y = *z ? *x : *y; } void j (vec2 *x, vec2 *y, vec2 *z, vec *t) { *x = (*y < *z) ? *x : 4.2; /* { dg-error "" } */ *y = (*x < *z) ? 2.5 : *y; /* { dg-error "" } */ *t = *t ? *t : *t; /* { dg-error "" } */ - *z = (*x < *z) ? '1' : '0'; /* { dg-error "" } */ - // The last one may eventually be accepted. + *z = (*x < *z) ? '1' : '0'; } template auto k (A *a, B b) -> decltype (*a ? *a : b); void k (...) {} void l (vec2 *v, double x) { k (v, x); Index: testsuite/g++.dg/ext/vector23.C =================================================================== --- testsuite/g++.dg/ext/vector23.C (revision 0) +++ testsuite/g++.dg/ext/vector23.C (revision 0) @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu++1y -Wsign-conversion" } */ + +typedef double vecd __attribute__((vector_size(4*sizeof(double)))); +typedef float vecf __attribute__((vector_size(8*sizeof(float)))); +typedef long vecl __attribute__((vector_size(4*sizeof(long)))); +typedef short vecs __attribute__((vector_size(8*sizeof(short)))); +typedef char vecc __attribute__((vector_size(16*sizeof(char)))); + +auto f(vecf*a,float d,long long i){ + return (*a<0)?d:i; // { dg-error "truncation" } +} +auto g(vecc*a){ + return (*a<0)?3LL:42UL; // { dg-error "inferred scalar type" } +} +auto h(vecd*a){ + return (*a<0)?'a':'c'; // { dg-error "inferred scalar type \[^\\n\]*double" } +} +auto i(vecc*a){ + return (*a<0)?1:0.; // { dg-error "inferred scalar type" } +} +auto j(vecl*a,long i,unsigned long k){ + return (*a<0)?i:k; // { dg-warning "may change the sign" } +} Property changes on: testsuite/g++.dg/ext/vector23.C ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision URL Added: svn:eol-style + native Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 200936) +++ cp/typeck.c (working copy) @@ -4528,37 +4528,52 @@ cp_build_binary_op (location_t location, 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); + if (complain & tf_error) + { + 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); + if (complain & tf_error) + { + 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); + if (!intt) + { + if (complain & tf_error) + error_at (location, "could not find an integer type " + "of the same size as %qT", TREE_TYPE (type0)); + return error_mark_node; + } 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)) Index: cp/call.c =================================================================== --- cp/call.c (revision 200936) +++ cp/call.c (working copy) @@ -4398,46 +4398,92 @@ build_conditional_expr_1 (location_t loc arg2 = force_rvalue (arg2, complain); arg3 = force_rvalue (arg3, complain); tree arg1_type = TREE_TYPE (arg1); arg2_type = TREE_TYPE (arg2); arg3_type = TREE_TYPE (arg3); if (TREE_CODE (arg2_type) != VECTOR_TYPE && TREE_CODE (arg3_type) != VECTOR_TYPE) { - if (complain & tf_error) - error_at (loc, "at least one operand of a vector conditional " - "operator must be a vector"); - return error_mark_node; + /* Rely on the error messages of the scalar version. */ + tree scal = build_conditional_expr_1 (loc, integer_one_node, + orig_arg2, orig_arg3, complain); + if (scal == error_mark_node) + return error_mark_node; + tree stype = TREE_TYPE (scal); + tree ctype = TREE_TYPE (arg1_type); + if (TYPE_SIZE (stype) != TYPE_SIZE (ctype) + || (!INTEGRAL_TYPE_P (stype) && !SCALAR_FLOAT_TYPE_P (stype))) + { + if (complain & tf_error) + error_at (loc, "inferred scalar type %qT is not an integer or " + "floating point type of the same size as %qT", stype, + COMPARISON_CLASS_P (arg1) + ? TREE_TYPE (TREE_TYPE (TREE_OPERAND (arg1, 0))) + : ctype); + return error_mark_node; + } + + tree vtype = build_opaque_vector_type (stype, + TYPE_VECTOR_SUBPARTS (arg1_type)); + /* We could pass complain & tf_warning to unsafe_conversion_p, + but the warnings (like Wsign-conversion) have already been + given by the scalar build_conditional_expr_1. We still check + unsafe_conversion_p to forbid truncating long long -> float. */ + if (unsafe_conversion_p (stype, arg2, false)) + { + if (complain & tf_error) + error_at (loc, "conversion of scalar %qT to vector %qT " + "involves truncation", arg2_type, vtype); + return error_mark_node; + } + if (unsafe_conversion_p (stype, arg3, false)) + { + if (complain & tf_error) + error_at (loc, "conversion of scalar %qT to vector %qT " + "involves truncation", arg3_type, vtype); + return error_mark_node; + } + + arg2 = cp_convert (stype, arg2, complain); + arg2 = save_expr (arg2); + arg2 = build_vector_from_val (vtype, arg2); + arg2_type = vtype; + arg3 = cp_convert (stype, arg3, complain); + arg3 = save_expr (arg3); + arg3 = build_vector_from_val (vtype, arg3); + arg3_type = vtype; } if ((TREE_CODE (arg2_type) == VECTOR_TYPE) != (TREE_CODE (arg3_type) == VECTOR_TYPE)) { enum stv_conv convert_flag = scalar_to_vector (loc, VEC_COND_EXPR, arg2, arg3, complain & tf_error); switch (convert_flag) { case stv_error: return error_mark_node; case stv_firstarg: { + arg2 = save_expr (arg2); arg2 = convert (TREE_TYPE (arg3_type), arg2); arg2 = build_vector_from_val (arg3_type, arg2); arg2_type = TREE_TYPE (arg2); break; } case stv_secondarg: { + arg3 = save_expr (arg3); arg3 = convert (TREE_TYPE (arg2_type), arg3); arg3 = build_vector_from_val (arg2_type, arg3); arg3_type = TREE_TYPE (arg3); break; } default: break; } }