tree-optimization/97559 - fix sinking in irreducible regions

This fixes sinking of loads when irreducible regions are involved
and the heuristics to find stores on the path along the sink
breaks down since that uses dominator queries.

2020-12-08  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/97559
	* tree-ssa-sink.c (statement_sink_location): Never ignore
	PHIs on sink paths in irreducible regions.

	* gcc.dg/torture/pr97559-1.c: New testcase.
	* gcc.dg/torture/pr97559-2.c: Likewise.
This commit is contained in:
Richard Biener 2020-12-08 09:45:57 +01:00
parent 3a6e3ad38a
commit a294e6368f
3 changed files with 48 additions and 5 deletions

View File

@ -0,0 +1,21 @@
/* { dg-do compile } */
int printf (char *, ...);
int a, b, c, d;
void e () {
int f = a;
if (b) {
L1:
b = 0;
L2:
if (c) {
if (f)
printf("0");
goto L1;
}
}
if (d)
goto L2;
}

View File

@ -0,0 +1,18 @@
/* { dg-do compile } */
int a, b, c, d;
void e() {
int f = b;
if (a) {
L1:
a = 0;
L2:
if (a) {
c = b;
goto L1;
}
}
if (d)
goto L2;
}

View File

@ -390,12 +390,15 @@ statement_sink_location (gimple *stmt, basic_block frombb,
with the use. */
if (gimple_code (use_stmt) == GIMPLE_PHI)
{
/* In case the PHI node post-dominates the current insert location
we can disregard it. But make sure it is not dominating
it as well as can happen in a CFG cycle. */
/* In case the PHI node post-dominates the current insert
location we can disregard it. But make sure it is not
dominating it as well as can happen in a CFG cycle. */
if (commondom != bb
&& !dominated_by_p (CDI_DOMINATORS, commondom, bb)
&& dominated_by_p (CDI_POST_DOMINATORS, commondom, bb))
&& dominated_by_p (CDI_POST_DOMINATORS, commondom, bb)
/* If the blocks are possibly within the same irreducible
cycle the above check breaks down. */
&& !(bb->flags & commondom->flags & BB_IRREDUCIBLE_LOOP))
continue;
bb = EDGE_PRED (bb, PHI_ARG_INDEX_FROM_USE (use_p))->src;
}
@ -407,7 +410,8 @@ statement_sink_location (gimple *stmt, basic_block frombb,
continue;
/* There is no easy way to disregard defs not on the path from
frombb to commondom so just consider them all. */
commondom = nearest_common_dominator (CDI_DOMINATORS, bb, commondom);
commondom = nearest_common_dominator (CDI_DOMINATORS,
bb, commondom);
if (commondom == frombb)
return false;
}