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