CVS head bug for target sh-elf: unrecognizable insn
tm
tm@kloo.net
Tue Jun 25 12:37:00 GMT 2002
I've done some more investigation of the problem I mentioned in:
http://gcc.gnu.org/ml/gcc-bugs/2002-06/msg00691.html
This insns seems to be unrecognizable because:
1) The SH4 has overloaded SFmode/DFmode register moves, and the actual width of the operand
is specified by the PR bit in the FPSCR, and
2) The SH4 has SFmode register moves defined as:
(define_insn "movsf_ie"
[(set (match_operand:SF 0 "general_movdst_operand"
"=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
(match_operand:SF 1 "general_movsrc_operand"
"f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
(use (match_operand:PSI 2 "fpscr_operand" "c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c,c"))
(clobber (match_scratch:SI 3 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
The insn doesn't seem to match because of the missing fpscr_operand
This abort occurs during regmove as shown by the stack backtrace:
#0 extract_insn (insn=0x4035ce88) at ../../gcc/gcc/recog.c:2130
#1 0x0827dfca in find_matches (insn=0x4035ce88, matchp=0xbffff070) at ../../gcc/gcc/regmove.c:1540
#2 0x0827d51a in regmove_optimize (f=0x40322b40, nregs=625, regmove_dump_file=0x0) at ../../gcc/gcc/regmove.c:1138
#3 0x08201f9e in rest_of_compilation (decl=0x40305348) at ../../gcc/gcc/toplev.c:3107
#4 0x0805fa00 in c_expand_body (fndecl=0x40305348, nested_p=0, can_defer_p=1) at ../../gcc/gcc/c-decl.c:6902#5 0x0805f720 in finish_function (nested=0, can_defer_p=1) at ../../gcc/gcc/c-decl.c:6769
#6 0x0804a06c in yyparse () at c-parse.y:396
#7 0x08050203 in c_common_parse_file (set_yydebug=0) at ../../gcc/gcc/c-lex.c:165
#8 0x08200505 in compile_file () at ../../gcc/gcc/toplev.c:2094
#9 0x082051d3 in do_compile () at ../../gcc/gcc/toplev.c:5185
#10 0x08205234 in toplev_main (argc=4, argv=0xbffff934) at ../../gcc/gcc/toplev.c:5217
#11 0x4003ab5c in __libc_start_main (main=0x80942dc <main>, argc=4, ubp_av=0xbffff934, init=0x8049080 <_init>,
fini=0x82a1780 <_fini>, rtld_fini=0x4000d634 <_dl_fini>, stack_end=0xbffff92c) at ../sysdeps/generic/libc-start.c:129
It appears this insn is created not by regmove, but by gcse:
(gdb) print insn->fld.rtint
$1 = 1078
(gdb) bt
#0 make_insn_raw (pattern=0x4038ba64) at ../../gcc/gcc/emit-rtl.c:3327
#1 0x080e5545 in emit_insn_after (x=0x4038ba64, after=0x40354078) at ../../gcc/gcc/emit-rtl.c:4131
#2 0x0814e8d4 in gcse_emit_move_after (src=0x4038ba50, dest=0x40349e74, insn=0x40354078) at ../../gcc/gcc/gcse.c:5154
#3 0x0814ea41 in pre_delete () at ../../gcc/gcc/gcse.c:5215
#4 0x0814ebdc in pre_gcse () at ../../gcc/gcc/gcse.c:5282
#5 0x0814ecbb in one_pre_gcse_pass (pass=1) at ../../gcc/gcc/gcse.c:5328
#6 0x08148a77 in gcse_main (f=0x40322b40, file=0x0) at ../../gcc/gcc/gcse.c:830
#7 0x08201792 in rest_of_compilation (decl=0x40305348) at ../../gcc/gcc/toplev.c:2816
#8 0x0805fa00 in c_expand_body (fndecl=0x40305348, nested_p=0, can_defer_p=1) at ../../gcc/gcc/c-decl.c:6902#9 0x0805f720 in finish_function (nested=0, can_defer_p=1) at ../../gcc/gcc/c-decl.c:6769
#10 0x0804a06c in yyparse () at c-parse.y:396
#11 0x08050203 in c_common_parse_file (set_yydebug=0) at ../../gcc/gcc/c-lex.c:165
#12 0x08200505 in compile_file () at ../../gcc/gcc/toplev.c:2094
#13 0x082051d3 in do_compile () at ../../gcc/gcc/toplev.c:5185
#14 0x08205234 in toplev_main (argc=4, argv=0xbffff934) at ../../gcc/gcc/toplev.c:5217
#15 0x4003ab5c in __libc_start_main (main=0x80942dc <main>, argc=4, ubp_av=0xbffff934, init=0x8049080 <_init>,
fini=0x82a1780 <_fini>, rtld_fini=0x4000d634 <_dl_fini>, stack_end=0xbffff92c) at ../sysdeps/generic/libc-start.c:129
The problem appears to be in this function:
/* This subroutine of apply_change_group verifies whether the changes to INSN
were valid; i.e. whether INSN can still be recognized. */
/* Emit move from SRC to DEST noting the equivalence with expression computed
in INSN. */
static rtx
gcse_emit_move_after (src, dest, insn)
rtx src, dest, insn;
{
rtx new;
rtx set = single_set (insn);
rtx note;
rtx eqv;
/* This should never fail since we're creating a reg->reg copy
we've verified to be valid. */
new = emit_insn_after (gen_rtx_SET (VOIDmode, dest, src), insn);
...
This appears to create an SFmode register-to-register move without the third operand.
Does this analysis appear correct?
Toshi
More information about the Gcc-bugs
mailing list