diff options
author | Jeff Law <law@redhat.com> | 2016-05-25 16:25:35 -0600 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 2016-05-25 16:25:35 -0600 |
commit | 8af01c66fb6123572bd534d8e912031fcb681a48 (patch) | |
tree | ac833108d5e1e510a99e9d9fdce8a634ecf5b6d4 /gcc/tree-ssa-threadbackward.c | |
parent | f9d6ce734db62ab7ff8ab4826a9313bf417e0a81 (diff) | |
download | gcc-8af01c66fb6123572bd534d8e912031fcb681a48.zip gcc-8af01c66fb6123572bd534d8e912031fcb681a48.tar.gz gcc-8af01c66fb6123572bd534d8e912031fcb681a48.tar.bz2 |
re PR tree-optimization/71272 (internal compiler error: in operator[], through tree-ssa-threadupdate.c:1981)
PR tree-optimization/71272
* tree-ssa-threadbackward.c (convert_and_register_jump_thread_path):
Update comments. Add test for empty path.
PR tree-optimization/71272
* gcc.c-torture/compile/pr71272.c: new test.
From-SVN: r236755
Diffstat (limited to 'gcc/tree-ssa-threadbackward.c')
-rw-r--r-- | gcc/tree-ssa-threadbackward.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c index 4d0fd9c..636b67d 100644 --- a/gcc/tree-ssa-threadbackward.c +++ b/gcc/tree-ssa-threadbackward.c @@ -373,6 +373,10 @@ convert_and_register_jump_thread_path (vec<basic_block, va_gc> *&path, { basic_block bb1 = (*path)[path->length () - j - 1]; basic_block bb2 = (*path)[path->length () - j - 2]; + + /* This can happen when we have an SSA_NAME as a PHI argument and + its initialization block is the head of the PHI argument's + edge. */ if (bb1 == bb2) continue; @@ -382,6 +386,22 @@ convert_and_register_jump_thread_path (vec<basic_block, va_gc> *&path, jump_thread_path->safe_push (x); } + /* As a consequence of the test for duplicate blocks in the path + above, we can get a path with no blocks. This happens if a + conditional can be fully evaluated at compile time using just + defining statements in the same block as the test. + + When we no longer push the block associated with a PHI argument + onto the stack, then this as well as the test in the loop above + can be removed. */ + if (jump_thread_path->length () == 0) + { + jump_thread_path->release (); + delete jump_thread_path; + path->pop (); + return; + } + /* Add the edge taken when the control variable has value ARG. */ jump_thread_edge *x = new jump_thread_edge (taken_edge, EDGE_NO_COPY_SRC_BLOCK); |