Bug 33673 - [4.3 Regression] ICE in verify_flow_info, missing barrier, when multiple tree opts disabled
Summary: [4.3 Regression] ICE in verify_flow_info, missing barrier, when multiple tree...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.3.0
: P1 normal
Target Milestone: 4.3.0
Assignee: Jakub Jelinek
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: ice-on-valid-code
Depends on:
Blocks:
 
Reported: 2007-10-06 01:21 UTC by Janis Johnson
Modified: 2007-11-01 08:49 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2007-10-31 10:29:42


Attachments
minimized testcase (294 bytes, text/plain)
2007-10-06 01:23 UTC, Janis Johnson
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Janis Johnson 2007-10-06 01:21:07 UTC
Benchmark 176.gcc from SPEC CPU2000 fails with an ICE in verify_flow_info and a message about a missing barrier when compiled on powerpc-linux with "-Os -fno-forward-propagate -fno-guess-branch-probability -fno-move-loop-invariants -fno-tree-dominator-opts -fno-tree-loop-optimize".  It's an odd set of options but the failure probably demonstrates some sort of dependency between the   optimizations.  All of the options are documented, none as experimental.

A minimized test case (I'll attach it) fails with these options for a cross cc1   for any of power*-*-*, s390*-linux, cris-elf, frv-elf, or m32c-elf with the output:

  bug11.c: In function ‘find_reg’:
  bug11.c:32: error: missing barrier after block 4
  bug11.c:32: internal compiler error: verify_flow_info failed
  Please submit a full bug report,
  with preprocessed source if appropriate.
  See <http://gcc.gnu.org/bugs.html> for instructions.

The failure starts with this patch:

    http://gcc.gnu.org/viewcvs?view=rev&rev=124786

    r124786 | rakdver | 2007-05-17 08:10:24 +0000 (Thu, 17 May 2007)
Comment 1 Janis Johnson 2007-10-06 01:23:10 UTC
Created attachment 14309 [details]
minimized testcase
Comment 2 Andrew Pinski 2007-10-06 01:30:54 UTC
Even though the patch was for Tree level, the patch exposed a latent bug in the rtl optimizers (missing barrier after can only happen on the rtl level).
Comment 3 Steven Bosscher 2007-10-06 12:36:44 UTC
10 to 1 this is a problem with coming out of cfglayout mode somewhere.
Comment 4 Jakub Jelinek 2007-10-11 16:27:08 UTC
If cprop_jump changes a conditional jump into unconditional, then it forgets
to add a BARRIER after it.  When not in cfglayout mode that's enough, but
in cfglayout mode it is uglier, though I haven't found a cfg hook which would
do what cprop_jump needs.


--- gcc/gcse.c.jj  2007-10-03 21:33:54.000000000 +0200
+++ gcc/gcse.c      2007-10-11 18:13:45.000000000 +0200
@@ -2853,6 +2853,14 @@ cprop_jump (basic_block bb, rtx setcc, r
       /* Remove REG_EQUAL note after simplification.  */
       if (note_src)
        remove_note (jump, note);
+
+      if (any_uncondjump_p (jump)
+         || (returnjump_p (jump) && !any_condjump_p (jump)))
+       {
+         rtx barrier = emit_barrier_after (jump);
+         if (current_ir_type () == IR_RTL_CFGLAYOUT)
+           bb->il.rtl->footer = unlink_insn_chain (barrier, barrier);
+       }
      }
 
 #ifdef HAVE_cc0

is ugly, but fixes this bug.
Comment 5 Steven Bosscher 2007-10-11 18:52:54 UTC
What do the edge flags look like after cprop changes the jump?  EDGE_FALLTHRU should be set.

Also, the unconditional JUMP_INSN should be removed.  Unconditional jumps are removed when going into cfglayout mode, and when a conditional jump is turned into  an unconditional jump, the whole JUMP_INSN can be removed.
Comment 6 Steven Bosscher 2007-10-11 18:53:21 UTC
The patch from comment #4 is wrong and should not be applied.
Comment 7 Jakub Jelinek 2007-10-11 19:29:38 UTC
It calls purge_dead_edges after changing the jump, so if it changed that into
an unconditional jump, purge_dead_edges will purge the EDGE_FALLTHRU
edge and keep the other edge.

If cfglayout mode is supposed to avoid unconditional jumps, then that needs to
be changed, so that the old non-fallthrough edge becomes EDGE_FALLTHRU and old
EDGE_FALLTHRU is removed.  I believe in other cases cprop_jump could e.g. only
simplify an conditional jump (then what it does ATM is probably ok) or could
e.g. change a conditional returnjump_p into unconditional one (how are those
supposed to be expressed in cfglayout mode)?
Anyway, it seems both pass_gcse and pass_bypass are both always in cfglayout mode, so no conditionalization on current_ir_type () is needed.
Comment 8 Steven Bosscher 2007-10-11 19:55:35 UTC
Updating the CFG as suggested in comment #7 is the appropriate thing to do.

How about using delete_insn_and_edges() on the jump insn, and setting EDGE_FALLTHRU on the remaining edge?
Comment 9 Jakub Jelinek 2007-11-01 08:48:16 UTC
Subject: Bug 33673

Author: jakub
Date: Thu Nov  1 08:48:05 2007
New Revision: 129819

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=129819
Log:
	PR rtl-optimization/33673
	* gcse.c (cprop_jump): If a conditional jump has been optimized
	into unconditional jump, make the remaining normal edge fallthru
	and delete the jump insn.

	* gcc.dg/pr33673.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr33673.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/gcse.c
    trunk/gcc/testsuite/ChangeLog

Comment 10 Jakub Jelinek 2007-11-01 08:49:37 UTC
Fixed.