Bug 24257 - [4.1 Regression] ICE: in extract_insn with -O -fgcse -fgcse-sm
Summary: [4.1 Regression] ICE: in extract_insn with -O -fgcse -fgcse-sm
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: 4.1.0
Assignee: Not yet assigned to anyone
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: ice-on-valid-code, patch
: 25475 (view as bug list)
Depends on:
Blocks: 19580
  Show dependency treegraph
 
Reported: 2005-10-07 15:17 UTC by Ferdinand
Modified: 2006-01-16 09:37 UTC (History)
6 users (show)

See Also:
Host:
Target: i686-pc-linux-gnu
Build:
Known to work: 3.4.0 4.0.0
Known to fail: 4.1.0
Last reconfirmed: 2005-10-07 15:21:31


Attachments
proposed fix (484 bytes, patch)
2006-01-09 21:25 UTC, Steven Bosscher
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ferdinand 2005-10-07 15:17:37 UTC
/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);
}

========================================================
Comment 1 Andrew Pinski 2005-10-07 15:21:31 UTC
Confirmed, 4.0.0 worked.
Comment 2 Janis Johnson 2005-10-07 23:01:48 UTC
A regression hunt identified this patch from hubicka@gcc.gnu.org:

  http://gcc.gnu.org/ml/gcc-cvs/2005-07/msg01082.html
Comment 3 Andrew Pinski 2005-10-07 23:03:02 UTC
Hmm, maybe this is not a target bug after all but a latent bug in gcse store motion.
Comment 4 Uroš Bizjak 2005-10-11 06:41:43 UTC
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.
Comment 5 Uroš Bizjak 2005-10-11 08:55:34 UTC
(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 ()).
Comment 6 Uroš Bizjak 2005-10-12 06:49:50 UTC
This is IMO middle-end problem, store motion should check if new insn pattern is valid, before old insn is replaced.
Comment 7 Steven Bosscher 2005-10-21 11:13:26 UTC
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?
Comment 8 Andrew Pinski 2005-10-21 12:48:34 UTC
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

Comment 9 Mark Mitchell 2005-10-31 06:05:31 UTC
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?
Comment 10 Steven Bosscher 2005-11-16 08:52:40 UTC
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.
Comment 11 Andrew Pinski 2005-12-18 02:53:51 UTC
*** Bug 25475 has been marked as a duplicate of this bug. ***
Comment 12 Steven Bosscher 2006-01-08 00:45:25 UTC
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

Comment 13 Steven Bosscher 2006-01-09 21:25:57 UTC
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".
Comment 14 Richard Biener 2006-01-14 11:04:21 UTC
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

Comment 15 Andrew Pinski 2006-01-14 19:27:37 UTC
Fixed on the mainline at least.
Comment 16 Richard Biener 2006-01-16 09:37:16 UTC
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

Comment 17 Richard Biener 2006-01-16 09:37:51 UTC
Fixed.