Petro Karashchenko via Gcc-patches <gcc-patches@gcc.gnu.org> writes:
> for bitfield MEMREFs
>
> [FIX] Propagate uncached type attributes to unaligned/packed types

This doesn't look safe in general.  The current code was added
to avoid wrong-code problems for accesses that step outside the
bounds of the original MEM_EXPR.

Could you explain in more detail what's going wrong in the testcase?
It wasn't obvious why the code you're removing would trigger for that test.

Thanks,
Richard

>
> [ARC] Update tests
>
> gcc/
> xxxx-xx-xx  Petro Karashchenko  <petro.karashche...@gmail.com>
>
>         * emit-rtl.c (adjust_address_1): Do not drop the object
>         if the new memory reference is outside the underlying
>         object to preserve object attributes that are needed
>         by some backend implementations. Remove adjust_object
>         parameter as it is not used anymore.
>         (adjust_automodify_address_1): Adjust according to
>         new adjust_address_1 prototype.
>         (replace_equiv_address_nv): Likewise.
>         * gcc/emit-rtl.h (adjust_address): Adjust according to
>         new adjust_address_1 prototype.
>         (adjust_address_nv): Likewise.
>         (adjust_bitfield_address): Likewise.
>         (adjust_bitfield_address_size): Likewise.
>         (adjust_bitfield_address_nv): Likewise.
>
> testsuite/
> xxxx-xx-xx  Petro Karashchenko  <petro.karashche...@gmail.com>
>
>         * gcc.target/arc/uncached-9.c: New file.
>
> Problem description:
> __attribute__((uncached)) is dropped for other than the first member of
> "packed" or "unaligned" types.
>
> Tests:
> Tested with ARC600 bases ASIC. The correct code is generated.
>
> From 1f8a824f8ed8c1452f2bdfc513716c63d5d12545 Mon Sep 17 00:00:00 2001
> From: Petro Karashchenko <petro.karashche...@gmail.com>
> Date: Sun, 16 Aug 2020 01:10:11 +0300
> Subject: [PATCH] [FIX] Remove object adjustment to preserve object attributes
>  for bitfield MEMREFs
>
> [FIX] Propagate uncached type attributes to unaligned/packed types
>
> [ARC] Update tests
>
> gcc/
> xxxx-xx-xx  Petro Karashchenko  <petro.karashche...@gmail.com>
>
>         * emit-rtl.c (adjust_address_1): Do not drop the object
>         if the new memory reference is outside the underlying
>         object to preserve object attributes that are needed
>         by some backend implementations. Remove adjust_object
>         parameter as it is not used anymore.
>         (adjust_automodify_address_1): Adjust according to
>         new adjust_address_1 prototype.
>         (replace_equiv_address_nv): Likewise.
>         * gcc/emit-rtl.h (adjust_address): Adjust according to
>         new adjust_address_1 prototype.
>         (adjust_address_nv): Likewise.
>         (adjust_bitfield_address): Likewise.
>         (adjust_bitfield_address_size): Likewise.
>         (adjust_bitfield_address_nv): Likewise.
>
> testsuite/
> xxxx-xx-xx  Petro Karashchenko  <petro.karashche...@gmail.com>
>
>         * gcc.target/arc/uncached-9.c: New file.
>
> Signed-off-by: Petro Karashchenko <petro.karashche...@gmail.com>
> ---
>  gcc/emit-rtl.c                            | 28 +++--------------------
>  gcc/emit-rtl.h                            | 12 +++++-----
>  gcc/testsuite/gcc.target/arc/uncached-9.c | 19 +++++++++++++++
>  3 files changed, 28 insertions(+), 31 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/uncached-9.c
>
> diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
> index f9b0e9714d9..c0e2ead907b 100644
> --- a/gcc/emit-rtl.c
> +++ b/gcc/emit-rtl.c
> @@ -2337,8 +2337,7 @@ change_address (rtx memref, machine_mode mode, rtx addr)
>  
>  rtx
>  adjust_address_1 (rtx memref, machine_mode mode, poly_int64 offset,
> -               int validate, int adjust_address, int adjust_object,
> -               poly_int64 size)
> +               int validate, int adjust_address, poly_int64 size)
>  {
>    rtx addr = XEXP (memref, 0);
>    rtx new_rtx;
> @@ -2413,25 +2412,11 @@ adjust_address_1 (rtx memref, machine_mode mode, 
> poly_int64 offset,
>    if (new_rtx == memref && maybe_ne (offset, 0))
>      new_rtx = copy_rtx (new_rtx);
>  
> -  /* Conservatively drop the object if we don't know where we start from.  */
> -  if (adjust_object && (!attrs.offset_known_p || !attrs.size_known_p))
> -    {
> -      attrs.expr = NULL_TREE;
> -      attrs.alias = 0;
> -    }
> -
>    /* Compute the new values of the memory attributes due to this adjustment.
>       We add the offsets and update the alignment.  */
>    if (attrs.offset_known_p)
>      {
>        attrs.offset += offset;
> -
> -      /* Drop the object if the new left end is not within its bounds.  */
> -      if (adjust_object && maybe_lt (attrs.offset, 0))
> -     {
> -       attrs.expr = NULL_TREE;
> -       attrs.alias = 0;
> -     }
>      }
>  
>    /* Compute the new alignment by taking the MIN of the alignment and the
> @@ -2445,18 +2430,11 @@ adjust_address_1 (rtx memref, machine_mode mode, 
> poly_int64 offset,
>  
>    if (maybe_ne (size, 0))
>      {
> -      /* Drop the object if the new right end is not within its bounds.  */
> -      if (adjust_object && maybe_gt (offset + size, attrs.size))
> -     {
> -       attrs.expr = NULL_TREE;
> -       attrs.alias = 0;
> -     }
>        attrs.size_known_p = true;
>        attrs.size = size;
>      }
>    else if (attrs.size_known_p)
>      {
> -      gcc_assert (!adjust_object);
>        attrs.size -= offset;
>        /* ??? The store_by_pieces machinery generates negative sizes,
>        so don't assert for that here.  */
> @@ -2477,7 +2455,7 @@ adjust_automodify_address_1 (rtx memref, machine_mode 
> mode, rtx addr,
>                            poly_int64 offset, int validate)
>  {
>    memref = change_address_1 (memref, VOIDmode, addr, validate, false);
> -  return adjust_address_1 (memref, mode, offset, validate, 0, 0, 0);
> +  return adjust_address_1 (memref, mode, offset, validate, 0, 0);
>  }
>  
>  /* Return a memory reference like MEMREF, but whose address is changed by
> @@ -2561,7 +2539,7 @@ replace_equiv_address_nv (rtx memref, rtx addr, bool 
> inplace)
>  rtx
>  widen_memory_access (rtx memref, machine_mode mode, poly_int64 offset)
>  {
> -  rtx new_rtx = adjust_address_1 (memref, mode, offset, 1, 1, 0, 0);
> +  rtx new_rtx = adjust_address_1 (memref, mode, offset, 1, 1, 0);
>    poly_uint64 size = GET_MODE_SIZE (mode);
>  
>    /* If there are no changes, just return the original memory reference.  */
> diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h
> index 3d6565c8a30..108669f51a1 100644
> --- a/gcc/emit-rtl.h
> +++ b/gcc/emit-rtl.h
> @@ -473,27 +473,27 @@ extern rtx change_address (rtx, machine_mode, rtx);
>  /* Return a memory reference like MEMREF, but with its mode changed
>     to MODE and its address offset by OFFSET bytes.  */
>  #define adjust_address(MEMREF, MODE, OFFSET) \
> -  adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 0, 0)
> +  adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 0)
>  
>  /* Likewise, but the reference is not required to be valid.  */
>  #define adjust_address_nv(MEMREF, MODE, OFFSET) \
> -  adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 0, 0)
> +  adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 0)
>  
>  /* Return a memory reference like MEMREF, but with its mode changed
>     to MODE and its address offset by OFFSET bytes.  Assume that it's
>     for a bitfield and conservatively drop the underlying object if we
>     cannot be sure to stay within its bounds.  */
>  #define adjust_bitfield_address(MEMREF, MODE, OFFSET) \
> -  adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 1, 0)
> +  adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 0)
>  
>  /* As for adjust_bitfield_address, but specify that the width of
>     BLKmode accesses is SIZE bytes.  */
>  #define adjust_bitfield_address_size(MEMREF, MODE, OFFSET, SIZE) \
> -  adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, 1, SIZE)
> +  adjust_address_1 (MEMREF, MODE, OFFSET, 1, 1, SIZE)
>  
>  /* Likewise, but the reference is not required to be valid.  */
>  #define adjust_bitfield_address_nv(MEMREF, MODE, OFFSET) \
> -  adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 1, 0)
> +  adjust_address_1 (MEMREF, MODE, OFFSET, 0, 1, 0)
>  
>  /* Return a memory reference like MEMREF, but with its mode changed
>     to MODE and its address changed to ADDR, which is assumed to be
> @@ -506,7 +506,7 @@ extern rtx change_address (rtx, machine_mode, rtx);
>    adjust_automodify_address_1 (MEMREF, MODE, ADDR, OFFSET, 0)
>  
>  extern rtx adjust_address_1 (rtx, machine_mode, poly_int64, int, int,
> -                          int, poly_int64);
> +                          poly_int64);
>  extern rtx adjust_automodify_address_1 (rtx, machine_mode, rtx,
>                                       poly_int64, int);
>  
> diff --git a/gcc/testsuite/gcc.target/arc/uncached-9.c 
> b/gcc/testsuite/gcc.target/arc/uncached-9.c
> new file mode 100644
> index 00000000000..44b8a0ed7f3
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/uncached-9.c
> @@ -0,0 +1,19 @@
> +/* { dg-do compile } */
> +
> +#include <stddef.h>
> +
> +typedef volatile struct {
> +  uint32_t a1;
> +  uint32_t a2;
> +  uint32_t a3;
> +  uint32_t a4;
> +} __attribute__((packed,uncached)) my_type_t;
> +
> +uint32_t foo (my_type_t *p)
> +{
> +  p->a3 = p->a2;
> +  return p->a4;
> +}
> +
> +/* { dg-final { scan-assembler-times "stb\.di" 4 } } */
> +/* { dg-final { scan-assembler-times "ldb\.di" 12 } } */

Reply via email to