re PR tree-optimization/91137 (Wrong code with -O3)
PR tree-optimization/91137 * tree-ssa-loop-ivopts.c (struct ivopts_data): New field. (tree_ssa_iv_optimize_init, alloc_iv, tree_ssa_iv_optimize_finalize): Init, use and fini the above new field. (determine_base_object_1): New function. (determine_base_object): Reimplement using walk_tree. gcc/testsuite PR tree-optimization/91137 * gcc.c-torture/execute/pr91137.c: New test. From-SVN: r273570
This commit is contained in:
parent
f1f1054190
commit
3796e3b399
4 changed files with 104 additions and 44 deletions
|
@ -1,3 +1,12 @@
|
|||
2019-07-18 Bin Cheng <bin.linux@linux.alibaba.com>
|
||||
|
||||
PR tree-optimization/91137
|
||||
* tree-ssa-loop-ivopts.c (struct ivopts_data): New field.
|
||||
(tree_ssa_iv_optimize_init, alloc_iv, tree_ssa_iv_optimize_finalize):
|
||||
Init, use and fini the above new field.
|
||||
(determine_base_object_1): New function.
|
||||
(determine_base_object): Reimplement using walk_tree.
|
||||
|
||||
2019-07-18 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* basic-block.h (CLEANUP_FORCE_FAST_DCE): New macro.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2019-07-18 Bin Cheng <bin.linux@linux.alibaba.com>
|
||||
|
||||
PR tree-optimization/91137
|
||||
* gcc.c-torture/execute/pr91137.c: New test.
|
||||
|
||||
2019-07-18 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* c-c++-common/pr53633-2.c: New test.
|
||||
|
|
34
gcc/testsuite/gcc.c-torture/execute/pr91137.c
Normal file
34
gcc/testsuite/gcc.c-torture/execute/pr91137.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
long long a;
|
||||
unsigned b;
|
||||
int c[70];
|
||||
int d[70][70];
|
||||
int e;
|
||||
|
||||
__attribute__ ((noinline)) void f(long long *g, int p2) {
|
||||
*g = p2;
|
||||
}
|
||||
|
||||
__attribute__ ((noinline)) void fn2() {
|
||||
for (int j = 0; j < 70; j++) {
|
||||
for (int i = 0; i < 70; i++) {
|
||||
if (b)
|
||||
c[i] = 0;
|
||||
for (int l = 0; l < 70; l++)
|
||||
d[i][1] = d[l][i];
|
||||
}
|
||||
for (int k = 0; k < 70; k++)
|
||||
e = c[0];
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
b = 5;
|
||||
for (int j = 0; j < 70; ++j)
|
||||
c[j] = 2075593088;
|
||||
fn2();
|
||||
f(&a, e);
|
||||
if (a)
|
||||
__builtin_abort();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -591,6 +591,9 @@ struct ivopts_data
|
|||
/* The common candidates. */
|
||||
vec<iv_common_cand *> iv_common_cands;
|
||||
|
||||
/* Hash map recording base object information of tree exp. */
|
||||
hash_map<tree, tree> *base_object_map;
|
||||
|
||||
/* The maximum invariant variable id. */
|
||||
unsigned max_inv_var_id;
|
||||
|
||||
|
@ -1043,61 +1046,68 @@ tree_ssa_iv_optimize_init (struct ivopts_data *data)
|
|||
data->vcands.create (20);
|
||||
data->inv_expr_tab = new hash_table<iv_inv_expr_hasher> (10);
|
||||
data->name_expansion_cache = NULL;
|
||||
data->base_object_map = NULL;
|
||||
data->iv_common_cand_tab = new hash_table<iv_common_cand_hasher> (10);
|
||||
data->iv_common_cands.create (20);
|
||||
decl_rtl_to_reset.create (20);
|
||||
gcc_obstack_init (&data->iv_obstack);
|
||||
}
|
||||
|
||||
/* Returns a memory object to that EXPR points. In case we are able to
|
||||
determine that it does not point to any such object, NULL is returned. */
|
||||
/* walk_tree callback for determine_base_object. */
|
||||
|
||||
static tree
|
||||
determine_base_object (tree expr)
|
||||
determine_base_object_1 (tree *tp, int *walk_subtrees, void *wdata)
|
||||
{
|
||||
enum tree_code code = TREE_CODE (expr);
|
||||
tree base, obj;
|
||||
|
||||
/* If this is a pointer casted to any type, we need to determine
|
||||
the base object for the pointer; so handle conversions before
|
||||
throwing away non-pointer expressions. */
|
||||
if (CONVERT_EXPR_P (expr))
|
||||
return determine_base_object (TREE_OPERAND (expr, 0));
|
||||
|
||||
if (!POINTER_TYPE_P (TREE_TYPE (expr)))
|
||||
return NULL_TREE;
|
||||
|
||||
switch (code)
|
||||
tree_code code = TREE_CODE (*tp);
|
||||
tree obj = NULL_TREE;
|
||||
if (code == ADDR_EXPR)
|
||||
{
|
||||
case INTEGER_CST:
|
||||
return NULL_TREE;
|
||||
|
||||
case ADDR_EXPR:
|
||||
obj = TREE_OPERAND (expr, 0);
|
||||
base = get_base_address (obj);
|
||||
|
||||
tree base = get_base_address (TREE_OPERAND (*tp, 0));
|
||||
if (!base)
|
||||
return expr;
|
||||
|
||||
if (TREE_CODE (base) == MEM_REF)
|
||||
return determine_base_object (TREE_OPERAND (base, 0));
|
||||
|
||||
return fold_convert (ptr_type_node,
|
||||
build_fold_addr_expr (base));
|
||||
|
||||
case POINTER_PLUS_EXPR:
|
||||
return determine_base_object (TREE_OPERAND (expr, 0));
|
||||
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
/* Pointer addition is done solely using POINTER_PLUS_EXPR. */
|
||||
gcc_unreachable ();
|
||||
|
||||
default:
|
||||
if (POLY_INT_CST_P (expr))
|
||||
return NULL_TREE;
|
||||
return fold_convert (ptr_type_node, expr);
|
||||
obj = *tp;
|
||||
else if (TREE_CODE (base) != MEM_REF)
|
||||
obj = fold_convert (ptr_type_node, build_fold_addr_expr (base));
|
||||
}
|
||||
else if (code == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (*tp)))
|
||||
obj = fold_convert (ptr_type_node, *tp);
|
||||
|
||||
if (!obj)
|
||||
{
|
||||
if (!EXPR_P (*tp))
|
||||
*walk_subtrees = 0;
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
/* Record special node for multiple base objects and stop. */
|
||||
if (*static_cast<tree *> (wdata))
|
||||
{
|
||||
*static_cast<tree *> (wdata) = integer_zero_node;
|
||||
return integer_zero_node;
|
||||
}
|
||||
/* Record the base object and continue looking. */
|
||||
*static_cast<tree *> (wdata) = obj;
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Returns a memory object to that EXPR points with caching. Return NULL if we
|
||||
are able to determine that it does not point to any such object; specially
|
||||
return integer_zero_node if EXPR contains multiple base objects. */
|
||||
|
||||
static tree
|
||||
determine_base_object (struct ivopts_data *data, tree expr)
|
||||
{
|
||||
tree *slot, obj = NULL_TREE;
|
||||
if (data->base_object_map)
|
||||
{
|
||||
if ((slot = data->base_object_map->get(expr)) != NULL)
|
||||
return *slot;
|
||||
}
|
||||
else
|
||||
data->base_object_map = new hash_map<tree, tree>;
|
||||
|
||||
(void) walk_tree_without_duplicates (&expr, determine_base_object_1, &obj);
|
||||
data->base_object_map->put (expr, obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/* Return true if address expression with non-DECL_P operand appears
|
||||
|
@ -1155,7 +1165,7 @@ alloc_iv (struct ivopts_data *data, tree base, tree step,
|
|||
}
|
||||
|
||||
iv->base = base;
|
||||
iv->base_object = determine_base_object (base);
|
||||
iv->base_object = determine_base_object (data, base);
|
||||
iv->step = step;
|
||||
iv->biv_p = false;
|
||||
iv->nonlin_use = NULL;
|
||||
|
@ -7527,6 +7537,8 @@ tree_ssa_iv_optimize_finalize (struct ivopts_data *data)
|
|||
delete data->inv_expr_tab;
|
||||
data->inv_expr_tab = NULL;
|
||||
free_affine_expand_cache (&data->name_expansion_cache);
|
||||
if (data->base_object_map)
|
||||
delete data->base_object_map;
|
||||
delete data->iv_common_cand_tab;
|
||||
data->iv_common_cand_tab = NULL;
|
||||
data->iv_common_cands.release ();
|
||||
|
|
Loading…
Add table
Reference in a new issue