From patchwork Sat Sep 28 15:30:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikael Pettersson X-Patchwork-Id: 278750 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 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 908BC2C010A for ; Sun, 29 Sep 2013 01:30:39 +1000 (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 :mime-version:content-type:content-transfer-encoding:message-id :date:to:subject; q=dns; s=default; b=H0SJG+7ZztTxR7ZQgtqzXkvBWY rHBHl2NXsEO2YUKY5vSBBJkb7Ts4FOG7E931DUGfMTrCXHVttX5huui1Eu4QQanT weLuyw9Af6w7iB9IWo72vFa+L9+r5B5lsj/BllCZucNkzBrXom6nJWnz2ANhpmXx VE4AZsGg43rWCKTrQ= 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 :mime-version:content-type:content-transfer-encoding:message-id :date:to:subject; s=default; bh=cuofyiM1gQmz8UmmRoXgDf30Vms=; b= O54vxxZi966LXi/1kCRj8Q33sc73siUuiUVa+uS0wNHdpYXOb0vb8X75xP0O7qxi mPHD9+/3NzohNif4JPoLql9M658zRb0vWPUaVtuos/29gPM5fMzkzpiuNJydALmr JFyIchqjQzbqMWh1gUHL+GgIzrqENSpSok7W6xJHabw= Received: (qmail 29685 invoked by alias); 28 Sep 2013 15:30:28 -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 29673 invoked by uid 89); 28 Sep 2013 15:30:28 -0000 Received: from mail-lb0-f174.google.com (HELO mail-lb0-f174.google.com) (209.85.217.174) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Sat, 28 Sep 2013 15:30:28 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.9 required=5.0 tests=ALL_TRUSTED, BAYES_00, FREEMAIL_FROM autolearn=ham version=3.3.2 X-HELO: mail-lb0-f174.google.com Received: by mail-lb0-f174.google.com with SMTP id w6so3148888lbh.19 for ; Sat, 28 Sep 2013 08:30:24 -0700 (PDT) X-Received: by 10.152.243.42 with SMTP id wv10mr46529lac.39.1380382223946; Sat, 28 Sep 2013 08:30:23 -0700 (PDT) Received: from cascade (h109n3-u-a31.ias.bredband.telia.com. [213.65.120.109]) by mx.google.com with ESMTPSA id e4sm9522433lba.15.1969.12.31.16.00.00 (version=TLSv1 cipher=RC4-SHA bits=128/128); Sat, 28 Sep 2013 08:30:23 -0700 (PDT) Received: by cascade (sSMTP sendmail emulation); Sat, 28 Sep 2013 17:30:20 +0200 From: Mikael Pettersson MIME-Version: 1.0 Message-ID: <21062.62988.797370.296379@gargle.gargle.HOWL> Date: Sat, 28 Sep 2013 17:30:20 +0200 To: gcc-patches@gcc.gnu.org Subject: [PATCH][RFC] fix reload causing ICE in subreg_get_info on m68k (PR58369) This patch fixes PR58369, an ICE in subreg_get_info when compiling boost for m68k-linux. choose_reload_regs attempts to reload a DFmode (8-byte) reg, finds an XFmode (12-byte) reg in "last_reg", and calls subreg_regno_offset with these two modes and a subreg offset of zero. However, this is not a correct lowpart subreg offset for big-endian and these two modes, so the lowpart subreg check in subreg_get_info fails, and the code continues to gcc_assert ((GET_MODE_SIZE (xmode) % GET_MODE_SIZE (ymode)) == 0); which fails because (12 % 8) != 0. choose_reload_regs passes the constant zero, in all cases where the reg isn't already a subreg, as the subreg offset to subreg_regno_offset, even though lowpart subregs on big-endian targets require an explicit offset computation. I think that is a bug. I believe other big-endian targets don't see this ICE because a) they define CANNOT_CHANGE_MODE_CLASS to reject differently-sized modes in floating-point registers (which prevents this path in choose_reload_regs), or b) their differently-sized modes are such that the size of a larger mode is a whole multiple of the size of the smaller mode (which allows the gcc_assert above to pass). This patch changes choose_reload_regs to call subreg_lowpart_offset to pass an endian-correct offset to subreg_regno_offset, except where the offset comes from a pre-existing subreg. [Defining CANNOT_CHANGE_MODE_CLASS appropriately for m68k also fixes the ICE, but I don't think the m68k backend really wants that, and I think it just papers over a generic bug.] Tested with trunk and 4.8 on {m68k,sparc64,powerpc64}-linux (big-endian), and on x86_64-linux/armv5tel-linux-gnueabi (little-endian). No regressions. Comments? Is this Ok for trunk? gcc/ 2013-09-28 Mikael Pettersson PR rtl-optimization/58369 * reload1.c (choose_reload_regs): Use subreg_lowpart_offset to pass endian-correct lowpart offset to subreg_regno_offset. --- gcc-4.9-20130922/gcc/reload1.c.~1~ 2013-09-09 15:07:10.000000000 +0200 +++ gcc-4.9-20130922/gcc/reload1.c 2013-09-28 16:24:21.068294912 +0200 @@ -6497,6 +6497,7 @@ choose_reload_regs (struct insn_chain *c if (inheritance) { int byte = 0; + bool byte_is_fixed = false; int regno = -1; enum machine_mode mode = VOIDmode; @@ -6519,7 +6520,10 @@ choose_reload_regs (struct insn_chain *c if (regno < FIRST_PSEUDO_REGISTER) regno = subreg_regno (rld[r].in_reg); else - byte = SUBREG_BYTE (rld[r].in_reg); + { + byte = SUBREG_BYTE (rld[r].in_reg); + byte_is_fixed = true; + } mode = GET_MODE (rld[r].in_reg); } #ifdef AUTO_INC_DEC @@ -6557,6 +6561,8 @@ choose_reload_regs (struct insn_chain *c rtx last_reg = reg_last_reload_reg[regno]; i = REGNO (last_reg); + if (! byte_is_fixed) + byte = subreg_lowpart_offset (mode, GET_MODE (last_reg)); i += subreg_regno_offset (i, GET_MODE (last_reg), byte, mode); last_class = REGNO_REG_CLASS (i);