This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: ARM platform: internal error - unrecognizable insn


> Using the following compiler on a NetWinder:
> 
> Reading specs from
> /usr/lib/gcc-lib/armv4l-unknown-linux-gnu/2.95.1/specs
> gcc version 2.95.1 19990816 (release)
> 
> I get the following error:
> 
> gcc -O2 -fsigned-char -fomit-frame-pointer -fpic  -I. -I.
> -I/usr/include/apache                     -c functions/dns.c -o
> functions/dns.o
> functions/dns.c: In function `php3_getmxrr':
> functions/dns.c:321: internal error--unrecognizable insn:
> (insn 781 780 286 (set (reg:SI 0 r0)
>         (umin:SI (reg/v:SI 0 r0)
>             (const_int 8192 [0x2000]))) -1 (nil)
>     (nil))
> make: *** [functions/dns.o] Error 1
> 
> This is an -O2 optimization bug.  Lowering the optimization level to -O1
> allows this file to build.  Unfortunately I still don't understand
> enough RTL to debug this one.  Sorry.  The .i file is attached.
> 
> Scott
> 
> 


This is truly horrible.  Before reload we have

(insn 774 256 257 (set (reg:SI 185)
        (reg:SI 77)) 176 {*movsi_insn} (insn_list/j/c 240 (nil))
    (expr_list:REG_EQUIV (plus:SI (reg:SI 25 sfp)
            (const_int -8256 [0xffffdfc0]))
        (nil)))
...

(insn 286 689 690 (parallel[
            (set (reg/v:SI 46)
                (plus:SI (umin:SI (reg/v:SI 47)
                        (const_int 8192 [0x2000]))
                    (reg:SI 185)))
            (clobber (reg:CC 24 cc))
        ] ) 108 {*minmax_arithsi} (nil)
    (expr_list:REG_DEAD (reg/v:SI 47)
        (expr_list:REG_UNUSED (reg:CC 24 cc)
            (nil))))

global alloc fails to allocate a register to pseudo 185 (or it gets 
spilled, it doesn't really matter), so reload eliminates it entirely, 
substituting the equivalent value for it.  The intermediate expression is 
effectively:

(parallel[
	(plus:SI (umin:SI (reg:SI 0 r0) (const_int 8192))
		 (plus:SI (reg:SI 13 sp) (const_int 92)))
	(clobber (reg:CC 24 cc)) ])

But this is immediately canonicalized to 

(insn 286 689 690 (parallel[ 
            (set (reg/v:SI 8 r8)
                (plus:SI (plus:SI (umin:SI (reg/v:SI 0 r0)
                            (const_int 8192 [0x2000]))
                        (reg:SI 13 sp))
                    (const_int 92 [0x5c])))
            (clobber (reg:CC 24 cc))
        ] ) 108 {*minmax_arithsi} (nil)
    (expr_list:REG_DEAD (reg/v:SI 0 r0)
        (expr_list:REG_UNUSED (reg:CC 24 cc)
            (nil))))

which no-longer matches any pattern in the MD file.  This then causes 
reload to try to push further reloads, but it is doing this based on the 
insn that we used to have, not the canonicalized version, so it tries to 
split the (umin()()) subexpression into a separate insn.  The resulting 
insns then fail to match because the clobber of the condition codes did 
not go with it.

Note that if it weren't for the canonicalization, reload would have simply 
pushed a new reload for the (plus (reg sp) (const_int 92)) sub-expression 
and it would have all worked fine.

The carnage here is just a nasty case of what we normally prevent by the 
additional matching rules on the insn, which normally prevent an 
expression containing the frame pointer (or arg pointer) from matching; 
unfortunately, these won't work in this instance, since the offending 
register isn't the frame pointer, nor is there an easy way to tell that it 
is equivalent to an expression based on it.

It seems that the only solution is to add an additional pattern to the MD 
for this case that matches the carnage generated by reload; there are 
already some for matching similar problems with the multiply-add 
instructions.  (Why does it have to do this canonicalization this way?  
Why can't it undo it if it fails to generate a matching insn?)  I fear 
that there are a large number of patterns in the description that could 
*potentially* fail in this way.

All this begs the question: should we have some special splits in the MD 
(define_reload?) that help reload to do the right thing in cases like this?

I'll think about adding a new pattern.

Richard.

PS.  The code doesn't fault with the latest version of the 2.95 branch, 
but I'm fairly certain this is just luck, not that the fundamental problem 
has been solved.

R.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]