gcc-7.0.0-alpha20161127 snapshot ICEs when compiling the following reduced snippet for 32-bit BE powerpc w/ -Os: int qs; void ms (int g1) { int cy; int *fr = &cy; for (;;) { *fr = 1; fr = &g1; while (qs != 0) { if (qs | cy) qs = g1 / 0; ++qs; } cy = 1; while (cy != 0) cy = 2; } } % powerpc-e300c3-linux-gnu-gcc-7.0.0-alpha20161127 -Os -w -c mfzov3v7.c mfzov3v7.c: In function 'ms': mfzov3v7.c:25:1: error: in basic block 3: } ^ mfzov3v7.c:25:1: error: flow control insn inside a basic block (insn 58 19 25 3 (trap_if (const_int 1 [0x1]) (const_int 0 [0])) 823 {trap} (nil)) mfzov3v7.c:25:1: internal compiler error: in rtl_verify_bb_insns, at cfgrtl.c:2656 0x2edfb398605 _fatal_insn(char const*, rtx_def const*, char const*, int, char const*) /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-7.0.0_alpha20161127/work/gcc-7-20161127/gcc/rtl-error.c:108 0x2edfaf5fe87 rtl_verify_bb_insns /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-7.0.0_alpha20161127/work/gcc-7-20161127/gcc/cfgrtl.c:2656 0x2edfaf5fe87 rtl_verify_flow_info_1 /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-7.0.0_alpha20161127/work/gcc-7-20161127/gcc/cfgrtl.c:2742 0x2edfaf4c08d verify_flow_info() /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-7.0.0_alpha20161127/work/gcc-7-20161127/gcc/cfghooks.c:258 0x2edfb322eb1 execute_function_todo /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-7.0.0_alpha20161127/work/gcc-7-20161127/gcc/passes.c:1977 0x2edfb323cfb execute_todo /var/tmp/portage/cross-powerpc-e300c3-linux-gnu/gcc-7.0.0_alpha20161127/work/gcc-7-20161127/gcc/passes.c:2015 Applying r242947 and (or) r243028 doesn't fix it.
This appears to happen in cprop. Would anyone like to test this on ppc? Index: cprop.c =================================================================== --- cprop.c (revision 242958) +++ cprop.c (working copy) @@ -1047,6 +1047,10 @@ int changed = 0, changed_this_round; rtx note; + /* We can't convert these to unconditional traps because it would invalidate the CFG. */ + if (GET_CODE (PATTERN (insn)) == TRAP_IF) + return 0; + do { changed_this_round = 0;
I have tested something similar, and it does work, but it prevents any optimisation by cprop of any trap_if, also if it would not turn into an unconditional trap. This is pretty bad :-(
Not sure it's that bad really. An unconditional trap is pretty much by definition not performance-critical. Then again, there's a possible alternate fix, which I'll attach.
Created attachment 40269 [details] Candidate patch
(In reply to Bernd Schmidt from comment #3) > Not sure it's that bad really. An unconditional trap is pretty much by > definition not performance-critical. Sure, but this was prohibiting propagating anything into a *conditional* trap instruction? Or do I read that wrong.
(In reply to Bernd Schmidt from comment #4) > Created attachment 40269 [details] > Candidate patch It fixes this particular issue. I didn't run regtest, though. Meanwhile, I have four additional snippets w/ the same ICE but w/ different backtrace. I'm going to file them as separate PRs tomorrow.
(In reply to Bernd Schmidt from comment #4) > Created attachment 40269 [details] > Candidate patch That looks great :-)
... and works fine, too! ms: stwu 1,-32(1) lis 9,qs@ha lwz 9,qs@l(9) twnei 9,0 .L6: b .L6 Nice :-)
I can't read that assembly language, but I'll take your word for it. I'm testing the patch on x86.
AFAICT, the patch was ACKed by Segher on December 15th (https://gcc.gnu.org/ml/gcc-patches/2016-12/msg01337.html). Is there something that still prevents it from being committed?
It is ready to be committed AFAIK; same for the related PR78727.
Thus fixed.
(In reply to Richard Biener from comment #12) > Thus fixed. The patch was posted to the mailing list[1] but never committed. [1] https://gcc.gnu.org/ml/gcc-patches/2016-12/msg01282.html
Bernd is on PTO right now. I'm going to try and pick up state on this and 78727.
Author: law Date: Sat Jan 14 16:52:18 2017 New Revision: 244467 URL: https://gcc.gnu.org/viewcvs?rev=244467&root=gcc&view=rev Log: PR rtl-optimization/78626 PR rtl-optimization/78727 * cprop.c (one_cprop_pass): Collect unconditional traps in the middle of a block, and split such blocks after everything else is finished. PR rtl-optimization/78626 PR rtl-optimization/78727 * gcc.dg/torture/pr78626.c: New test. * gcc.dg/torture/pr78727.c: New test. Added: trunk/gcc/testsuite/gcc.dg/torture/pr78626.c trunk/gcc/testsuite/gcc.dg/torture/pr78727.c Modified: trunk/gcc/ChangeLog trunk/gcc/cprop.c trunk/gcc/testsuite/ChangeLog
Fixed by Bernd's patch I installed on the trunk.