Commit bcfaa720 by Richard Biener Committed by Richard Biener

re PR ipa/81877 (Incorrect results with lto and -fipa-cp and -fipa-cp-clone)

2017-12-18  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/81877
	* tree-ssa-loop-im.c (ref_indep_loop_p): Remove safelen parameters.
	(outermost_indep_loop): Adjust.
	(ref_indep_loop_p_1): Likewise.  Remove safelen handling again.
	(can_sm_ref_p): Adjust.

	* g++.dg/torture/pr81877.C: New testcase.
	* g++.dg/vect/pr70729.cc: XFAIL.
	* g++.dg/vect/pr70729-nest.cc: XFAIL.

From-SVN: r255776
parent 8c3563f3
2017-12-18 Richard Biener <rguenther@suse.de> 2017-12-18 Richard Biener <rguenther@suse.de>
PR tree-optimization/81877
* tree-ssa-loop-im.c (ref_indep_loop_p): Remove safelen parameters.
(outermost_indep_loop): Adjust.
(ref_indep_loop_p_1): Likewise. Remove safelen handling again.
(can_sm_ref_p): Adjust.
2017-12-18 Richard Biener <rguenther@suse.de>
PR middle-end/77291 PR middle-end/77291
* tree.c (array_at_struct_end_p): Return true if the underlying * tree.c (array_at_struct_end_p): Return true if the underlying
object has space for at least one element in excess of what object has space for at least one element in excess of what
2017-12-18 Richard Biener <rguenther@suse.de> 2017-12-18 Richard Biener <rguenther@suse.de>
PR tree-optimization/81877
* g++.dg/torture/pr81877.C: New testcase.
* g++.dg/vect/pr70729.cc: XFAIL.
* g++.dg/vect/pr70729-nest.cc: XFAIL.
2017-12-18 Richard Biener <rguenther@suse.de>
PR middle-end/77291 PR middle-end/77291
* gcc.dg/Warray-bounds-26.c: New testcase. * gcc.dg/Warray-bounds-26.c: New testcase.
......
/* { dg-do run } */
void __attribute__((noipa)) g(int p, int *out)
{
int x = 0, y;
#pragma GCC ivdep
for (int i = 0; i < 100; i++)
{
int &r = p ? x : y;
r = 42;
out[i] = x;
}
}
int main()
{
int out[100] = { 0 };
g (1, out);
if (out[0] != 42)
__builtin_abort ();
return 0;
}
...@@ -76,4 +76,4 @@ void Ss::foo (int n) ...@@ -76,4 +76,4 @@ void Ss::foo (int n)
} }
} }
// { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target x86_64-*-* i?86-*-* } } } // { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { xfail *-*-* } } }
...@@ -70,4 +70,4 @@ void Ss::foo (float *in, float w) ...@@ -70,4 +70,4 @@ void Ss::foo (float *in, float w)
} }
} }
// { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target x86_64-*-* i?86-*-* } } } // { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { xfail *-*-* } } }
...@@ -199,7 +199,7 @@ static struct ...@@ -199,7 +199,7 @@ static struct
static bitmap_obstack lim_bitmap_obstack; static bitmap_obstack lim_bitmap_obstack;
static obstack mem_ref_obstack; static obstack mem_ref_obstack;
static bool ref_indep_loop_p (struct loop *, im_mem_ref *, struct loop *); static bool ref_indep_loop_p (struct loop *, im_mem_ref *);
static bool ref_always_accessed_p (struct loop *, im_mem_ref *, bool); static bool ref_always_accessed_p (struct loop *, im_mem_ref *, bool);
/* Minimum cost of an expensive expression. */ /* Minimum cost of an expensive expression. */
...@@ -548,10 +548,10 @@ outermost_indep_loop (struct loop *outer, struct loop *loop, im_mem_ref *ref) ...@@ -548,10 +548,10 @@ outermost_indep_loop (struct loop *outer, struct loop *loop, im_mem_ref *ref)
aloop != loop; aloop != loop;
aloop = superloop_at_depth (loop, loop_depth (aloop) + 1)) aloop = superloop_at_depth (loop, loop_depth (aloop) + 1))
if ((!ref->stored || !bitmap_bit_p (ref->stored, aloop->num)) if ((!ref->stored || !bitmap_bit_p (ref->stored, aloop->num))
&& ref_indep_loop_p (aloop, ref, loop)) && ref_indep_loop_p (aloop, ref))
return aloop; return aloop;
if (ref_indep_loop_p (loop, ref, loop)) if (ref_indep_loop_p (loop, ref))
return loop; return loop;
else else
return NULL; return NULL;
...@@ -2150,20 +2150,13 @@ record_dep_loop (struct loop *loop, im_mem_ref *ref, bool stored_p) ...@@ -2150,20 +2150,13 @@ record_dep_loop (struct loop *loop, im_mem_ref *ref, bool stored_p)
} }
/* Returns true if REF is independent on all other memory /* Returns true if REF is independent on all other memory
references in LOOP. REF_LOOP is where REF is accessed, SAFELEN is the references in LOOP. */
safelen to apply. */
static bool static bool
ref_indep_loop_p_1 (int safelen, struct loop *loop, im_mem_ref *ref, ref_indep_loop_p_1 (struct loop *loop, im_mem_ref *ref, bool stored_p)
bool stored_p, struct loop *ref_loop)
{ {
stored_p |= (ref->stored && bitmap_bit_p (ref->stored, loop->num)); stored_p |= (ref->stored && bitmap_bit_p (ref->stored, loop->num));
if (loop->safelen > safelen
/* Check that REF is accessed inside LOOP. */
&& (loop == ref_loop || flow_loop_nested_p (loop, ref_loop)))
safelen = loop->safelen;
bool indep_p = true; bool indep_p = true;
bitmap refs_to_check; bitmap refs_to_check;
...@@ -2174,32 +2167,6 @@ ref_indep_loop_p_1 (int safelen, struct loop *loop, im_mem_ref *ref, ...@@ -2174,32 +2167,6 @@ ref_indep_loop_p_1 (int safelen, struct loop *loop, im_mem_ref *ref,
if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID)) if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID))
indep_p = false; indep_p = false;
else if (safelen > 1)
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file,"REF is independent due to safelen %d\n",
safelen);
print_generic_expr (dump_file, ref->mem.ref, TDF_SLIM);
fprintf (dump_file, "\n");
}
/* We need to recurse to properly handle UNANALYZABLE_MEM_ID. */
struct loop *inner = loop->inner;
while (inner)
{
if (!ref_indep_loop_p_1 (safelen, inner, ref, stored_p, ref_loop))
{
indep_p = false;
break;
}
inner = inner->next;
}
/* Avoid caching here as safelen depends on context and refs
are shared between different contexts. */
return indep_p;
}
else else
{ {
if (bitmap_bit_p (&ref->indep_loop, LOOP_DEP_BIT (loop->num, stored_p))) if (bitmap_bit_p (&ref->indep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
...@@ -2210,7 +2177,7 @@ ref_indep_loop_p_1 (int safelen, struct loop *loop, im_mem_ref *ref, ...@@ -2210,7 +2177,7 @@ ref_indep_loop_p_1 (int safelen, struct loop *loop, im_mem_ref *ref,
struct loop *inner = loop->inner; struct loop *inner = loop->inner;
while (inner) while (inner)
{ {
if (!ref_indep_loop_p_1 (safelen, inner, ref, stored_p, ref_loop)) if (!ref_indep_loop_p_1 (inner, ref, stored_p))
{ {
indep_p = false; indep_p = false;
break; break;
...@@ -2264,14 +2231,14 @@ ref_indep_loop_p_1 (int safelen, struct loop *loop, im_mem_ref *ref, ...@@ -2264,14 +2231,14 @@ ref_indep_loop_p_1 (int safelen, struct loop *loop, im_mem_ref *ref,
} }
/* Returns true if REF is independent on all other memory references in /* Returns true if REF is independent on all other memory references in
LOOP. REF_LOOP is the loop where REF is accessed. */ LOOP. */
static bool static bool
ref_indep_loop_p (struct loop *loop, im_mem_ref *ref, struct loop *ref_loop) ref_indep_loop_p (struct loop *loop, im_mem_ref *ref)
{ {
gcc_checking_assert (MEM_ANALYZABLE (ref)); gcc_checking_assert (MEM_ANALYZABLE (ref));
return ref_indep_loop_p_1 (0, loop, ref, false, ref_loop); return ref_indep_loop_p_1 (loop, ref, false);
} }
/* Returns true if we can perform store motion of REF from LOOP. */ /* Returns true if we can perform store motion of REF from LOOP. */
...@@ -2307,7 +2274,7 @@ can_sm_ref_p (struct loop *loop, im_mem_ref *ref) ...@@ -2307,7 +2274,7 @@ can_sm_ref_p (struct loop *loop, im_mem_ref *ref)
/* And it must be independent on all other memory references /* And it must be independent on all other memory references
in LOOP. */ in LOOP. */
if (!ref_indep_loop_p (loop, ref, loop)) if (!ref_indep_loop_p (loop, ref))
return false; return false;
return true; return true;
......
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