Bug 81090 - [8 Regression] [graphite] ICE in loop_preheader_edge
Summary: [8 Regression] [graphite] ICE in loop_preheader_edge
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: 8.0
Assignee: Richard Biener
URL:
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2017-06-14 09:01 UTC by Arseny Solokha
Modified: 2017-06-19 07:35 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-06-14 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arseny Solokha 2017-06-14 09:01:52 UTC
gcc-8.0.0-alpha20170611 snapshot ICEs when compiling the following snippet w/ -O2 (-O3, -Ofast) -floop-nest-optimize:

int x3, za;
int hg[1];

void
yw (int dq)
{
  const int r7 = 2;

  while (dq < 1)
    {
      for (x3 = 0; x3 < r7; ++x3)
        for (za = 0; za < r7; ++za)
          hg[1] = 0;
      ++dq;
    }

  x3 = 0;
  while (x3 < r7)
    {
      ++x3;
      if (x3 == 0)
        break;
    }
}

% gcc-8.0.0-alpha20170611 -O2 -floop-nest-optimize -c yrfe1sre.c
during GIMPLE pass: graphite
yrfe1sre.c: In function 'yw':
yrfe1sre.c:5:1: internal compiler error: Segmentation fault
 yw (int dq)
 ^~

(gdb) where
#0  0x000000000087c4e8 in loop_preheader_edge(loop const*) ()
#1  0x0000000000d44621 in analyze_scalar_evolution(loop*, tree_node*) ()
#2  0x0000000000d47d7b in analyze_scalar_evolution_in_loop(loop*, loop*, tree_node*, bool*) ()
#3  0x0000000000d47ed2 in simple_iv_with_niters(loop*, loop*, tree_node*, affine_iv*, tree_node**, bool) ()
#4  0x0000000000bad67f in is_comparison_with_loop_invariant_p(gcond*, loop*, tree_node**, tree_code*, tree_node**, tree_node**) ()
#5  0x0000000000bb4139 in predict_loops() ()
#6  0x0000000000bb6023 in tree_estimate_probability(bool) ()
#7  0x0000000001375172 in graphite_transform_loops() ()
#8  0x0000000001375701 in (anonymous namespace)::pass_graphite_transforms::execute(function*) ()
#9  0x0000000000b9b629 in execute_one_pass(opt_pass*) ()
#10 0x0000000000b9be55 in execute_pass_list_1(opt_pass*) ()
#11 0x0000000000b9be67 in execute_pass_list_1(opt_pass*) ()
#12 0x0000000000b9be67 in execute_pass_list_1(opt_pass*) ()
#13 0x0000000000b9be67 in execute_pass_list_1(opt_pass*) ()
#14 0x0000000000b9be99 in execute_pass_list(function*, opt_pass*) ()
#15 0x00000000008a4720 in cgraph_node::expand() ()
#16 0x00000000008a5bd1 in symbol_table::compile() [clone .part.51] ()
#17 0x00000000008a7dc7 in symbol_table::finalize_compilation_unit() ()
#18 0x0000000000c71655 in compile_file() ()
#19 0x000000000072f69a in toplev::main(int, char**) ()
#20 0x00000000007315bb in main ()
Comment 1 Richard Biener 2017-06-14 09:34:52 UTC
#6  0x0000000000de6e8e in is_comparison_with_loop_invariant_p (
    stmt=0x7ffff69d7460, loop=0x7ffff69d8210, loop_invariant=0x7fffffffd800, 
    compare_code=0x7fffffffd814, loop_step=0x7fffffffd808, 
    loop_iv_base=0x7fffffffd7f8)
    at /space/rguenther/src/svn/early-lto-debug/gcc/predict.c:1397
1397      if (!simple_iv (loop, loop_containing_stmt (stmt), op0, &iv0, true))
(gdb) p stmt
$1 = (gcond *) 0x7ffff69d7460
(gdb) p debug_gimple_stmt (stmt)
if (0 != 0)
$2 = void
(gdb) p gimple_bb (stmt)
$3 = <basic_block 0x0>

hum.  Ok, so it looks like loop->bounds got invalid and we have stale nb_iter->stmt pointers.

Caused by moving of IVCANON pass as well.  Testcase works with -fdisable-tree-ivcanon.

But sth is fishy, I suppose ivcanon fails to invalidate recorded niters.
Honza?  Like the following which fixes the ICE:

Index: gcc/tree-ssa-loop-ivcanon.c
===================================================================
--- gcc/tree-ssa-loop-ivcanon.c (revision 249185)
+++ gcc/tree-ssa-loop-ivcanon.c (working copy)
@@ -1216,11 +1216,13 @@ canonicalize_induction_variables (void)
   estimate_numbers_of_iterations ();
 
   FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
-    {
-      changed |= canonicalize_loop_induction_variables (loop,
-                                                       true, UL_SINGLE_ITER,
-                                                       true);
-    }
+    if (canonicalize_loop_induction_variables (loop,
+                                              true, UL_SINGLE_ITER,
+                                              true))
+      {
+       changed = true;
+       free_numbers_of_iterations_estimates_loop (loop);
+      }
   gcc_assert (!need_ssa_update_p (cfun));
 
   unloop_loops (loop_closed_ssa_invalidated, &irred_invalidated);

but I can't see where ivcanon builds a new exit condition stmt, it just
updates the existing one...
Comment 2 Richard Biener 2017-06-14 09:47:08 UTC
Ah, it is CFG cleanup removing a loop exit edge but not updating loop info it seems.  So when remove_edge calls rescan_loop_exit it doesn't adjust bounds.
So either we are not supposed to keep those "live" at all or we somehow
need to manage them as well during CFG cleanup and other loop opts...
Comment 3 Richard Biener 2017-06-14 12:48:59 UTC
Mine.
Comment 4 Richard Biener 2017-06-16 09:28:56 UTC
So amending scev_reset to do free_numbers_of_iterations_estimates causes issues with complete peeling which uses gimple_duplicate_loop_to_header_edge which
calls scev_reset (peeling invalidates cached CHRECs for the loop header PHIs
and derived SSA names) but then using ->bounds to mark paths in the loop copies
as gcc_unreachable () (remove_exits_and_undefined_stmts).  That looks fishy
somewhat, also because we defer this operation when processing adjacent loops
which will then eventually clear estimates before the 2nd adjacent loop is processed (that might still work in the end if we only reset estimates for
a single loop at a time or estimates are computed on-demand again when using
the correct API).  Even more ugly so we ggc_free bounds ...
Comment 5 Richard Biener 2017-06-16 12:19:56 UTC
Author: rguenth
Date: Fri Jun 16 12:19:24 2017
New Revision: 249249

URL: https://gcc.gnu.org/viewcvs?rev=249249&root=gcc&view=rev
Log:
2017-06-16  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/81090
	* passes.def (pass_record_bounds): Remove.
	* tree-pass.h (make_pass_record_bounds): Likewise.
	* tree-ssa-loop.c (pass_data_record_bounds, pass_record_bounds,
	make_pass_record_bounds): Likewise.
	* tree-ssa-loop-ivcanon.c (canonicalize_induction_variables): Do
	not free niter estimates at the beginning but at the end.
	* tree-scalar-evolution.c (scev_finalize): Free niter estimates.

	* gcc.dg/graphite/pr81090.c: New testcase.

Added:
    trunk/gcc/testsuite/gcc.dg/graphite/pr81090.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/passes.def
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/tree-pass.h
    trunk/gcc/tree-scalar-evolution.c
    trunk/gcc/tree-ssa-loop-ivcanon.c
    trunk/gcc/tree-ssa-loop.c
Comment 6 Richard Biener 2017-06-19 07:35:13 UTC
Fixed.