/tmp/gcc41/libexec/gcc/i686-pc-linux-gnu/4.1.0/cc1 -quiet -v icefoo.c -dumpbase icefoo.c -auxbase icefoo -O -version -fgcse -fgcse-sm -o icefoo.s GNU C version 4.1.0 20051007 (experimental) (i686-pc-linux-gnu) compiled by GNU C version 4.1.0 20051007 (experimental). GGC heuristics: --param ggc-min-expand=99 --param ggc-min-heapsize=129306 Compiler executable checksum: a278381769db4d67bad1ec630ceb45dd icefoo.c: In function 'oof': icefoo.c:23: error: unrecognizable insn: (insn 47 15 19 0 (set (reg:SI 61) (ashift:SI (mem/s/j:SI (reg/v/f:SI 59 [ s ]) [0 <variable>.buf+0 S4 A32]) (subreg:QI (reg/v:SI 60 [ n ]) 0))) -1 (nil) (expr_list:REG_DEAD (reg/v:SI 60 [ n ]) (nil))) icefoo.c:23: internal compiler error: in extract_insn, at recog.c:2084 Configured with: ../gcc/configure --prefix=/tmp/gcc41 --enable-languages=c --disable-nls --enable-checking=assert,rtlflag,misc ======================================================== typedef struct A { int buf, left; } A; static void flush(A *s, int n) { s->buf <<= n; while (s->left < 32) { s->buf <<= 8; s->left += 8; } s->buf=0; } void oof(A *s, int n) { s->buf = n; s->left = n; flush(s, n); } ========================================================
Confirmed, 4.0.0 worked.
A regression hunt identified this patch from hubicka@gcc.gnu.org: http://gcc.gnu.org/ml/gcc-cvs/2005-07/msg01082.html
Hmm, maybe this is not a target bug after all but a latent bug in gcse store motion.
From _.c.10.gcse1: STORE_MOTION delete insn in BB 0: (insn 17 15 47 0 (parallel [ (set (mem/s:SI (reg/v/f:SI 59 [ s ]) [3 <variable>.buf+0 S4 A32]) (ashift:SI (mem/s:SI (reg/v/f:SI 59 [ s ]) [3 <variable>.buf+0 S4 A32]) (subreg:QI (reg/v:SI 60 [ n ]) 0))) (clobber (reg:CC 17 flags)) ]) 288 {*ashlsi3_1} (nil) (nil)) STORE MOTION replaced with insn: (insn 47 17 19 0 (set (reg:SI 61) (ashift:SI (mem/s:SI (reg/v/f:SI 59 [ s ]) [3 <variable>.buf+0 S4 A32]) (subreg:QI (reg/v:SI 60 [ n ]) 0))) -1 (nil) (nil)) gcse-sm blindly converted valid insn pattern into unrecognized insn pattern.
(In reply to comment #4) > > gcse-sm blindly converted valid insn pattern into unrecognized insn pattern. The problem is in gcse.c, function replace_store_insn(), line 6294: 6293 mem = smexpr->pattern; 6294 insn = gen_move_insn (reg, SET_SRC (single_set (del))); 6295 insn = emit_insn_after (insn, del); This code does not handle parallels and replaces only destination of an insn pattern. "ashlsi3" pattern, as defined in i386.md also requires operand 0 and operand 1 to match (via ix86_expand_binary_operator ()).
This is IMO middle-end problem, store motion should check if new insn pattern is valid, before old insn is replaced.
I do not consider this to be a regression, really. Store motion was always broken. There are reasons for why it is disabled by default ;-) pinskia, what do you think: Keep this marked as a regression, or not?
Subject: Re: [4.1 Regression] ICE: in extract_insn with -O -fgcse -fgcse-sm On Oct 21, 2005, at 7:13 AM, steven at gcc dot gnu dot org wrote: > pinskia, what do you think: Keep this marked as a regression, or not? I think it should be kept as a regression. Otherwise it will get overlooked before it is time to turn on store motion. -- Pinski
How broken is -fgcse-sm? Is it broken enough that it should not only be disabled by default but also hard-wired off on release branches?
Re. comment #9 GCSE store motion is very broken, and it's really been like that for a long time. And it doesn't really do much, either, when you turn it on. Sadly we have nothing to replace it right now except the loop store motion in tree-ssa-loop-im.c, which doesn't work as well as GCSE store motion due to alias representation issues at the tree level. We're just going to have to fix this one IMHO.
*** Bug 25475 has been marked as a duplicate of this bug. ***
I looked at what is going on here with "GNU C version 4.1.0 20060107 (prerelease) (x86_64-unknown-linux-gnu)" We produce the invalid insn in replace_store_insn, where we have: (gdb) p debug_rtx(del) (insn 19 17 21 0 (parallel [ (set (mem/s:SI (reg/v/f:DI 63 [ s ]) [3 <variable>.buf+0 S4 A32]) (ashift:SI (mem/s:SI (reg/v/f:DI 63 [ s ]) [3 <variable>.buf+0 S4 A32]) (subreg:QI (reg/v:SI 64 [ n ]) 0))) (clobber (reg:CC 17 flags)) ]) 413 {*ashlsi3_1} (nil) (nil)) gen_move_insn is used to produce a move for this: replace_store_insn (reg=0x2aaaaafcc000, del=0x2aaaaafc73c0, bb=0x2aaaaafb9780, smexpr=0xcdae70) at gcse.c:6296 6296 mem = smexpr->pattern; (gdb) p debug_rtx(del) (insn 19 17 21 0 (parallel [ (set (mem/s:SI (reg/v/f:DI 63 [ s ]) [3 <variable>.buf+0 S4 A32]) (ashift:SI (mem/s:SI (reg/v/f:DI 63 [ s ]) [3 <variable>.buf+0 S4 A32]) (subreg:QI (reg/v:SI 64 [ n ]) 0))) (clobber (reg:CC 17 flags)) ]) 413 {*ashlsi3_1} (nil) (nil)) $8 = void (gdb) next 6297 insn = gen_move_insn (reg, SET_SRC (single_set (del))); (gdb) p debug_rtx(mem) (mem/s:SI (reg/v/f:DI 63 [ s ]) [3 <variable>.buf+0 S4 A32]) $9 = void (gdb) next 6298 insn = emit_insn_after (insn, del); (gdb) p debug_rtx(insn) (insn 57 0 0 (set (reg:SI 65) (ashift:SI (mem/s:SI (reg/v/f:DI 63 [ s ]) [3 <variable>.buf+0 S4 A32]) (subreg:QI (reg/v:SI 64 [ n ]) 0))) -1 (nil) (nil)) $10 = void (gdb) p recog_memoized (insn) $11 = -1
Created attachment 10601 [details] proposed fix This is my throw-over-the-wall completely untested proposed fix for PR24257. We end up ICEing when we try to emit an invalid SET insns where the SET_DEST is a REG and the SET_SRC is taken from a store to a MEM. When the SET_SRC of that store can't be assigned to a register, we should not consider the store movable. This happens for example with x86/AMD64 memory read-modify-write instructions, i.e. "MEM <- MEM op x".
Subject: Bug 24257 Author: rguenth Date: Sat Jan 14 11:04:16 2006 New Revision: 109701 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=109701 Log: 2006-01-14 Steven Bosscher <stevenb.gcc@gmail.com> Richard Guenther <rguenther@suse.de> PR rtl-optimization/24257 * gcse.c (find_moveable_store): Only consider a store movable when the SET_SRC of the insn can be assigned to a register. * gcc.dg/torture/pr24257.c: New testcase. Added: trunk/gcc/testsuite/gcc.dg/torture/pr24257.c Modified: trunk/gcc/ChangeLog trunk/gcc/gcse.c trunk/gcc/testsuite/ChangeLog
Fixed on the mainline at least.
Subject: Bug 24257 Author: rguenth Date: Mon Jan 16 09:37:10 2006 New Revision: 109744 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=109744 Log: 2006-01-16 Steven Bosscher <stevenb.gcc@gmail.com> Richard Guenther <rguenther@suse.de> PR rtl-optimization/24257 * gcse.c (find_moveable_store): Only consider a store movable when the SET_SRC of the insn can be assigned to a register. * gcc.dg/torture/pr24257.c: New testcase. Added: branches/gcc-4_1-branch/gcc/testsuite/gcc.dg/torture/pr24257.c Modified: branches/gcc-4_1-branch/gcc/ChangeLog branches/gcc-4_1-branch/gcc/gcse.c branches/gcc-4_1-branch/gcc/testsuite/ChangeLog
Fixed.