diff options
author | Richard Biener <rguenther@suse.de> | 2025-09-03 10:41:17 +0200 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2025-09-03 14:33:36 +0200 |
commit | df64893e7082d7fae5d6863fd02371b37c78557f (patch) | |
tree | 17efa550baadd114e4b164c6cef68a69fc1251d1 /gcc/testsuite | |
parent | c8a24f60b6874fca4fb3adb153f8d5f1dd72b951 (diff) | |
download | gcc-df64893e7082d7fae5d6863fd02371b37c78557f.zip gcc-df64893e7082d7fae5d6863fd02371b37c78557f.tar.gz gcc-df64893e7082d7fae5d6863fd02371b37c78557f.tar.bz2 |
tree-optimization/121756 - handle irreducible regions when sinking
The sinking code currently does not heuristically avoid placing
code into an irreducible region in the same way it avoids placing
into a deeper loop nest. Critically for the PR we may not insert
a VDEF into a irreducible region that does not contain a virtual
definition. The following adds the missing heuristic and also
a stop-gap for the VDEF issue - since we cannot determine
validity inside an irreducible region we have to reject any
VDEF movement with destination inside such region, even when
it originates there. In particular irreducible sub-cycles are
not tracked separately and can cause issues.
I chose to not complicate the already partly incomplete assert
but prune it down to essentials.
PR tree-optimization/121756
* tree-ssa-sink.cc (select_best_block): Avoid irreducible
regions in otherwise same loop depth.
(statement_sink_location): When sinking a VDEF, never place
that into an irreducible region.
* gcc.dg/torture/pr121756.c: New testcase.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr121756.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr121756.c b/gcc/testsuite/gcc.dg/torture/pr121756.c new file mode 100644 index 0000000..37c5c50 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr121756.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ + +int a, b, *c = &b; +static void g(int i) { + int d = 0, e, f[] = {a}, j = a; + e = b; + if (e - i) + return; + a = 0; +h: + if (e) { + e = j; + if (f[3]) + goto k; + goto h; + } + while (1) { d = -1; + while (1) { + if (d - 1 - j < 0) + return; + k: + if (f[1]) + break; + } + } +} +int main() { + g(1); + return 0; +} |