From patchwork Fri Oct 28 11:18:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernd Schmidt X-Patchwork-Id: 79905 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp1118019qge; Fri, 28 Oct 2016 04:18:39 -0700 (PDT) X-Received: by 10.107.149.70 with SMTP id x67mr10598833iod.44.1477653519325; Fri, 28 Oct 2016 04:18:39 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id l8si10824095pax.155.2016.10.28.04.18.39 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 28 Oct 2016 04:18:39 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-return-439813-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-439813-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-439813-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=r+IRGb3hrUFhh286/R4jtgmxrdhdTTQ34vWs89MyhprikRNspB pb4cqaKJUn3RpO5CCHW/355X4pmcwPKqBrV5Jy5+tJZW5D9QbvIxsKjmf1fDaaCa G+7XODB6xVb+HLH7tIMZBksaz7CfaFH6llSoC86FF0aRCc7i5KFUYQPQA= 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 :from:subject:message-id:date:mime-version:content-type; s= default; bh=VFCukcXlC8tzglMxI0PhNIkqJ2Y=; b=UmfOSTYjUOtaf2j+B6nL o04v+I3Fx88BC8Cf4jRcHPZqrXd0Uk9qzHN6AKhsGHKXuOlbF7FlJljjNgEQcIyO ijml/MPBwLr0iZvQNr1tDg9k/fwiprDXWTJ/ZLTGEqR9pVXCG//MR8wIVkfMsyiu aRHvHEDd9V/KVtMV5li8zqU= Received: (qmail 109727 invoked by alias); 28 Oct 2016 11:18:25 -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 109700 invoked by uid 89); 28 Oct 2016 11:18:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=BAYES_00, KAM_ASCII_DIVIDERS, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=xexp, XEXP, thinks, const0_rtx 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 ESMTP; Fri, 28 Oct 2016 11:18:22 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B1B80C057FA5 for ; Fri, 28 Oct 2016 11:18:21 +0000 (UTC) Received: from localhost.localdomain (vpn1-6-203.ams2.redhat.com [10.36.6.203]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u9SBIKC2032606 for ; Fri, 28 Oct 2016 07:18:20 -0400 To: GCC Patches From: Bernd Schmidt Subject: Fix PR77309, combine eliminates sign bit comparison Message-ID: <8078ee43-0cbf-d0a4-5e84-b78f0cee7d9a@redhat.com> Date: Fri, 28 Oct 2016 13:18:19 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.3.0 MIME-Version: 1.0 X-IsSubscribed: yes In this PR, we manage to simplify the code down to (lt (and (reg) (signbit)) (const 0)) simplify_comparison then calls make_compound_operation on the AND expression, and that turns it into a ZERO_EXTRACT of a single bit, changing the meaning of the comparison. The problem is a special case we have for comparisons in make_compound_operation, it thinks it should convert single-bit ANDs into such extractions. But this is only valid if the bit isn't the sign bit, or if we're testing for equality with zero. The following patch was bootstrapped and tested on x86_64-linux. Ok? Bernd PR rtl-optimization/77309 * combine.c (make_compound_operation): Allow EQ for IN_CODE, and don't assume an equality comparison for plain COMPARE. (simplify_comparison): Pass a more accurate code to make_compound_operation. PR rtl-optimization/77309 * gcc.dg/torture/pr77309.c: New test. Index: gcc/combine.c =================================================================== --- gcc/combine.c (revision 241233) +++ gcc/combine.c (working copy) @@ -7757,7 +7757,8 @@ extract_left_shift (rtx x, int count) IN_CODE says what kind of expression we are processing. Normally, it is SET. In a memory address it is MEM. When processing the arguments of - a comparison or a COMPARE against zero, it is COMPARE. */ + a comparison or a COMPARE against zero, it is COMPARE, or EQ if more + precisely it is an equality comparison against zero. */ rtx make_compound_operation (rtx x, enum rtx_code in_code) @@ -7771,6 +7772,7 @@ make_compound_operation (rtx x, enum rtx rtx new_rtx = 0; rtx tem; const char *fmt; + bool equality_comparison = false; /* PR rtl-optimization/70944. */ if (VECTOR_MODE_P (mode)) @@ -7780,6 +7782,11 @@ make_compound_operation (rtx x, enum rtx address, we stay there. If we have a comparison, set to COMPARE, but once inside, go back to our default of SET. */ + if (in_code == EQ) + { + equality_comparison = true; + in_code = COMPARE; + } next_code = (code == MEM ? MEM : ((code == COMPARE || COMPARISON_P (x)) && XEXP (x, 1) == const0_rtx) ? COMPARE @@ -7988,11 +7995,12 @@ make_compound_operation (rtx x, enum rtx /* If we are in a comparison and this is an AND with a power of two, convert this into the appropriate bit extract. */ else if (in_code == COMPARE - && (i = exact_log2 (UINTVAL (XEXP (x, 1)))) >= 0) + && (i = exact_log2 (UINTVAL (XEXP (x, 1)))) >= 0 + && (equality_comparison || i < GET_MODE_PRECISION (mode) - 1)) new_rtx = make_extraction (mode, - make_compound_operation (XEXP (x, 0), - next_code), - i, NULL_RTX, 1, 1, 0, 1); + make_compound_operation (XEXP (x, 0), + next_code), + i, NULL_RTX, 1, 1, 0, 1); /* If the one operand is a paradoxical subreg of a register or memory and the constant (limited to the smaller mode) has only zero bits where @@ -12425,7 +12433,11 @@ simplify_comparison (enum rtx_code code, We can never remove a SUBREG for a non-equality comparison because the sign bit is in a different place in the underlying object. */ - op0 = make_compound_operation (op0, op1 == const0_rtx ? COMPARE : SET); + rtx_code op0_mco_code = SET; + if (op1 == const0_rtx) + op0_mco_code = code == NE || code == EQ ? EQ : COMPARE; + + op0 = make_compound_operation (op0, op0_mco_code); op1 = make_compound_operation (op1, SET); if (GET_CODE (op0) == SUBREG && subreg_lowpart_p (op0) Index: gcc/testsuite/gcc.dg/torture/pr77309.c =================================================================== --- gcc/testsuite/gcc.dg/torture/pr77309.c (nonexistent) +++ gcc/testsuite/gcc.dg/torture/pr77309.c (working copy) @@ -0,0 +1,14 @@ +/* { dg-do run } */ + +int a, b; + +int main () +{ + long c = 1 % (2 ^ b); + c = -c & ~(~(b ^ ~b) || a); + + if (c >= 0) + __builtin_abort (); + + return 0; +}