From patchwork Sat Nov 2 11:52:01 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 287976 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 258352C00EF for ; Sat, 2 Nov 2013 22:52:14 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:cc:subject:date:message-id:mime-version:content-type; q=dns; s=default; b=b88NGn5OAyHZVILlCI2W+huyqaaRmqQixk2ZfGkME9rl0ExYKC EAk4A1nHc1RhWp4cpW6+eXocB4/agOpAxyaXftg+hPRyZL7O4cGoVcev5P+32igM tQp2lPyF7tvEbxI2FdvMm5aViCqkrULzg58iXpjoAus8zwh6faFIVvxNo= 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:from :to:cc:subject:date:message-id:mime-version:content-type; s= default; bh=iuTEZaLXJTm7VyMQJJcAtVoERy8=; b=SMVIJYqKdnEQMuilTpDH edjxqXch8dhai+hLYc6jdlhmi9AH8dEL/Sf2gl6geAta6J+jDTNVfL6BBge5Xb+e glhbZgthRcJRaY+cbIUN0/UnWXaoxYGw7Hc0hN050o3OAqtkJ7ScdCnAWeXPlJiH 4gi9K3uwSW8qsoImbeC+FkE= Received: (qmail 16410 invoked by alias); 2 Nov 2013 11:52:08 -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 16397 invoked by uid 89); 2 Nov 2013 11:52:07 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-wg0-f41.google.com Received: from mail-wg0-f41.google.com (HELO mail-wg0-f41.google.com) (74.125.82.41) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sat, 02 Nov 2013 11:52:06 +0000 Received: by mail-wg0-f41.google.com with SMTP id b13so283215wgh.2 for ; Sat, 02 Nov 2013 04:52:03 -0700 (PDT) X-Received: by 10.194.94.167 with SMTP id dd7mr1064354wjb.43.1383393123116; Sat, 02 Nov 2013 04:52:03 -0700 (PDT) Received: from localhost ([2.28.235.51]) by mx.google.com with ESMTPSA id dn2sm15531421wid.1.2013.11.02.04.52.01 for (version=TLSv1.2 cipher=AES128-GCM-SHA256 bits=128/128); Sat, 02 Nov 2013 04:52:02 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, zadeck@naturalbridge.com, mikestump@comcast.net, rdsandiford@googlemail.com Cc: zadeck@naturalbridge.com, mikestump@comcast.net Subject: [wide-int] Make shifted_mask more forgiving Date: Sat, 02 Nov 2013 11:52:01 +0000 Message-ID: <87d2mjja1q.fsf@talisman.default> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 r201806 added some extra checks to the handling of CONCAT when expanding assignments. This was to fix an ICE on gcc.dg/pr48335-2.c for ppc. I tripped over this because it also causes the assembly output for the test to change. I tried backing out the patch and the ICE was from the assert in wide-int.cc:shifted_mask: gcc_assert (start < 4 * MAX_BITSIZE_MODE_ANY_INT); However, in this case, the mask was being generated by mask_rtx, which specifically allows inputs that are out of range of the mode: /* Return a constant integer mask value of mode MODE with BITSIZE ones followed by BITPOS zeros, or the complement of that if COMPLEMENT. The mask is truncated if necessary to the width of mode MODE. The mask is zero-extended if BITSIZE+BITPOS is too small for MODE. */ So I don't think these inputs should trigger an ICE, even if in this particularly case they're conceptually wrong for some reason. Since wide-int.cc:shifted_mask already handles zero-width masks and cases where the end bit is out of range, I think we should handle the start being out of range too. It might be that 201806 is a good thing anyway (no idea either way), but I think it should go directly on mainline first if so. Tested on powerpc64-linux-gnu and x86_64-linux-gnu. It fixes the pr48335-2.c assembly differences. OK to install? Thanks, Richard Index: gcc/expr.c =================================================================== --- gcc/expr.c 2013-11-02 11:15:32.739837369 +0000 +++ gcc/expr.c 2013-11-02 11:15:42.562911693 +0000 @@ -4765,14 +4765,12 @@ expand_assignment (tree to, tree from, b && (bitpos == 0 || bitpos == mode_bitsize / 2)) result = store_expr (from, XEXP (to_rtx, bitpos != 0), false, nontemporal); - else if (bitpos + bitsize <= mode_bitsize / 2 - && bitpos+bitsize <= mode_bitsize) + else if (bitpos + bitsize <= mode_bitsize / 2) result = store_field (XEXP (to_rtx, 0), bitsize, bitpos, bitregion_start, bitregion_end, mode1, from, get_alias_set (to), nontemporal); - else if (bitpos >= mode_bitsize / 2 - && bitpos+bitsize <= mode_bitsize) + else if (bitpos >= mode_bitsize / 2) result = store_field (XEXP (to_rtx, 1), bitsize, bitpos - mode_bitsize / 2, bitregion_start, bitregion_end, @@ -4791,12 +4789,8 @@ expand_assignment (tree to, tree from, b } else { - HOST_WIDE_INT extra = 0; - if (bitpos+bitsize > mode_bitsize) - extra = bitpos+bitsize - mode_bitsize; rtx temp = assign_stack_temp (GET_MODE (to_rtx), - GET_MODE_SIZE (GET_MODE (to_rtx)) - + extra); + GET_MODE_SIZE (GET_MODE (to_rtx))); write_complex_part (temp, XEXP (to_rtx, 0), false); write_complex_part (temp, XEXP (to_rtx, 1), true); result = store_field (temp, bitsize, bitpos, Index: gcc/wide-int.cc =================================================================== --- gcc/wide-int.cc 2013-11-02 11:15:32.740837376 +0000 +++ gcc/wide-int.cc 2013-11-02 11:15:42.562911693 +0000 @@ -748,18 +748,16 @@ unsigned int wi::shifted_mask (HOST_WIDE_INT *val, unsigned int start, unsigned int width, bool negate, unsigned int prec) { - gcc_assert (start < 4 * MAX_BITSIZE_MODE_ANY_INT); - - if (start + width > prec) - width = prec - start; - unsigned int end = start + width; - - if (width == 0) + if (start >= prec || width == 0) { val[0] = negate ? -1 : 0; return 1; } + if (width > prec - start) + width = prec - start; + unsigned int end = start + width; + unsigned int i = 0; while (i < start / HOST_BITS_PER_WIDE_INT) val[i++] = negate ? -1 : 0;