From patchwork Wed Jan 18 18:08:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Richard Earnshaw (lists)" X-Patchwork-Id: 716790 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 3v3ZjF6ldMz9snk for ; Thu, 19 Jan 2017 05:08:49 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ExXq9whP"; 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:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=HuLi0LjM7dWqn8QMAdbIvzxWYOZ8ZgA1yQR6ygpOCsCqrIwmgD miCdnk6GO5sg3ZlcaYWO+2sc+7pBf4BpenoPg/LKM07lI5gM4LMS1yDE5etpwkJm vcMP+YaeLlV+M7PE+Zl2LSCbfYka7Vnt6HdC5BeFzMc4NHda1uoNffNnk= 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:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=AZvPxE2Fb6OYv3nabPeVLQ7lUdY=; b=ExXq9whPqT+JB5vrkMWV TBZIVmLenJypahqXQOiB7NlsOqKQpaS9ev1nc5v1ZUdEiMw8iztegL+lt/Mr47UA Ylp4RKuoesdU8y9219YwoMn/zfhBIRD4xrb2y5RD/gf1b9F+KcuQht3MLTCU9oPK Ow5zCjf9+GiXO9DCAqdaU0E= Received: (qmail 127095 invoked by alias); 18 Jan 2017 18:08:39 -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 127070 invoked by uid 89); 18 Jan 2017 18:08:39 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-5.1 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 18 Jan 2017 18:08:37 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E08AF154D; Wed, 18 Jan 2017 10:08:35 -0800 (PST) Received: from e105689-lin.cambridge.arm.com (e105689-lin.cambridge.arm.com [10.2.207.32]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4F0213F318; Wed, 18 Jan 2017 10:08:35 -0800 (PST) To: gcc-patches Cc: Jiong Wang From: "Richard Earnshaw (lists)" Subject: [expand] Fix for PR rtl-optimization/79121 incorrect expansion of extend plus left shift Message-ID: <70b62c30-956f-0c3c-92f1-0cd5f1acdb2d@arm.com> Date: Wed, 18 Jan 2017 18:08:34 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 PR 79121 is a silent wrong code regression where, when generating a shift from an extended value moving from one to two machine registers, the type of the right shift is for the most significant word should be determined by the signedness of the inner type, not the signedness of the result type. gcc: PR rtl-optimization/79121 * expr.c (expand_expr_real_2, case LSHIFT_EXPR): Look at the signedness of the inner type when shifting an extended value. testsuite: * gcc.c-torture/execute/pr79121.c: New test. Bootstrapped on x86_64 and cross-tested on ARM. OK for trunk and GCC-6? R. diff --git a/gcc/expr.c b/gcc/expr.c index 4c54faf..cae13a4 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -9093,7 +9093,6 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, if (code == LSHIFT_EXPR && target && REG_P (target) - && ! unsignedp && mode == GET_MODE_WIDER_MODE (word_mode) && GET_MODE_SIZE (mode) == 2 * GET_MODE_SIZE (word_mode) && TREE_CONSTANT (treeop1) @@ -9114,6 +9113,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, rtx_insn *seq, *seq_old; unsigned int high_off = subreg_highpart_offset (word_mode, mode); + bool extend_unsigned + = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def))); rtx low = lowpart_subreg (word_mode, op0, mode); rtx dest_low = lowpart_subreg (word_mode, target, mode); rtx dest_high = simplify_gen_subreg (word_mode, target, @@ -9125,7 +9126,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, start_sequence (); /* dest_high = src_low >> (word_size - C). */ temp = expand_variable_shift (RSHIFT_EXPR, word_mode, low, - rshift, dest_high, unsignedp); + rshift, dest_high, + extend_unsigned); if (temp != dest_high) emit_move_insn (dest_high, temp); diff --git a/gcc/testsuite/gcc.c-torture/execute/pr79121.c b/gcc/testsuite/gcc.c-torture/execute/pr79121.c new file mode 100644 index 0000000..9fca7fb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr79121.c @@ -0,0 +1,34 @@ +extern void abort (void); + +__attribute__ ((noinline, noclone)) unsigned long long f1 (int x) +{ + return ((unsigned long long) x) << 4; +} + +__attribute__ ((noinline, noclone)) long long f2 (unsigned x) +{ + return ((long long) x) << 4; +} + +__attribute__ ((noinline, noclone)) unsigned long long f3 (unsigned x) +{ + return ((unsigned long long) x) << 4; +} + +__attribute__ ((noinline, noclone)) long long f4 (int x) +{ + return ((long long) x) << 4; +} + +int main () +{ + if (f1 (0xf0000000) != 0xffffffff00000000) + abort (); + if (f2 (0xf0000000) != 0xf00000000) + abort (); + if (f3 (0xf0000000) != 0xf00000000) + abort (); + if (f4 (0xf0000000) != 0xffffffff00000000) + abort (); + return 0; +}