aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2021-10-20 18:52:45 +0200
committerAldy Hernandez <aldyh@redhat.com>2021-10-21 10:10:45 +0200
commit70e72c3a11315fb6a228b7f58d027c2e1fbb9940 (patch)
tree2c069ab6626af6f4632614411e9112117e95c869 /gcc
parentd438dd2523a35e073eed04d146f1e73e2514d93d (diff)
downloadgcc-70e72c3a11315fb6a228b7f58d027c2e1fbb9940.zip
gcc-70e72c3a11315fb6a228b7f58d027c2e1fbb9940.tar.gz
gcc-70e72c3a11315fb6a228b7f58d027c2e1fbb9940.tar.bz2
Avoid threading circular paths.
The backward threader keeps a hash of visited blocks to avoid crossing the same block twice. Interestingly, we haven't been checking it for the final block out of the path. This may be inherited from the old code, as it was simple enough that it didn't matter. With the upcoming changes enabling the fully resolving threader, it gets tripped often enough to cause wrong code to be generated. Tested on x86-64 Linux. gcc/ChangeLog: * tree-ssa-threadbackward.c (back_threader::maybe_register_path): Avoid threading circular paths.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/tree-ssa-threadbackward.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c
index d94e3b9..38913b0 100644
--- a/gcc/tree-ssa-threadbackward.c
+++ b/gcc/tree-ssa-threadbackward.c
@@ -140,6 +140,10 @@ back_threader::maybe_register_path ()
if (taken_edge && taken_edge != UNREACHABLE_EDGE)
{
+ // Avoid circular paths.
+ if (m_visited_bbs.contains (taken_edge->dest))
+ return UNREACHABLE_EDGE;
+
bool irreducible = false;
bool profitable
= m_profit.profitable_path_p (m_path, m_name, taken_edge, &irreducible);