This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
-ffixed-di vs. strlen
- From: Ian Lance Taylor <ian at wasabisystems dot com>
- To: gcc at gcc dot gnu dot org
- Date: 12 Feb 2004 15:06:15 -0500
- Subject: -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