From patchwork Wed Jan 13 15:26:50 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 566991 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.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id A4861140317 for ; Thu, 14 Jan 2016 02:27:08 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=t/LO+RfE; dkim-atps=neutral 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:message-id:mime-version:content-type; q=dns; s=default; b=T365Nu+af+i5Eaa+046SwHGV5N90zoq+5CJWrCJll+nX2WCxW2 0dU/IdHmyB/cMY+0pKDgWdSeIKi1qFMNNylObVzhz4/OlqH63sJ1o6r7/sY+PWG4 3ZPV7cCsO47sqEnYcFYKW2xkpZhVykqJfAE/dIswIMLy20gWCR6OdjRbc= 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:message-id:mime-version:content-type; s= default; bh=c2VFsOOtIRK49Uakc2p8suWEy34=; b=t/LO+RfEe4jSY93Y8c9X uVg4hXJ6drLw1S6BTLiYja7yvLcyRACM4ZW1pMqW+/wDMlALQTINlZtOP6cEpuXW g6BhrO2H0bncNv6Fyp1JSGzFsH62DMKGZKyR7uU1OiWa25v4J+sRUm+biTvc3Ff9 vF8JM61yj1V6Jl6rywrGFnM= Received: (qmail 37412 invoked by alias); 13 Jan 2016 15:27:01 -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 37392 invoked by uid 89); 13 Jan 2016 15:27:00 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=UD:c-typeck.c, c-typeck.c, ctypeckc, fes X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 13 Jan 2016 15:26:59 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 11FF832B716; Wed, 13 Jan 2016 15:26:58 +0000 (UTC) Received: from redhat.com (ovpn-204-42.brq.redhat.com [10.40.204.42]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u0DFQrVt007349 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Wed, 13 Jan 2016 10:26:56 -0500 Date: Wed, 13 Jan 2016 16:26:50 +0100 From: Marek Polacek To: GCC Patches Cc: Richard Biener , Jason Merrill , Joseph Myers Subject: [C/C++ PATCH] Don't emit invalid VEC_COND_EXPR for vector comparisons (PR c/68062) Message-ID: <20160113152650.GJ25528@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) We crash on the following testcase because the FEs create VEC_COND_EXPR < a == b , { -1, -1, -1, -1 } , { 0, 0, 0, 0 } > where the operands of the comparison are same except for the sign (it's vector_types_compatible_elements_p that says that). But GIMPLE doesn't like the difference in the sign. As I read the discussion in the PR, the way forward here is to perform signed -> unsigned conversions. So that is what I do in the following. Bootstrapped/regtested on x86_64-linux and ppc64le-linux, ok for trunk? 2016-01-13 Marek Polacek PR c/68062 * c-typeck.c (build_binary_op) [EQ_EXPR, GE_EXPR]: Promote operand to unsigned, if needed. * typeck.c (cp_build_binary_op): Promote operand to unsigned, if needed. * c-c++-common/vector-compare-4.c: New test. Marek diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c index 952041b..b646451 100644 --- gcc/c/c-typeck.c +++ gcc/c/c-typeck.c @@ -11048,6 +11048,18 @@ build_binary_op (location_t location, enum tree_code code, return error_mark_node; } + /* It's not precisely specified how the usual arithmetic + conversions apply to the vector types. Here, we use + the unsigned type if one of the operands is signed and + the other one is unsigned. */ + if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)) + { + if (!TYPE_UNSIGNED (type0)) + op0 = build1 (VIEW_CONVERT_EXPR, type1, op0); + else + op1 = build1 (VIEW_CONVERT_EXPR, type0, op1); + } + /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); @@ -11201,6 +11213,18 @@ build_binary_op (location_t location, enum tree_code code, return error_mark_node; } + /* It's not precisely specified how the usual arithmetic + conversions apply to the vector types. Here, we use + the unsigned type if one of the operands is signed and + the other one is unsigned. */ + if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)) + { + if (!TYPE_UNSIGNED (type0)) + op0 = build1 (VIEW_CONVERT_EXPR, type1, op0); + else + op1 = build1 (VIEW_CONVERT_EXPR, type0, op1); + } + /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); diff --git gcc/cp/typeck.c gcc/cp/typeck.c index 472b41b..ffa9ed4 100644 --- gcc/cp/typeck.c +++ gcc/cp/typeck.c @@ -4813,6 +4813,18 @@ cp_build_binary_op (location_t location, return error_mark_node; } + /* It's not precisely specified how the usual arithmetic + conversions apply to the vector types. Here, we use + the unsigned type if one of the operands is signed and + the other one is unsigned. */ + if (TYPE_UNSIGNED (type0) != TYPE_UNSIGNED (type1)) + { + if (!TYPE_UNSIGNED (type0)) + op0 = build1 (VIEW_CONVERT_EXPR, type1, op0); + else + op1 = build1 (VIEW_CONVERT_EXPR, type0, op1); + } + /* Always construct signed integer vector type. */ intt = c_common_type_for_size (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (type0))), 0); diff --git gcc/testsuite/c-c++-common/vector-compare-4.c gcc/testsuite/c-c++-common/vector-compare-4.c index e69de29..14faf04 100644 --- gcc/testsuite/c-c++-common/vector-compare-4.c +++ gcc/testsuite/c-c++-common/vector-compare-4.c @@ -0,0 +1,41 @@ +/* PR c/68062 */ +/* { dg-do compile } */ + +typedef signed char __attribute__ ((vector_size (4))) v4qi; +typedef unsigned char __attribute__ ((vector_size (4))) uv4qi; +typedef signed int __attribute__ ((vector_size (4 * __SIZEOF_INT__))) v4si; +typedef unsigned int __attribute__ ((vector_size (4 * __SIZEOF_INT__))) uv4si; + +v4qi +fn1 (void) +{ + v4qi a = { 1, 2, 3, 4 }; + uv4qi b = { 4, 3, 2, 1 }; + v4qi v = { 0, 0, 0, 0 }; + + v += (a == b); + v += (a != b); + v += (a >= b); + v += (a <= b); + v += (a > b); + v += (a < b); + + return v; +} + +v4si +fn2 (void) +{ + v4si a = { 1, 2, 3, 4 }; + uv4si b = { 4, 3, 2, 1 }; + v4si v = { 0, 0, 0, 0 }; + + v += (a == b); + v += (a != b); + v += (a >= b); + v += (a <= b); + v += (a > b); + v += (a < b); + + return v; +}