ipa/102714 - IPA SRA eliding volatile
The following fixes the volatileness check of IPA SRA which was looking at the innermost reference when checking TREE_THIS_VOLATILE but the reference to check is the outermost one. 2021-10-13 Richard Biener <rguenther@suse.de> PR ipa/102714 * ipa-sra.c (ptr_parm_has_nonarg_uses): Fix volatileness check. * gcc.dg/ipa/pr102714.c: New testcase.
This commit is contained in:
parent
78fff8a4da
commit
23cd18c60c
@ -1005,15 +1005,17 @@ ptr_parm_has_nonarg_uses (cgraph_node *node, function *fun, tree parm,
|
||||
if (gimple_assign_single_p (stmt))
|
||||
{
|
||||
tree rhs = gimple_assign_rhs1 (stmt);
|
||||
while (handled_component_p (rhs))
|
||||
rhs = TREE_OPERAND (rhs, 0);
|
||||
if (TREE_CODE (rhs) == MEM_REF
|
||||
&& TREE_OPERAND (rhs, 0) == name
|
||||
&& integer_zerop (TREE_OPERAND (rhs, 1))
|
||||
&& types_compatible_p (TREE_TYPE (rhs),
|
||||
TREE_TYPE (TREE_TYPE (name)))
|
||||
&& !TREE_THIS_VOLATILE (rhs))
|
||||
uses_ok++;
|
||||
if (!TREE_THIS_VOLATILE (rhs))
|
||||
{
|
||||
while (handled_component_p (rhs))
|
||||
rhs = TREE_OPERAND (rhs, 0);
|
||||
if (TREE_CODE (rhs) == MEM_REF
|
||||
&& TREE_OPERAND (rhs, 0) == name
|
||||
&& integer_zerop (TREE_OPERAND (rhs, 1))
|
||||
&& types_compatible_p (TREE_TYPE (rhs),
|
||||
TREE_TYPE (TREE_TYPE (name))))
|
||||
uses_ok++;
|
||||
}
|
||||
}
|
||||
else if (is_gimple_call (stmt))
|
||||
{
|
||||
@ -1047,15 +1049,17 @@ ptr_parm_has_nonarg_uses (cgraph_node *node, function *fun, tree parm,
|
||||
continue;
|
||||
}
|
||||
|
||||
while (handled_component_p (arg))
|
||||
arg = TREE_OPERAND (arg, 0);
|
||||
if (TREE_CODE (arg) == MEM_REF
|
||||
&& TREE_OPERAND (arg, 0) == name
|
||||
&& integer_zerop (TREE_OPERAND (arg, 1))
|
||||
&& types_compatible_p (TREE_TYPE (arg),
|
||||
TREE_TYPE (TREE_TYPE (name)))
|
||||
&& !TREE_THIS_VOLATILE (arg))
|
||||
uses_ok++;
|
||||
if (!TREE_THIS_VOLATILE (arg))
|
||||
{
|
||||
while (handled_component_p (arg))
|
||||
arg = TREE_OPERAND (arg, 0);
|
||||
if (TREE_CODE (arg) == MEM_REF
|
||||
&& TREE_OPERAND (arg, 0) == name
|
||||
&& integer_zerop (TREE_OPERAND (arg, 1))
|
||||
&& types_compatible_p (TREE_TYPE (arg),
|
||||
TREE_TYPE (TREE_TYPE (name))))
|
||||
uses_ok++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
117
gcc/testsuite/gcc.dg/ipa/pr102714.c
Normal file
117
gcc/testsuite/gcc.dg/ipa/pr102714.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-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 *)((unsigned long)ptr & ~2UL);
|
||||
}
|
||||
|
||||
static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) bool radix_tree_is_internal_node(void *ptr)
|
||||
{
|
||||
return ((unsigned long)ptr & 3UL) ==
|
||||
2UL;
|
||||
}
|
||||
|
||||
static inline __attribute__((__gnu_inline__)) __attribute__((__unused__)) __attribute__((no_instrument_function)) void *xa_mk_internal(unsigned long 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" } } */
|
Loading…
Reference in New Issue
Block a user