diff options
author | Richard Biener <rguenther@suse.de> | 2021-05-12 15:39:52 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2021-05-12 17:01:32 +0200 |
commit | 097fde5e7514e909f2e8472be2e008d0cab2260d (patch) | |
tree | 82047c43a36e8e4b1be56ae54955ea708bbaea17 /gcc | |
parent | d1adbe5c1bd3f3ba098ff112eed9b61515e2dc20 (diff) | |
download | gcc-097fde5e7514e909f2e8472be2e008d0cab2260d.zip gcc-097fde5e7514e909f2e8472be2e008d0cab2260d.tar.gz gcc-097fde5e7514e909f2e8472be2e008d0cab2260d.tar.bz2 |
tree-optimization/100566 - fix another predication issue in VN
This amends the fix for PR100053 where I failed to amend all edge
tests in dominated_by_p_w_unex.
2021-05-12 Richard Biener <rguenther@suse.de>
PR tree-optimization/100566
* tree-ssa-sccvn.c (dominated_by_p_w_unex): Properly handle
allow_back for all edge queries.
* gcc.dg/torture/pr100566.c: New testcase.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr100566.c | 36 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 6 |
2 files changed, 40 insertions, 2 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/pr100566.c b/gcc/testsuite/gcc.dg/torture/pr100566.c new file mode 100644 index 0000000..ed85691 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100566.c @@ -0,0 +1,36 @@ +/* { dg-do run } */ + +volatile int s, c; + +__attribute__((noipa)) void +foo (void) +{ + if (c++ > 1) + __builtin_abort (); +} + +__attribute__((noipa)) int +bar (void) +{ + int i = 0, j = s; + if (j == 0) + goto lab; + for (i = 0; i < j; i++) + { + lab: + foo (); + if (!j) + goto lab; + } + return 0; +} + +int +main () +{ + s = 1; + bar (); + if (c != 1) + __builtin_abort (); + return 0; +} diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index e54a0c9..e876121 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -4529,7 +4529,8 @@ dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back) /* Iterate to the single executable bb2 successor. */ edge succe = NULL; FOR_EACH_EDGE (e, ei, bb2->succs) - if (e->flags & EDGE_EXECUTABLE) + if ((e->flags & EDGE_EXECUTABLE) + || (!allow_back && (e->flags & EDGE_DFS_BACK))) { if (succe) { @@ -4547,7 +4548,8 @@ dominated_by_p_w_unex (basic_block bb1, basic_block bb2, bool allow_back) { FOR_EACH_EDGE (e, ei, succe->dest->preds) if (e != succe - && (e->flags & EDGE_EXECUTABLE)) + && ((e->flags & EDGE_EXECUTABLE) + || (!allow_back && (e->flags & EDGE_DFS_BACK)))) { succe = NULL; break; |