Commit 58adb739 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/43560 (possible wrong code bug)

2010-03-29  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/43560
	* tree-ssa-loop-im.c (ref_always_accessed_p): Add store_p
	parameter.
	(can_sm_ref_p): Treat stores to readonly locations as
	trapping.

	* gcc.dg/torture/pr43560.c: New testcase.

From-SVN: r157799
parent 52150625
2010-03-29 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43560
* tree-ssa-loop-im.c (ref_always_accessed_p): Add store_p
parameter.
(can_sm_ref_p): Treat stores to readonly locations as
trapping.
2010-03-29 Jie Zhang <jie@codesourcery.com>
PR 43564
......
2010-03-29 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43560
* gcc.dg/torture/pr43560.c: New testcase.
2010-03-29 Jason Merrill <jason@redhat.com>
N3077
......
/* { dg-do run } */
/* { dg-require-weak "" } */
int g_6[1][2] = {{1,1}};
int g_34 = 0;
int *const g_82 = &g_6[0][1];
int *g_85[2][1] __attribute__((weak));
void __attribute__((noinline))
func_4 (int x)
{
int i;
for (i = 0; i <= x; i++) {
if (g_6[0][1]) {
*g_82 = 1;
} else {
int **l_109 = &g_85[1][0];
if (&g_82 != l_109) {
} else {
*l_109 = &g_6[0][1];
}
*g_82 = 1;
}
}
}
int main (void)
{
g_85[0][0] = &g_34;
g_85[1][0] = &g_34;
func_4(1);
return 0;
}
......@@ -1900,16 +1900,22 @@ hoist_memory_references (struct loop *loop, bitmap mem_refs,
}
}
/* Returns true if REF is always accessed in LOOP. */
/* Returns true if REF is always accessed in LOOP. If STORED_P is true
make sure REF is always stored to in LOOP. */
static bool
ref_always_accessed_p (struct loop *loop, mem_ref_p ref)
ref_always_accessed_p (struct loop *loop, mem_ref_p ref, bool stored_p)
{
VEC (mem_ref_loc_p, heap) *locs = NULL;
unsigned i;
mem_ref_loc_p loc;
bool ret = false;
struct loop *must_exec;
tree base;
base = get_base_address (ref->mem);
if (INDIRECT_REF_P (base))
base = TREE_OPERAND (base, 0);
get_all_locs_in_loop (loop, ref, &locs);
for (i = 0; VEC_iterate (mem_ref_loc_p, locs, i, loc); i++)
......@@ -1917,6 +1923,22 @@ ref_always_accessed_p (struct loop *loop, mem_ref_p ref)
if (!get_lim_data (loc->stmt))
continue;
/* If we require an always executed store make sure the statement
stores to the reference. */
if (stored_p)
{
tree lhs;
if (!gimple_get_lhs (loc->stmt))
continue;
lhs = get_base_address (gimple_get_lhs (loc->stmt));
if (!lhs)
continue;
if (INDIRECT_REF_P (lhs))
lhs = TREE_OPERAND (lhs, 0);
if (lhs != base)
continue;
}
must_exec = get_lim_data (loc->stmt)->always_executed_in;
if (!must_exec)
continue;
......@@ -2054,6 +2076,8 @@ ref_indep_loop_p (struct loop *loop, mem_ref_p ref)
static bool
can_sm_ref_p (struct loop *loop, mem_ref_p ref)
{
tree base;
/* Unless the reference is stored in the loop, there is nothing to do. */
if (!bitmap_bit_p (ref->stored, loop->num))
return false;
......@@ -2064,9 +2088,14 @@ can_sm_ref_p (struct loop *loop, mem_ref_p ref)
|| !for_each_index (&ref->mem, may_move_till, loop))
return false;
/* If it can trap, it must be always executed in LOOP. */
if (tree_could_trap_p (ref->mem)
&& !ref_always_accessed_p (loop, ref))
/* If it can trap, it must be always executed in LOOP.
Readonly memory locations may trap when storing to them, but
tree_could_trap_p is a predicate for rvalues, so check that
explicitly. */
base = get_base_address (ref->mem);
if ((tree_could_trap_p (ref->mem)
|| (DECL_P (base) && TREE_READONLY (base)))
&& !ref_always_accessed_p (loop, ref, true))
return false;
/* And it must be independent on all other memory references
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment