/* { dg-do compile } */ /* { dg-options "-std=gnu17 -O2 -fno-strict-aliasing -fdump-ipa-sra-details -fdump-tree-optimized" } */ typedef _Bool bool; enum { false = 0, true = 1 }; struct xarray { unsigned int xa_lock; unsigned int xa_flags; void * xa_head; }; struct list_head { struct list_head *next, *prev; }; struct callback_head { struct callback_head *next; void (*func)(struct callback_head *head); } __attribute__((aligned(sizeof(void *)))); struct xa_node { unsigned char shift; unsigned char offset; unsigned char count; unsigned char nr_values; struct xa_node *parent; struct xarray *array; union { struct list_head private_list; struct callback_head callback_head; }; void *slots[(1UL << (0 ? 4 : 6))]; union { unsigned long tags[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))]; unsigned long marks[3][((((1UL << (0 ? 4 : 6))) + (64) - 1) / (64))]; }; }; static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long shift_maxindex(unsigned int shift) { return ((1UL << (0 ? 4 : 6)) << shift) - 1; } static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) unsigned long node_maxindex(const struct xa_node *node) { return shift_maxindex(node->shift); } static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) struct xa_node *entry_to_node(void *ptr) { return (void *)((__UINTPTR_TYPE__)ptr & ~(__UINTPTR_TYPE__)2); } static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) bool radix_tree_is_internal_node(void *ptr) { return ((__UINTPTR_TYPE__)ptr & 3UL) == 2UL; } static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) void *xa_mk_internal(__UINTPTR_TYPE__ v) { return (void *)((v << 2) | 2); } static unsigned radix_tree_load_root(const struct xarray *root, struct xa_node **nodep, unsigned long *maxindex) { struct xa_node *node = ({ typeof(root->xa_head) ________p1 = ({(*(const volatile typeof(root->xa_head) *)&(root->xa_head)); }); ((typeof(*root->xa_head) *)(________p1)); }); *nodep = node; if (__builtin_expect(!!(radix_tree_is_internal_node(node)), 1)) { node = entry_to_node(node); *maxindex = node_maxindex(node); return node->shift + (0 ? 4 : 6); } *maxindex = 0; return 0; } void *__radix_tree_lookup(const struct xarray *root, unsigned long index, struct xa_node **nodep, void ***slotp) { struct xa_node *node, *parent; unsigned long maxindex; restart: parent = ((void *)0); radix_tree_load_root(root, &node, &maxindex); while (radix_tree_is_internal_node(node)) { parent = entry_to_node(node); if (node == xa_mk_internal(256)) goto restart; if (parent->shift == 0) break; } if (nodep) *nodep = parent; return node; } /* { dg-final { scan-ipa-dump-not "IPA_PARAM_OP_SPLIT" "sra" } } */ /* { dg-final { scan-tree-dump " ={v} " "optimized" } } */