From patchwork Thu Dec 30 12:22:07 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 76990 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]) by ozlabs.org (Postfix) with SMTP id 51246B7093 for ; Thu, 30 Dec 2010 23:22:22 +1100 (EST) Received: (qmail 17306 invoked by alias); 30 Dec 2010 12:22:19 -0000 Received: (qmail 17285 invoked by uid 22791); 30 Dec 2010 12:22:16 -0000 X-SWARE-Spam-Status: No, hits=-1.3 required=5.0 tests=AWL, BAYES_00, MSGID_FROM_MTA_HEADER, SPF_SOFTFAIL, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mtagate3.uk.ibm.com (HELO mtagate3.uk.ibm.com) (194.196.100.163) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 30 Dec 2010 12:22:11 +0000 Received: from d06nrmr1806.portsmouth.uk.ibm.com (d06nrmr1806.portsmouth.uk.ibm.com [9.149.39.193]) by mtagate3.uk.ibm.com (8.13.1/8.13.1) with ESMTP id oBUCM8vT026949 for ; Thu, 30 Dec 2010 12:22:08 GMT Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by d06nrmr1806.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id oBUCMAua3502278 for ; Thu, 30 Dec 2010 12:22:10 GMT Received: from d06av02.portsmouth.uk.ibm.com (loopback [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id oBUCM8eh029723 for ; Thu, 30 Dec 2010 05:22:08 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with SMTP id oBUCM7GP029710; Thu, 30 Dec 2010 05:22:07 -0700 Message-Id: <201012301222.oBUCM7GP029710@d06av02.portsmouth.uk.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Thu, 30 Dec 2010 13:22:07 +0100 Subject: [patch] Respect known misaligned addresses in set_mem_attributes_minus_bitpos To: richard.guenther@gmail.com (Richard Guenther) Date: Thu, 30 Dec 2010 13:22:07 +0100 (CET) From: "Ulrich Weigand" Cc: ramana.radhakrishnan@arm.com, gcc-patches@gcc.gnu.org, rearnsha@arm.com In-Reply-To: from "Richard Guenther" at Dec 26, 2010 11:13:50 PM MIME-Version: 1.0 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 Richard Guenther wrote: > The correct way to fix this is IMHO to make set_mem_attributes_minus_bitpos > not get initial alignment from the mode (but assert the mem-attrs are not > set yet in that function). At least if I understand the problem correctly. > > Ulrich promised to do this a while back ... Sorry for the long delay; I finally found some time to work on this. The patch below changes set_mem_attributes_minus_bitpos to not rely on the implicit defaulting rules in the MEM_ accessor macros. Instead, they are used only if memory attributes are in fact present. If not, deriving defaults for size and alignment from the MEM's mode are open-coded in this function. The overall behaviour should be identical to before, except for the one case we wanted to change: if set_mem_attributes_minus_bitpos is called with an expression (not a type) describing an object, the alignment is determined solely from that expression; default alignment of the mode is ignored, even on STRICT_ALIGNMENT targets. This fixes the problem I was originally seeing on a (modified) SPU target (and in fact generates fully identical code to what I was getting with my back-end work-around). Ramana, does this fix the ARM problem as well? There may be additional changes one could possibly do: - Is set_mem_attributes_minus_bitpos ever called on a MEM that already has attributes? If not, this set of defaults could go away ... - Is there really any case where using the mode's *size* is necessary (i.e. where we don't already get the size from the type)? - If we don't get an expression, but just a type, the rules when to use the type's alignment seem somewhat complex to me ... If this could be simplified so we can *always* use the type alignment, they all the STRICT_ALIGNMENT special case could maybe go there? But I guess all this could be follow-on work. Tested on s390x-linux, powerpc64-linux and spu-elf with no regressions. OK for mainline? Bye, Ulrich ChangeLog: * emit-rtl.c (set_mem_attributes_minus_bitpos): Explicitly derive default values from MEM mode if no memory attributes are present. Do not use mode alignment, even on STRICT_ALIGNMENT targets, when called with an expression (not a type). Index: gcc-head/gcc/emit-rtl.c =================================================================== --- gcc-head.orig/gcc/emit-rtl.c +++ gcc-head/gcc/emit-rtl.c @@ -1540,11 +1540,11 @@ void set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, HOST_WIDE_INT bitpos) { - alias_set_type alias = MEM_ALIAS_SET (ref); - tree expr = MEM_EXPR (ref); - rtx offset = MEM_OFFSET (ref); - rtx size = MEM_SIZE (ref); - unsigned int align = MEM_ALIGN (ref); + alias_set_type alias; + tree expr = NULL; + rtx offset = NULL_RTX; + rtx size = NULL_RTX; + unsigned int align = BITS_PER_UNIT; HOST_WIDE_INT apply_bitpos = 0; tree type; @@ -1580,6 +1580,27 @@ set_mem_attributes_minus_bitpos (rtx ref && TREE_CODE (type) != COMPLEX_TYPE) MEM_SCALAR_P (ref) = 1; + /* Default values from pre-existing memory attributes if present. */ + if (MEM_ATTRS (ref)) + { + expr = MEM_EXPR (ref); + offset = MEM_OFFSET (ref); + size = MEM_SIZE (ref); + align = MEM_ALIGN (ref); + } + + /* Otherwise, default values from the mode of the MEM reference. */ + else if (GET_MODE (ref) != BLKmode) + { + /* Respect mode size. */ + size = GEN_INT (GET_MODE_SIZE (GET_MODE (ref))); + + /* Respect mode alignment for STRICT_ALIGNMENT targets if T is a type; + if T is an object, always compute the object alignment below. */ + if (STRICT_ALIGNMENT && TYPE_P (t)) + align = GET_MODE_ALIGNMENT (GET_MODE (ref)); + } + /* We can set the alignment from the type if we are making an object, this is an INDIRECT_REF, or if TYPE_ALIGN_OK. */ if (objectp || TREE_CODE (t) == INDIRECT_REF || TYPE_ALIGN_OK (type))