On September 18, 2018 5:47:34 AM GMT+02:00, Alexandre Oliva <ol...@adacore.com> 
wrote:
>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)

I think so. We want to retain the alignment we'd extracted from the original 
ref. As you said the indirection is spuirously introduced by the compiler. 

>
>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.

OK. 

Richard. 

>From: Richard Biener <rguent...@suse.de>
>for  gcc/ChangeLog
>
>       PR middle-end/87054
>       * gimplify.c (gimplify_expr): Retain alignment of
>       addressable lvalue in dereference.
>
>From: Alexandre Oliva <ol...@adacore.com>
>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
>+  }
>+}

Reply via email to