aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-phiopt.cc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2024-12-02 08:35:23 -0800
committerAndrew Pinski <quic_apinski@quicinc.com>2024-12-03 22:09:38 -0800
commitb7c69cc072ef0da36439ebc55c513b48e68391b7 (patch)
tree037c8b1e7463dd9d9c0b2371233dc84cf5fad96a /gcc/tree-ssa-phiopt.cc
parent7a92ba766815c9a6b73593967a26fdfbebfc7e69 (diff)
downloadgcc-b7c69cc072ef0da36439ebc55c513b48e68391b7.zip
gcc-b7c69cc072ef0da36439ebc55c513b48e68391b7.tar.gz
gcc-b7c69cc072ef0da36439ebc55c513b48e68391b7.tar.bz2
phiopt: Reset the number of iterations information of a loop when changing an exit from the loop [PR117243]
After r12-5300-gf98f373dd822b3, phiopt could get the following bb structure: | middle-bb -----| | | | |----| | phi<1, 2> | | cond | | | | | |--------+---| Which was considered 2 loops. The inner loop had esimtate of upper_bound to be 8, due to the original `for (b = 0; b <= 7; b++)`. The outer loop was already an infinite one. So phiopt would come along and change the condition to be unconditionally true, we change the inner loop to being an infinite one but don't reset the estimate on the loop and cleanup cfg comes along and changes it into one loop but also does not reset the estimate of the loop. Then the loop unrolling uses the old estimate and decides to add an unreachable there.o So the fix is when phiopt changes an exit to a loop, reset the estimates, similar to how cleanupcfg does it when merging some basic blocks. Bootstrapped and tested on x86_64-linux-gnu. PR tree-optimization/117243 PR tree-optimization/116749 gcc/ChangeLog: * tree-ssa-phiopt.cc (replace_phi_edge_with_variable): Reset loop estimates if the cond_block was an exit to a loop. gcc/testsuite/ChangeLog: * gcc.dg/torture/pr117243-1.c: New test. * gcc.dg/torture/pr117243-2.c: New test. Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc/tree-ssa-phiopt.cc')
-rw-r--r--gcc/tree-ssa-phiopt.cc11
1 files changed, 11 insertions, 0 deletions
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index 1565180..d7b7c74 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -55,6 +55,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-propagate.h"
#include "tree-ssa-dce.h"
#include "calls.h"
+#include "tree-ssa-loop-niter.h"
/* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */
@@ -152,6 +153,16 @@ replace_phi_edge_with_variable (basic_block cond_block,
else
gcc_unreachable ();
+ /* If we are removing the cond on a loop exit,
+ reset number of iteration information of the loop. */
+ if (loop_exits_from_bb_p (cond_block->loop_father, cond_block))
+ {
+ auto loop = cond_block->loop_father;
+ free_numbers_of_iterations_estimates (loop);
+ loop->any_upper_bound = false;
+ loop->any_likely_upper_bound = false;
+ }
+
if (edge_to_remove && EDGE_COUNT (edge_to_remove->dest->preds) == 1)
{
e->flags |= EDGE_FALLTHRU;