(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
ipa/
pr102714.c
       1  /* { dg-do compile } */
       2  /* { dg-options "-O2 -fno-strict-aliasing -fdump-ipa-sra-details -fdump-tree-optimized" } */
       3  
       4  typedef _Bool bool;
       5  
       6  enum {
       7   false = 0,
       8   true = 1
       9  };
      10  
      11  struct xarray {
      12   unsigned int xa_lock;
      13   unsigned int xa_flags;
      14   void * xa_head;
      15  
      16  };
      17  
      18  struct list_head {
      19   struct list_head *next, *prev;
      20  };
      21  
      22  struct callback_head {
      23   struct callback_head *next;
      24   void (*func)(struct callback_head *head);
      25  } __attribute__((aligned(sizeof(void *))));
      26  
      27  struct xa_node {
      28   unsigned char shift;
      29   unsigned char offset;
      30   unsigned char count;
      31   unsigned char nr_values;
      32   struct xa_node *parent;
      33   struct xarray *array;
      34   union {
      35    struct list_head private_list;
      36    struct callback_head callback_head;
      37   };
      38   void *slots[(1UL << (0 ? 4 : 6))];
      39   union {
      40    unsigned long tags[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))];
      41    unsigned long marks[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))];
      42   };
      43  };
      44  
      45  static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long shift_maxindex(unsigned int shift)
      46  {
      47   return ((1UL << (0 ? 4 : 6)) << shift) - 1;
      48  }
      49  
      50  static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long node_maxindex(const struct xa_node *node)
      51  {
      52   return shift_maxindex(node->shift);
      53  }
      54  
      55  static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) struct xa_node *entry_to_node(void *ptr)
      56  {
      57   return (void *)((unsigned long)ptr & ~2UL);
      58  }
      59  
      60  static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) bool radix_tree_is_internal_node(void *ptr)
      61  {
      62   return ((unsigned long)ptr & 3UL) ==
      63      2UL;
      64  }
      65  
      66  static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) void *xa_mk_internal(unsigned long v)
      67  {
      68   return (void *)((v << 2) | 2);
      69  }
      70  
      71  static unsigned radix_tree_load_root(const struct xarray *root,
      72    struct xa_node **nodep, unsigned long *maxindex)
      73  {
      74   struct xa_node *node =
      75   ({
      76      typeof(root->xa_head) ________p1 = ({(*(const volatile typeof(root->xa_head) *)&(root->xa_head)); });
      77      ((typeof(*root->xa_head) *)(________p1));
      78   });
      79  
      80   *nodep = node;
      81  
      82   if (__builtin_expect(!!(radix_tree_is_internal_node(node)), 1)) {
      83    node = entry_to_node(node);
      84    *maxindex = node_maxindex(node);
      85    return node->shift + (0 ? 4 : 6);
      86   }
      87  
      88   *maxindex = 0;
      89   return 0;
      90  }
      91  
      92  void *__radix_tree_lookup(const struct xarray *root,
      93       unsigned long index, struct xa_node **nodep,
      94       void ***slotp)
      95  {
      96   struct xa_node *node, *parent;
      97   unsigned long maxindex;
      98  
      99   restart:
     100   parent = ((void *)0);
     101   radix_tree_load_root(root, &node, &maxindex);
     102   while (radix_tree_is_internal_node(node)) {
     103  
     104    parent = entry_to_node(node);
     105    if (node == xa_mk_internal(256))
     106     goto restart;
     107    if (parent->shift == 0)
     108     break;
     109   }
     110   if (nodep)
     111    *nodep = parent;
     112  
     113   return node;
     114  }
     115  
     116  /* { dg-final { scan-ipa-dump-not "IPA_PARAM_OP_SPLIT" "sra" } } */
     117  /* { dg-final { scan-tree-dump " ={v} " "optimized" } } */