This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Add tests for recent dse bugs


Hi Jeff,


On 17 January 2017 at 00:44, Jeff Law <law@redhat.com> wrote:
>
>
> ACATS already had a test covering the Ada issue, Eric also added a test to
> the gnat.dg testsuite.  So that's well covered.
>
> The test for the bootstrap comparison failure was (as expected) trivial to
> construct (ssa-dse-29.c).  The test for the ppc64 big endian failures was
> easy to extract from sel-sched.c (ssa-dse-2.C)  What was more interesting
> was the scanning.
>
> I finally decided to enhance the dumps a bit to facilitate testing.  If we
> have a trimmable store, we now dump the trimming information.  The test then
> verifies two things.  First that we don't get a negative trim, second that
> the dead memmove call gets deleted.
>
> Bootstrapped and regression tested on x86_64-linux-gnu.  Installing on the
> trunk.
>
> Again folks, sorry for the breakage over the weekend.
>
> Jeff
>
> commit b241d3db9d195bdffa4349cea077ee0e94985435
> Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
> Date:   Mon Jan 16 23:43:05 2017 +0000
>
>     2017-01-16  Jeff Law  <law@redhat.com>
>
>         PR tree-optimization/79090
>         PR tree-optimization/33562
>         PR tree-optimization/61912
>         PR tree-optimization/77485
>         * tree-ssa-dse.c (compute_trims): Accept STMT argument.  Dump STMT
>         and computed trims into the dump file.
>
>         PR tree-optimization/79090
>         PR tree-optimization/33562
>         PR tree-optimization/61912
>         PR tree-optimization/77485
>         * tree-ssa-dse.c (compute_trims): Accept STMT argument.  Dump STMT
>         and computed trims into the dump file.
>
>     git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@244509
> 138bc75d-0d04-0410-961f-82ee72b054a4
>
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index 265e3a5..8507528 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,12 @@
> +2017-01-16  Jeff Law  <law@redhat.com>
> +
> +       PR tree-optimization/79090
> +       PR tree-optimization/33562
> +       PR tree-optimization/61912
> +       PR tree-optimization/77485
> +       * tree-ssa-dse.c (compute_trims): Accept STMT argument.  Dump STMT
> +       and computed trims into the dump file.
> +
>  2017-01-17  Uros Bizjak  <ubizjak@gmail.com>
>
>         * config/i386/i386.h (LIMIT_RELOAD_CLASS): Remove.
> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
> index ef1fea5..09c5d52 100644
> --- a/gcc/testsuite/ChangeLog
> +++ b/gcc/testsuite/ChangeLog
> @@ -1,3 +1,12 @@
> +2017-01-16  Jeff Law  <law@redhat.com>
> +
> +       PR tree-optimization/33562
> +       PR tree-optimization/61912
> +       PR tree-optimization/77485
> +       PR tree-optimization/79090
> +       * gcc.dg/tree-ssa/ssa-dse-29.c: New test.
> +       * g++.dg/tree-ssa/ssa-dse-2.C: New test.
> +

The new ssa-dse-2.C test fails on arm because:
warning: declaration of 'void* memmove(void*, const void*, size_t)'
conflicts with built-in declaration 'void* memmove(void*, const void*,
unsigned int)' [-Wbuiltin-declaration-mismatch]

Christophe

>  2017-01-16  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c/79089
> diff --git a/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-2.C
> b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-2.C
> new file mode 100644
> index 0000000..d69edd2
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/tree-ssa/ssa-dse-2.C
> @@ -0,0 +1,59 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-dse2-details" } */
> +
> +typedef long unsigned int size_t;
> +extern "C"
> +{
> +  extern void *memmove (void *__dest, const void *__src, size_t __n) throw
> ()
> +    __attribute__ ((__nonnull__ (1, 2)));
> +}
> +extern void abort () __attribute__ ((__noreturn__));
> +struct vec_prefix { unsigned m_num; };
> +struct vl_embed { };
> +struct vl_ptr { };
> +struct va_heap { typedef vl_ptr default_layout; };
> +template < typename T, typename A = va_heap, typename L = typename
> A::default_layout > struct vec { };
> +template < typename T, typename A > struct vec < T, A, vl_embed >
> +{
> +  unsigned length (void) const { return m_vecpfx.  m_num; }
> +  bool is_empty (void) const { return m_vecpfx.  m_num == 0; }
> +  void block_remove (unsigned, unsigned);
> +  vec_prefix m_vecpfx;
> +  T m_vecdata[1];
> +};
> +template < typename T, typename A > inline void vec < T, A, vl_embed
>>::block_remove (unsigned ix, unsigned len)
> +{
> +  T * slot = &m_vecdata[ix];
> +  m_vecpfx.m_num -= len;
> +  memmove (slot, slot + len, (m_vecpfx.m_num - ix) * sizeof (T));
> +}
> +
> +template < typename T > struct vec < T, va_heap, vl_ptr >
> +{
> +  bool is_empty (void) const { return m_vec ?  m_vec-> is_empty () : true;
> }
> +  unsigned length (void) const { return m_vec ?  m_vec-> length () : 0; }
> +  void block_remove (unsigned, unsigned);
> +  vec < T, va_heap, vl_embed > * m_vec;
> +};
> +template < typename T > inline void vec < T, va_heap, vl_ptr
>>::block_remove (unsigned ix, unsigned len)
> +{
> +  m_vec->block_remove (ix, len);
> +}
> +
> +typedef struct _list_node * _list_t;
> +typedef struct _expr expr_def;
> +typedef expr_def * expr_t;
> +typedef _list_t av_set_t;
> +static vec < expr_t > vec_av_set;
> +bool
> +fill_vec_av_set (av_set_t av)
> +{
> +  if (vec_av_set.length () > 0)
> +    vec_av_set.block_remove (0, vec_av_set.length ());
> +  ((!(vec_av_set.is_empty ())? abort () , 0 : 0));
> +}
> +
> +/* { dg-final { scan-tree-dump-not "Trimming statement .head = -" "dse2" }
> } */
> +/* { dg-final { scan-tree-dump "Deleted dead call: " "dse2" } } */
> +
> +
> diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c
> b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c
> new file mode 100644
> index 0000000..31529e7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-29.c
> @@ -0,0 +1,26 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fdump-tree-dse-details" } */
> +
> +struct z {
> +  int a;
> +  int b;
> +  int c;
> +};
> +
> +int
> +foo(int cond, struct z *s)
> +{
> +
> +  if (cond)
> +    {
> +      s->a = 1;
> +      s->b = 2;
> +      s->c = 3;
> +    }
> +  __builtin_memset (s, 0, sizeof (struct z));
> +}
> +
> +/* { dg-final { scan-tree-dump-times "Deleted dead store" 3 "dse1"} } */
> +/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse2"} } */
> +/* { dg-final { scan-tree-dump-not "Deleted dead store" "dse3"} } */
> +
> diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
> index 65dcb12..84c0b11 100644
> --- a/gcc/tree-ssa-dse.c
> +++ b/gcc/tree-ssa-dse.c
> @@ -212,10 +212,14 @@ setup_live_bytes_from_ref (ao_ref *ref, sbitmap
> live_bytes)
>     tail of ORIG resulting in a bitmap that is a superset of LIVE.
>
>     Store the number of elements trimmed from the head and tail in
> -   TRIM_HEAD and TRIM_TAIL.  */
> +   TRIM_HEAD and TRIM_TAIL.
> +
> +   STMT is the statement being trimmed and is used for debugging dump
> +   output only.  */
>
>  static void
> -compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail)
> +compute_trims (ao_ref *ref, sbitmap live, int *trim_head, int *trim_tail,
> +              gimple *stmt)
>  {
>    /* We use sbitmaps biased such that ref->offset is bit zero and the
> bitmap
>       extends through ref->size.  So we know that in the original bitmap
> @@ -231,6 +235,15 @@ compute_trims (ao_ref *ref, sbitmap live, int
> *trim_head, int *trim_tail)
>    int first_orig = 0;
>    int first_live = bitmap_first_set_bit (live);
>    *trim_head = (first_live - first_orig) & ~0x1;
> +
> +  if ((*trim_head || *trim_tail)
> +      && dump_file && (dump_flags & TDF_DETAILS))
> +    {
> +      fprintf (dump_file, "  Trimming statement (head = %d, tail = %d): ",
> +              *trim_head, *trim_tail);
> +      print_gimple_stmt (dump_file, stmt, dump_flags, 0);
> +      fprintf (dump_file, "\n");
> +    }
>  }
>
>  /* STMT initializes an object from COMPLEX_CST where one or more of the
> @@ -244,7 +257,7 @@ static void
>  maybe_trim_complex_store (ao_ref *ref, sbitmap live, gimple *stmt)
>  {
>    int trim_head, trim_tail;
> -  compute_trims (ref, live, &trim_head, &trim_tail);
> +  compute_trims (ref, live, &trim_head, &trim_tail, stmt);
>
>    /* The amount of data trimmed from the head or tail must be at
>       least half the size of the object to ensure we're trimming
> @@ -296,7 +309,7 @@ maybe_trim_constructor_store (ao_ref *ref, sbitmap live,
> gimple *stmt)
>
>    int head_trim = 0;
>    int tail_trim = 0;
> -  compute_trims (ref, live, &head_trim, &tail_trim);
> +  compute_trims (ref, live, &head_trim, &tail_trim, stmt);
>
>    /* Now we want to replace the constructor initializer
>       with memset (object + head_trim, 0, size - head_trim - tail_trim).  */
> @@ -384,7 +397,7 @@ maybe_trim_memstar_call (ao_ref *ref, sbitmap live,
> gimple *stmt)
>      case BUILT_IN_MEMMOVE:
>        {
>         int head_trim, tail_trim;
> -       compute_trims (ref, live, &head_trim, &tail_trim);
> +       compute_trims (ref, live, &head_trim, &tail_trim, stmt);
>
>         /* Tail trimming is easy, we can just reduce the count.  */
>          if (tail_trim)
> @@ -405,7 +418,7 @@ maybe_trim_memstar_call (ao_ref *ref, sbitmap live,
> gimple *stmt)
>      case BUILT_IN_MEMSET:
>        {
>         int head_trim, tail_trim;
> -       compute_trims (ref, live, &head_trim, &tail_trim);
> +       compute_trims (ref, live, &head_trim, &tail_trim, stmt);
>
>         /* Tail trimming is easy, we can just reduce the count.  */
>          if (tail_trim)
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]