From patchwork Tue Sep 18 03:47:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 970909 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-485850-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="Aa/q25f4"; dkim-atps=neutral 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 42Dprt0pHPz9sCD for ; Tue, 18 Sep 2018 13:49:15 +1000 (AEST) 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=LKbbzW+/lCki42FH97bW+8eCn8QIMOIk85Mhjl90rBpO3pLc2E 72bPPPfbjaNdZrUSzQOIMt1vE144/G3F4BPbNTXs78n08x3hA3KBHF1aI70Gz/G0 ofgfOAaIl8oWevBihcxU6pDJIJk4bLYmmy9edlNax+BP1LkT/AbgJT+FQ= 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=xu0GFMLc1LfGRqum4OivShPrYbQ=; b=Aa/q25f4Q7PPQAGPNMOy NXd2Q8xsr0FJAGklWml8w8KOoBO/d73GThS7+aeGpwpKyRy7h2/l0n+C3tyrzy9n WrQbCNCCWtboNdy2Tuz+6UwP0zoQNil8yMFQlzVnKH28r3Gy7OLe8dwYvROe0hnB SeE30IbJD/ykaKjekF+Iezw= Received: (qmail 81612 invoked by alias); 18 Sep 2018 03:48:26 -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 81438 invoked by uid 89); 18 Sep 2018 03:48:04 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=free!, Latin, latin, object's X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 18 Sep 2018 03:48:02 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id EAEF5117D04; Mon, 17 Sep 2018 23:48:00 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id nzoRTgqRDq4J; Mon, 17 Sep 2018 23:48:00 -0400 (EDT) Received: from free.home (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by rock.gnat.com (Postfix) with ESMTPS id 762C911703B; Mon, 17 Sep 2018 23:48:00 -0400 (EDT) Received: from livre (livre.home [172.31.160.2]) by free.home (8.15.2/8.15.2) with ESMTP id w8I3lY2D233779; Tue, 18 Sep 2018 00:47:36 -0300 From: Alexandre Oliva To: gcc-patches@gcc.gnu.org Cc: Richard Biener Subject: [PR87054] fix unaligned access Date: Tue, 18 Sep 2018 00:47:34 -0300 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 Richard, this is the patch you proposed in the PR a while ago, along with the testcase I'd posted. Please let me know if the commit-message paragraph below sounds good to you, and then I'll proceed to install it, or amend as requested. (do we really want the MEM_REF to carry stricter alignment than the base type? I'd have retained the object's alignment only for looser-than-type alignment) Building an ADDR_EXPR uses the canonical type to build the pointer type, but then, as we dereference it, we lose track of lax alignment known to apply to the dereferenced object. This might not be a problem in general, but it is when the compiler implicitly introduces address taking and dereferencing, as it does for asm statements, and as it may do in some loop optimizations. Regstrapped on x86_64-linux-gnu. From: Richard Biener for gcc/ChangeLog PR middle-end/87054 * gimplify.c (gimplify_expr): Retain alignment of addressable lvalue in dereference. From: Alexandre Oliva for gcc/testsuite/ChangeLog PR middle-end/87054 * gcc.dg/pr87054.c: New. --- gcc/gimplify.c | 8 +++++++- gcc/testsuite/gcc.dg/pr87054.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/pr87054.c diff --git a/gcc/gimplify.c b/gcc/gimplify.c index f0eb04a751ccc..509fc2f3f5be2 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -12538,9 +12538,15 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, /* An lvalue will do. Take the address of the expression, store it in a temporary, and replace the expression with an INDIRECT_REF of that temporary. */ + tree ref_alias_type = reference_alias_ptr_type (*expr_p); + unsigned int ref_align = get_object_alignment (*expr_p); + tree ref_type = TREE_TYPE (*expr_p); tmp = build_fold_addr_expr_loc (input_location, *expr_p); gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue); - *expr_p = build_simple_mem_ref (tmp); + if (TYPE_ALIGN (ref_type) != ref_align) + ref_type = build_aligned_type (ref_type, ref_align); + *expr_p = build2 (MEM_REF, ref_type, + tmp, build_zero_cst (ref_alias_type)); } else if ((fallback & fb_rvalue) && is_gimple_reg_rhs_or_call (*expr_p)) { diff --git a/gcc/testsuite/gcc.dg/pr87054.c b/gcc/testsuite/gcc.dg/pr87054.c new file mode 100644 index 0000000000000..4ca2b62d2c7c9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr87054.c @@ -0,0 +1,29 @@ +// { dg-do run } +// { dg-options "-O2" } + +#ifndef T +# ifdef __SSE__ +# define T __int128 +# else +# define T long +# endif +#endif +#ifndef R +# ifdef __SSE__ +# define R "x" +# else +# define R "r" +# endif +#endif + + +typedef T A; // #define T to long or __int128 +struct B { char d; A c; } __attribute__((packed)); +struct B b[50]; // many elements to avoid loop unrolling + +int main () { + int i; + for (i = 0; i < sizeof(b) / sizeof(*b); i++) { + asm ("" : "+" R (b[i].c)); // #define R to "r" on ppc or "x" on x86_64 + } +}