regehr@home:~/volatile/bugs/tmp351$ current-gcc -v Using built-in specs. COLLECT_GCC=current-gcc COLLECT_LTO_WRAPPER=/mnt/z/z/compiler-install/gcc-r170512-install/libexec/gcc/i686-pc-linux-gnu/4.6.0/lto-wrapper Target: i686-pc-linux-gnu Configured with: ../configure --with-libelf=/usr/local --enable-lto --prefix=/mnt/z/z/compiler-install/gcc-r170512-install --program-prefix=r170512- --enable-languages=c,c++ Thread model: posix gcc version 4.6.0 20110226 (experimental) (GCC) regehr@home:~/volatile/bugs/tmp351$ current-gcc -O -funroll-loops small.c -o small small.c: In function ‘main’: small.c:53:1: internal compiler error: in get_loop_body, at cfgloop.c:831 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions. regehr@home:~/volatile/bugs/tmp351$ cat small.c static unsigned foo (unsigned ui1, unsigned ui2) { return ui1 - ui2; } static unsigned g_5[3][1][9] = { }; static short g_17; static short *g_80[4] = { &g_17, &g_17, &g_17, &g_17 }; static short **g_79[5] = { &g_80[1], &g_80[1], &g_80[1], &g_80[1], &g_80[1] }; static int g_132; static short ***volatile g = &g_79[1]; static unsigned g_566; static void func_1 (void) { lbl_777:*g; for (; g; g += 0) for (; g; g += 1) { for (;;) { } } lbl_802:if (g_566) goto lbl_777; for (g_132 = 0; g_132 >= 0; g_132 = foo (g_132, 1)) { if (g_5[+3][+1][+9] || **g) { for (; g; g += 1) { } } else goto lbl_802; } } int main (int argc, char *argv[]) { func_1 (); }
Confirmed. The ICE happens during RTL complete loop peeling.
ICE starts with http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=145357
Somewhat simplified testcase (still for -O -funroll-loops): extern unsigned int a, b, c; extern int d; static int foo (void) { lab: if (b) for (d = 0; d >= 0; d--) if (a || c) for (; c; c++) ; else goto lab; } int main () { foo (); return 0; }
Created attachment 23508 [details] proposed fix When the non-exit path is removed during the complete peeling of the loop, we may need to move some basic blocks up the loop hierarchy (this happens when this removal destroys the path from the bb to the latch of the considered superloop). We achieve this by iteratively moving blocks to the common superloop of their successors; when a block is moved up the hierarchy, we add its predecessors to the queue to process. However, when the predecessor of bb already belongs to a loop higher in the hierarchy, we do not put it to the queue (since the change at bb obviously cannot affect the placement of the predecessor). This gets slightly more complicated by the need to handle subloops; in the described heuristics, we were mistakenly comparing the position of the predecessor with the subloop, instead of with the loop to that the subloop was moved.
Thanks, this patch seems to work (I've bootstrapped/regtested it on x86_64-linux and i686-linux together with the #c3 testcase with /* PR rtl-optimization/47899 */ /* { dg-do compile } */ /* { dg-options "-O -funroll-loops" } */ under gcc/testsuite/gcc.dg/pr47899.c, no regressions).
(In reply to comment #5) > Thanks, this patch seems to work (I've bootstrapped/regtested it on > x86_64-linux and i686-linux together with the #c3 testcase with > /* PR rtl-optimization/47899 */ > /* { dg-do compile } */ > /* { dg-options "-O -funroll-loops" } */ > under gcc/testsuite/gcc.dg/pr47899.c, no regressions). Jakub, are you going to commit the patch (you can consider it approved)? I can do it, of course, but since you already finished the testing...
(In reply to comment #6) > (In reply to comment #5) > > Thanks, this patch seems to work (I've bootstrapped/regtested it on > > x86_64-linux and i686-linux together with the #c3 testcase with > > /* PR rtl-optimization/47899 */ > > /* { dg-do compile } */ > > /* { dg-options "-O -funroll-loops" } */ > > under gcc/testsuite/gcc.dg/pr47899.c, no regressions). > > Jakub, are you going to commit the patch (you can consider it approved)? I can > do it, of course, but since you already finished the testing... I can do so, just not sure how exactly would you prefer to describe your changes in ChangeLog.
Author: jakub Date: Sat Mar 5 14:28:14 2011 New Revision: 170699 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=170699 Log: PR rtl-optimization/47899 * cfgloopmanip.c (fix_bb_placements): Fix first argument to flow_loop_nested_p when moving the loop upward. * gcc.dg/pr47899.c: New test. Added: trunk/gcc/testsuite/gcc.dg/pr47899.c Modified: trunk/gcc/ChangeLog trunk/gcc/cfgloopmanip.c trunk/gcc/testsuite/ChangeLog
Fixed on the trunk so far.
The testcase still ICEs the same way with custom flags: (r170934, x86_64-linux) $ gcc -O -funroll-loops -fthread-jumps -fno-tree-ch gcc.dg/pr47899.c gcc.dg/pr47899.c: In function 'main': gcc.dg/pr47899.c:26:1: internal compiler error: in get_loop_body, at cfgloop.c:831 Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions.
Confirmed, but can you track this in a new bug?
Thank you for reply. I opened PR48133 for the testcase from comment #10.
Author: rguenth Date: Mon Apr 18 14:02:22 2011 New Revision: 172647 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172647 Log: 2011-04-18 Richard Guenther <rguenther@suse.de> Backported from 4.6 branch 2011-03-11 Jakub Jelinek <jakub@redhat.com> PR c++/48035 * init.c (build_zero_init_1): Extracted from build_zero_init. Add FIELD_SIZE argument, if non-NULL and field bit_position as not smaller than that, don't add that field's initializer. Pass DECL_SIZE as last argument to build_zero_init_1 for DECL_FIELD_IS_BASE fields. (build_zero_init): Use build_zero_init_1. * g++.dg/inherit/virtual8.C: New test. 2011-03-05 Zdenek Dvorak <ook@ucw.cz> PR rtl-optimization/47899 * cfgloopmanip.c (fix_bb_placements): Fix first argument to flow_loop_nested_p when moving the loop upward. * gcc.dg/pr47899.c: New test. 2011-03-15 Richard Guenther <rguenther@suse.de> PR middle-end/48031 * fold-const.c (fold_indirect_ref_1): Do not create new variable-sized or variable-indexed array accesses when in gimple form. Modified: branches/gcc-4_5-branch/gcc/ChangeLog branches/gcc-4_5-branch/gcc/cfgloopmanip.c branches/gcc-4_5-branch/gcc/cp/ChangeLog branches/gcc-4_5-branch/gcc/cp/init.c branches/gcc-4_5-branch/gcc/fold-const.c branches/gcc-4_5-branch/gcc/testsuite/ChangeLog
Fixed.
Author: rguenth Date: Mon Apr 18 14:37:08 2011 New Revision: 172652 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=172652 Log: 2011-04-18 Richard Guenther <rguenther@suse.de> Backported from 4.6 branch 2011-03-11 Jakub Jelinek <jakub@redhat.com> PR c++/48035 * init.c (build_zero_init_1): Extracted from build_zero_init. Add FIELD_SIZE argument, if non-NULL and field bit_position as not smaller than that, don't add that field's initializer. Pass DECL_SIZE as last argument to build_zero_init_1 for DECL_FIELD_IS_BASE fields. (build_zero_init): Use build_zero_init_1. * g++.dg/inherit/virtual8.C: New test. 2011-03-05 Zdenek Dvorak <ook@ucw.cz> PR rtl-optimization/47899 * cfgloopmanip.c (fix_bb_placements): Fix first argument to flow_loop_nested_p when moving the loop upward. * gcc.dg/pr47899.c: New test. 2011-03-15 Richard Guenther <rguenther@suse.de> PR middle-end/48031 * fold-const.c (fold_indirect_ref_1): Do not create new variable-sized or variable-indexed array accesses when in gimple form. Added: branches/gcc-4_5-branch/gcc/testsuite/g++.dg/inherit/virtual8.C branches/gcc-4_5-branch/gcc/testsuite/gcc.dg/pr47899.c