From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20142 invoked by alias); 27 Oct 2008 20:02:05 -0000 Received: (qmail 20033 invoked by uid 22791); 27 Oct 2008 20:02:04 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Mon, 27 Oct 2008 20:01:29 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id m9RK1Rm3031642 for ; Mon, 27 Oct 2008 16:01:27 -0400 Received: from tyan-ft48-01.lab.bos.redhat.com (tyan-ft48-01.lab.bos.redhat.com [10.16.42.4]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id m9RK1QD0022167 for ; Mon, 27 Oct 2008 16:01:26 -0400 Received: (from jakub@localhost) by tyan-ft48-01.lab.bos.redhat.com (8.14.2/8.14.2/Submit) id m9RK27Jg021420 for gcc-patches@gcc.gnu.org; Mon, 27 Oct 2008 21:02:07 +0100 Date: Mon, 27 Oct 2008 20:58:00 -0000 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix combiner issues with shifts (PR c/37924) Message-ID: <20081027200207.GU14706@tyan-ft48-01.lab.bos.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.18 (2008-05-17) X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2008-10/txt/msg01168.txt.bz2 Hi! This patch fixes a couple of combiner issues. 1) simplify_shift_const_1 does something only if a shift count is within its range, but then can add or subtract shift counts without checking the result. This is because each such addition or subtraction is followed by continue and expects next iteration to canonicalize the count. Unfortunately if complement_p is true, the loop is exited before that canonicalization. This patch moves if (complement_p) break; after the shift count canonicalization. 2) make_compound_operation in several places didn't check if shift count is in its range, and calling make_extraction with negative length results in ICE. We should leave out-of-range shift counts unmodified. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2008-10-27 Jakub Jelinek PR c/37924 * combine.c (make_compound_operation): Don't call make_extraction with non-positive length. (simplify_shift_const_1): Canonicalize count even if complement_p. * gcc.c-torture/execute/pr37924.c: New test. --- gcc/combine.c.jj 2008-10-23 13:21:41.000000000 +0200 +++ gcc/combine.c 2008-10-27 17:05:29.000000000 +0100 @@ -6996,7 +6996,8 @@ make_compound_operation (rtx x, enum rtx if (GET_CODE (rhs) == CONST_INT && GET_CODE (lhs) == ASHIFT && GET_CODE (XEXP (lhs, 1)) == CONST_INT - && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1))) + && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1)) + && INTVAL (rhs) < mode_width) { new_rtx = make_compound_operation (XEXP (lhs, 0), next_code); new_rtx = make_extraction (mode, new_rtx, @@ -7016,6 +7017,7 @@ make_compound_operation (rtx x, enum rtx && (OBJECT_P (SUBREG_REG (lhs)))) && GET_CODE (rhs) == CONST_INT && INTVAL (rhs) < HOST_BITS_PER_WIDE_INT + && INTVAL (rhs) < mode_width && (new_rtx = extract_left_shift (lhs, INTVAL (rhs))) != 0) new_rtx = make_extraction (mode, make_compound_operation (new_rtx, next_code), 0, NULL_RTX, mode_width - INTVAL (rhs), @@ -9003,11 +9005,6 @@ simplify_shift_const_1 (enum rtx_code co if (GET_CODE (varop) == CLOBBER) return NULL_RTX; - /* If we discovered we had to complement VAROP, leave. Making a NOT - here would cause an infinite loop. */ - if (complement_p) - break; - /* Convert ROTATERT to ROTATE. */ if (code == ROTATERT) { @@ -9053,6 +9050,11 @@ simplify_shift_const_1 (enum rtx_code co } } + /* If we discovered we had to complement VAROP, leave. Making a NOT + here would cause an infinite loop. */ + if (complement_p) + break; + /* An arithmetic right shift of a quantity known to be -1 or 0 is a no-op. */ if (code == ASHIFTRT --- gcc/testsuite/gcc.c-torture/execute/pr37924.c.jj 2008-10-27 19:24:11.000000000 +0100 +++ gcc/testsuite/gcc.c-torture/execute/pr37924.c 2008-10-27 19:23:10.000000000 +0100 @@ -0,0 +1,29 @@ +/* PR c/37924 */ + +extern void abort (void); + +char a; + +int +test (void) +{ + int b = -1; + return ((unsigned int) (a ^ b)) >> 9; +} + +int +main (void) +{ + if (test () != (-1U >> 9)) + abort (); + a = 0x40; + if (test () != (-1U >> 9)) + abort (); + a = 0x80; + if (test () != (a < 0) ? 0 : (-1U >> 9)) + abort (); + a = 0xff; + if (test () != (a < 0) ? 0 : (-1U >> 9)) + abort (); + return 0; +} Jakub