[Bug ada/48835] porting GNAT to m68k-linux

mikpe at it dot uu.se gcc-bugzilla@gcc.gnu.org
Fri Mar 22 14:30:00 GMT 2013


--- Comment #55 from Mikael Pettersson <mikpe at it dot uu.se> 2013-03-22 14:30:23 UTC ---
(In reply to comment #54)
> This ICE started with r180192, an ICE fix (PR50780).  I don't see anything in
> that patch that seems m68k or cc0 related

Actually, r180192 is HIGHLY CC0-related, see PR49847#c16.

Here's an annotated gdb session:

sh-4.2$ gdb /mnt/scratch/objdir47/./gcc/gnat1
GNU gdb (GDB) Brewer Linux (
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "m68k-brewer-linux-gnu".
For bug reporting instructions, please see:
Reading symbols from /mnt/scratch/objdir47/gcc/gnat1...done.
(gdb) run -gnatwa -quiet -nostdinc -dumpbase a-calfor.adb -auxbase-strip
a-calfor.o -O2 -Wextra -Wall -fpic -g -mcpu=68060 -gnatpg -mcpu=68060 -gnatO
a-calfor.o a-calfor.adb -o /tmp/ccudsaKf.s
Starting program: /mnt/scratch/objdir47/gcc/gnat1 -gnatwa -quiet -nostdinc
-dumpbase a-calfor.adb -auxbase-strip a-calfor.o -O2 -Wextra -Wall -fpic -g
-mcpu=68060 -gnatpg -mcpu=68060 -gnatO a-calfor.o a-calfor.adb -o

Program received signal SIGSEGV, Segmentation fault.
0x806f7016 in find_comparison_args (code=GE, parg1=0xeffff218,
parg2=0xeffff21c, pmode1=0xeffff220, pmode2=0xeffff224) at
2975      while (arg2 == CONST0_RTX (GET_MODE (arg1)))
Missing separate debuginfos, use: debuginfo-install
glibc-2.15-58.bl17.bl.1.m68k gmp-5.0.4-1.bl15.bl.2.m68k
libmpc-1.0.1-1.bl17.bl.1.m68k mpfr-3.1.1-1.bl17.bl.1.m68k
(gdb) bt
#0  0x806f7016 in find_comparison_args (code=GE, parg1=0xeffff218,
parg2=0xeffff21c, pmode1=0xeffff220, pmode2=0xeffff224) at
#1  0x806fe620 in record_jump_equiv (taken=<optimized out>, insn=0xc0a07440) at
#2  cse_extended_basic_block (ebb_data=<optimized out>) at
#3  cse_main (f=0xc09e3f80, nregs=185) at
#4  0x806fe720 in rest_of_handle_cse () at
#5  0x804ba474 in execute_one_pass (pass=0x8088bc8c) at
#6  0x804ba780 in execute_pass_list (pass=0x8088bc8c) at
#7  0x804ba790 in execute_pass_list (pass=0x80889834) at
#8  0x8057b212 in tree_rest_of_compilation (fndecl=0xc0547600) at
#9  0x8035bb5a in cgraph_expand_function (node=0xc04d3d10) at
#10 0x8035d3f2 in cgraph_expand_all_functions () at
#11 cgraph_optimize () at /mnt/scratch/gcc-4.7-r180192/gcc/cgraphunit.c:2168
#12 0x8035d57e in cgraph_finalize_compilation_unit () at
#13 0x80049b26 in gnat_write_global_declarations () at
#14 0x8053e70a in compile_file () at
#15 do_compile () at /mnt/scratch/gcc-4.7-r180192/gcc/toplev.c:1930
#16 toplev_main (argc=21, argv=0xeffff444) at
#17 0xc012dee8 in __libc_start_main () from /lib/libc.so.6
#18 0x800279a2 in _start ()
(gdb) list
2971      arg1 = *parg1, arg2 = *parg2;
2973      /* If ARG2 is const0_rtx, see what ARG1 is equivalent to.  */
2975      while (arg2 == CONST0_RTX (GET_MODE (arg1)))
2976        {
2977          /* Set nonzero when we find something of interest.  */
2978          rtx x = 0;
2979          int reverse_code = 0;
(gdb) print *parg1
$1 = (rtx) 0x0

We're at the start of find_comparison_args, and *parg1 is NULL. No wonder we
SEGV then at line 2975.

(gdb) up
#1  0x806fe620 in record_jump_equiv (taken=<optimized out>, insn=0xc0a07440) at
3920      code = find_comparison_args (code, &op0, &op1, &mode0, &mode1);
(gdb) list
3915         know that it isn't valid for floating-point.  */
3916      code = GET_CODE (XEXP (SET_SRC (set), 0));
3917      op0 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 0), insn);
3918      op1 = fold_rtx (XEXP (XEXP (SET_SRC (set), 0), 1), insn);
3920      code = find_comparison_args (code, &op0, &op1, &mode0, &mode1);
3921      if (! cond_known_true)
3922        {
3923          code = reversed_comparison_code_parts (code, op0, op1, insn);
(gdb) print op0
$2 = (rtx) 0x0
(gdb) call debug_rtx(set)
(set (pc)
    (if_then_else (ge (cc0)
            (const_int 0 [0]))
        (label_ref:SI 471)
(gdb) call debug_rtx(insn)
(jump_insn 298 457 458 43 (set (pc)
        (if_then_else (ge (cc0)
                (const_int 0 [0]))
            (label_ref:SI 471)
            (pc))) a-calfor.adb:758 398 {bge}
     (expr_list:REG_BR_PROB (const_int 5000 [0x1388])
 -> 471)

record_jump_equiv gets a jump_insn with a condition whose OP0 was (cc0) but
fold_rtx turned it into NULL.  So we're calling find_comparison_args with a
pointer to NULL, causing it to SEGV.

A quick look at the start of fold_rtx reveals:

  /* Try to perform some initial simplifications on X.  */
  code = GET_CODE (x);
  switch (code)
#ifdef HAVE_cc0
    case CC0:
      return prev_insn_cc0;

Remember PR49847?  A consequence of r180192 is that it may separate CC0 setters
from users in EH contexts.  And that's clearly what's happening here.  Patching
the above case to return x when prev_insn_cc0 is NULL eliminates the SEGV when
compiling a-calfor.adb, and allows compilation to proceed through many more
.adb files; a debug printf shows that the case above with NULL prev_insn_cc0
triggers many times when compiling the 68060-optimized Ada runtime.  I'm
currently doing a clean bootstrap with that patch.

More information about the Gcc-bugs mailing list