From patchwork Thu Feb 11 23:26:46 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 582070 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 2A267140BFC for ; Fri, 12 Feb 2016 10:27:01 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=vWaZl5eM; 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:subject:message-id:reply-to:mime-version:content-type; q=dns; s=default; b=dB/9ZO3Yc4JdTtPjOfdXUAXgdci4HOzu0YyvECSzQRq iqj6lsfrKk5pvNxvvO2qquHxr5nnZpkAXqWqKAl0Y531oLEkvMNyx9tsyHj1q4+K KAzUsUJyWdauf1+jnLxn0ZPu6CEip5XMf25UAuUCc8upAPXum7q7LK26izvGxGmE = 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:subject:message-id:reply-to:mime-version:content-type; s=default; bh=bWLIfZ2fgRUK0MXUHsMsqrW9iho=; b=vWaZl5eMlSRssQuvi 4oUusEmyzaYIqGEnG9nGlI97wzo/3L3qFRL0WN/RGbGPlqN7sZaQ3rKbxa2bxqa9 55n1zATZLO0eAwwJmetFwsp62riMJtBHnCqJUitQCjR/R3o6LRenVECg8w+XayhA TN3ZjgvhI9fCjPv96eUYdpQ0g8= Received: (qmail 19181 invoked by alias); 11 Feb 2016 23:26:53 -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 19138 invoked by uid 89); 11 Feb 2016 23:26:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=2016-02-12, 20160212, himode, HImode 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; Thu, 11 Feb 2016 23:26:51 +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 CCE3F4C65E for ; Thu, 11 Feb 2016 23:26:50 +0000 (UTC) Received: from tucnak.zalov.cz ([10.3.113.11]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u1BNQnLG023752 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Thu, 11 Feb 2016 18:26:50 -0500 Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id u1BNQlM4027591 for ; Fri, 12 Feb 2016 00:26:48 +0100 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id u1BNQk6i027590 for gcc-patches@gcc.gnu.org; Fri, 12 Feb 2016 00:26:46 +0100 Date: Fri, 12 Feb 2016 00:26:46 +0100 From: Jakub Jelinek To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix ICE when expanding incorrect shift counts (PR rtl-optimization/69764) Message-ID: <20160211232646.GH3017@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) X-IsSubscribed: yes Hi! When expanding shifts with invalid shift counts (negative or too large), the shift count on the GIMPLE level is typically an int mode INTEGER_CST, but when it is passed down through various layers up to expand_binop_directly, we only have one known mode (other than operand modes, but that is VOIDmode for CONST_INTs) - the mode of the first argument (== result). But, we treat it as if even the shift count has that mode, and either keep it as is (if the expander has that mode for the shift count), or convert_modes it to the mode of the operand. If the CONST_INT is too large, we can have a problem though, because it could be e.g result of expand_normal of SImode value originally, but we then treat it as valid HImode or QImode CONST_INT, and so either crash in convert_modes, or later on when dealing with the shift count, as it might not be valid for the mode we are expecting. As expand_shift_1 and expand_binop seem to use GEN_INT for the shift count in lots of places, rather than say gen_int_mode, I think this needs to be fixed up only at the low level - in expand_binop_directly, which this patch does. The common case, where the shift count is >= 0 and < bitsize, are handled without need to call gen_int_mode. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-02-12 Jakub Jelinek PR rtl-optimization/69764 * optabs.c (expand_binop_directly): For shift_optab_p, if xop1 is CONST_INT above scalar int mode's GET_MODE_BITSIZE (mode), force it into mode. * c-c++-common/pr69764.c: New test. Jakub --- gcc/optabs.c.jj 2016-02-11 20:28:51.240492706 +0100 +++ gcc/optabs.c 2016-02-12 00:11:58.951795368 +0100 @@ -1006,6 +1006,14 @@ expand_binop_directly (machine_mode mode xop0 = avoid_expensive_constant (xmode0, binoptab, 0, xop0, unsignedp); if (!shift_optab_p (binoptab)) xop1 = avoid_expensive_constant (xmode1, binoptab, 1, xop1, unsignedp); + /* The mode of shift/rotate second operand is often different + from the mode of the operation, and for invalid shift counts xop1 + might not be valid constant in mode, so the following convert_modes + might ICE on it. Fix it up here. */ + else if (CONST_INT_P (xop1) + && SCALAR_INT_MODE_P (mode) + && UINTVAL (xop1) >= GET_MODE_BITSIZE (mode)) + xop1 = gen_int_mode (INTVAL (xop1), mode); /* In case the insn wants input operands in modes different from those of the actual operands, convert the operands. It would --- gcc/testsuite/c-c++-common/pr69764.c.jj 2016-02-12 00:00:54.950084697 +0100 +++ gcc/testsuite/c-c++-common/pr69764.c 2016-02-12 00:00:54.950084697 +0100 @@ -0,0 +1,38 @@ +/* PR rtl-optimization/69764 */ +/* { dg-do compile { target int32plus } } */ + +unsigned char +fn1 (unsigned char a) +{ + return a >> ~6; /* { dg-warning "right shift count is negative" } */ +} + +unsigned short +fn2 (unsigned short a) +{ + return a >> ~6; /* { dg-warning "right shift count is negative" } */ +} + +unsigned int +fn3 (unsigned int a) +{ + return a >> ~6; /* { dg-warning "right shift count is negative" } */ +} + +unsigned char +fn4 (unsigned char a) +{ + return a >> 0xff03; /* { dg-warning "right shift count >= width of type" } */ +} + +unsigned short +fn5 (unsigned short a) +{ + return a >> 0xff03; /* { dg-warning "right shift count >= width of type" } */ +} + +unsigned int +fn6 (unsigned int a) +{ + return a >> 0xff03; /* { dg-warning "right shift count >= width of type" } */ +}