1  /* { dg-do compile { target { nonpic || pie_enabled } } } */
       2  /* { dg-options "-O2 -fdump-tree-pre-stats -fdump-tree-fre1" } */
       3  #include <stddef.h>
       4  
       5  union tree_node;
       6  typedef union tree_node *tree;
       7  
       8  struct tree_common
       9  {
      10    tree chain;
      11  };
      12  
      13  struct tree_list
      14  {
      15    struct tree_common common;
      16    tree value;
      17  };
      18  
      19  union tree_node
      20  
      21  {
      22    struct tree_common common;
      23    struct tree_list list;
      24  };
      25  
      26  extern void abort (void) __attribute__((noreturn));
      27  
      28  void __attribute__((noinline))
      29  foo (void)
      30  {
      31    abort ();
      32  }
      33  
      34  /* There are some reloaded loads of *cell, and cell->common.chain on various
      35     branches.  */
      36  void __attribute__((noinline))
      37  remove_useless_vars (tree *unexpanded_var_list, int dump_file)
      38  {
      39    tree var, *cell;
      40    int c = 0;
      41    for (cell = unexpanded_var_list; *cell; )
      42      {
      43        var = (*cell)->list.value;
      44        if (var)
      45          {
      46            if (dump_file)
      47              foo ();
      48  
      49            *cell = ((*cell)->common.chain);
      50            continue;
      51          }
      52  
      53        cell = &((*cell)->common.chain);
      54      }
      55  }
      56  extern void *malloc (__SIZE_TYPE__) __attribute__ ((malloc));
      57  
      58  int
      59  main (void)
      60  {
      61    int i;
      62    tree unexpanded_var_list, last = (tree) 0;
      63  
      64    for (i = 0; i < 2; i++)
      65      {
      66        unexpanded_var_list = malloc (sizeof (struct tree_list));
      67        unexpanded_var_list->list.value = (tree) (ptrdiff_t) (i & 1);
      68        unexpanded_var_list->common.chain = last;
      69        last = unexpanded_var_list;
      70      }
      71  
      72    remove_useless_vars (&unexpanded_var_list, 0);
      73    return 0;
      74  }
      75  
      76  /* { dg-final { scan-tree-dump-not "= unexpanded_var_list;" "fre1" } } */
      77  /* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre" } } */
      78  /* { dg-final { scan-tree-dump-times "Insertions: 1" 1 "pre" } } */