This is the mail archive of the gcc@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]
Other format: [Raw text]

-ffixed-di vs. strlen


If I compile this trivial function
    int foo(const char *s) { return strlen (s); }
with the options -O -ffixed-di on i686-pc-linux-gnu, I get this ICE:

/home/ian/foo1.c: In function `foo':
/home/ian/foo1.c:1: error: unable to find a register to spill in class `DIREG'
/home/ian/foo1.c:1: error: this is the insn:
(insn 15 34 16 0 (parallel [
            (set (reg:SI 2 cx [62])
                (unspec:SI [
                        (mem:BLK (reg/f:SI 1 dx [orig:64 s ] [64]) [0 A8])
                        (reg:QI 0 ax [66])
                        (const_int 1 [0x1])
                        (reg:SI 2 cx [65])
                    ] 20))
            (use (reg:SI 19 dirflag))
            (clobber (reg/f:SI 1 dx [orig:64 s ] [64]))
            (clobber (reg:CC 17 flags))
        ]) 632 {*strlenqi_1} (insn_list 11 (insn_list 12 (insn_list 13 (insn_list 14 (nil)))))
    (expr_list:REG_DEAD (reg:SI 19 dirflag)
        (expr_list:REG_DEAD (reg:SI 2 cx [65])
            (expr_list:REG_DEAD (reg:QI 0 ax [66])
                (expr_list:REG_DEAD (reg/f:SI 1 dx [orig:64 s ] [64])
                    (expr_list:REG_UNUSED (reg:CC 17 flags)
                        (expr_list:REG_UNUSED (reg/f:SI 1 dx [orig:64 s ] [64])
                            (nil))))))))
/home/ian/foo1.c:1: internal compiler error: in spill_failure, at reload1.c:1873Please submit a full bug report,
with preprocessed source if appropriate.
See <URL:http://gcc.gnu.org/bugs.html> for instructions.

This happens because the expansion of strlen requires the di register,
and I've told the compiler not to use it.

This is related to PR optimization/11001, which is an offshoot of PR
optimization/8092.  In the test case for PR optimization/11001, di is
dedicated to a local register variable:
    register int *rp asm("%edi");
Then there is a call to strlen.  The crash is the same as above.

It's quite easy to change gcc to avoid the crash when using
-ffixed-di.  It's a bit tricky to generate optimal code when using a
local register variable, but it's not hard to generate correct
code--we just keep have to keep track of which registers have
dedicated local variables.

The question is whether it's worth changing the compiler in this way.
Is this a case of ``don't do that?''  Or should the compiler aim to
generate correct code even in the presence of a dedicated local
register variable or a -ffixed-REG option?

If we say that this case is ``don't do that,'' then how much effort do
we want to put into generating a decent error message?  I note that PR
11001 was reported as a bug.  It's obvious to a backend gcc hacker
what is happening, but it's apparently not obvious even to experienced
gcc users.

It is interesting to note that the code compiles at -O2, with a call
to the strlen function.  In fact, strlen is inlined at -O1, but
explicitly called at -O2.  That seems frankly weird to me, but it's
apparently been that way since 2001.

Ian


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