Bug 48826 - ICE in dwarf2out_var_location, at dwarf2out.c:22013
Summary: ICE in dwarf2out_var_location, at dwarf2out.c:22013
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: ---
Assignee: Richard Sandiford
URL:
Keywords:
: 48843 (view as bug list)
Depends on:
Blocks:
 
Reported: 2011-04-29 16:27 UTC by Ryan Mansfield
Modified: 2018-10-15 02:21 UTC (History)
3 users (show)

See Also:
Host: i686-linux-gnu
Target: mips-unknown-linux-uclibc
Build: i686-linux-gnu
Known to work:
Known to fail:
Last reconfirmed: 2011-05-22 21:06:18


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ryan Mansfield 2011-04-29 16:27:37 UTC
$ cat ice.i
int foo() {
  return bar();
}
$ ./xgcc -v
Using built-in specs.
COLLECT_GCC=./xgcc
Target: mips-unknown-linux-uclibc
Configured with: ../configure --target=mips-unknown-linux-uclibc --prefix=/home/ryan/x-tools/mips-unknown-linux-uclibc --with-sysroot=/home/ryan/x-tools/mips-unknown-linux-uclibc/mips-unknown-linux-uclibc/sys-root --enable-languages=c --disable-multilib --with-float=soft --enable-__cxa_atexit --with-local-prefix=/home/ryan/x-tools/mips-unknown-linux-uclibc/mips-unknown-linux-uclibc/sys-root --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-c99 --enable-long-long --enable-target-optspace
Thread model: posix
gcc version 4.7.0 20110429 (experimental) [trunk revision 173156] (GCC) 
$ ./xgcc -B. -O -g ice.i
ice.i: In function 'foo':
ice.i:3:1: internal compiler error: in dwarf2out_var_location, at dwarf2out.c:22013
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
Comment 1 Ryan Mansfield 2011-05-04 13:01:31 UTC
The change that introduced this ICE is rev171033.

http://gcc.gnu.org/viewcvs?view=revision&revision=171033
Comment 2 Ryan Mansfield 2011-05-04 14:06:56 UTC
After rev171033 debugging is completely broken for this mips configuration. i.e. everything build I compile with -g ICEs this way.
Comment 3 Jakub Jelinek 2011-05-04 14:10:20 UTC
Most probably the backend is reordering insns after var-tracking, it shouldn't be doing that.  ARM/SH/S390 backends all have fixed similar bugs very quickly after this patch went in.
Comment 4 Ryan Mansfield 2011-05-05 13:19:43 UTC
The issue with ARM/SH/S390 backends appears to be there was a literal pool split happening in between a call insn and the NOTE_INSN_CALL_ARG_LOCATION. It looks like on mips the issue, at least for my testcase, is the gp store in mips_split_call is getting emitted in between the call insn and the note.

(call_insn 39 5 40 (parallel [
            (set (reg:SI 2 $2)
                (call (mem:SI (reg:SI 25 $25 [196]) [0 S4 A32])
                    (const_int 16 [0x10])))
            (clobber (reg:SI 31 $31))
            (clobber (reg:SI 28 $28))
        ]) /home/ryan/ice.i:2 575 {call_value_split}
     (nil)
    (expr_list:REG_DEP_TRUE (use (reg:SI 79 $fakec))
        (expr_list:REG_DEP_TRUE (use (reg:SI 28 $28))
            (nil))))

(insn 40 39 32 (set (reg:SI 28 $28)
        (mem/c:SI (plus:SI (reg/f:SI 29 $sp)
                (const_int 16 [0x10])) [0 S4 A32])) /home/ryan/ice.i:2 280 {*movsi_internal}
     (nil))

(note 32 40 7 (expr_list:REG_DEP_TRUE (concat:SI (reg:SI 79 $fakec)
        (reg:SI 79 $fakec))
    (expr_list:REG_DEP_TRUE (concat:SI (reg:SI 28 $28)
            (reg:SI 28 $28))
        (nil))) NOTE_INSN_CALL_ARG_LOCATION)
Comment 5 Richard Sandiford 2011-05-22 21:06:18 UTC
About to post a patch.
Comment 6 Richard Sandiford 2011-05-23 17:57:38 UTC
Author: rsandifo
Date: Mon May 23 17:57:35 2011
New Revision: 174080

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=174080
Log:
gcc/
	PR rtl-optimization/48826
	* emit-rtl.c (try_split): When splitting a call that is followed
	by a NOTE_INSN_CALL_ARG_LOCATION, move the note after the new call.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/emit-rtl.c
Comment 7 Richard Sandiford 2011-05-23 18:24:31 UTC
Fixed on trunk.
Comment 8 Richard Sandiford 2011-05-23 18:27:33 UTC
*** Bug 48843 has been marked as a duplicate of this bug. ***
Comment 9 Ryan Mansfield 2011-05-26 14:20:54 UTC
Richard, thanks for your patch. It fixed most of the failures I saw but there are still cases where the note doesn't get moved after call split. The following example ICEs with rev174285.

void  foo ()
{
  int *const pc = __builtin_return_address (0);
  bar (pc);
}
Comment 10 baoshan 2014-09-11 21:44:32 UTC
The code is broken in the latest code because beside NOTE instruction there could be BARRIER too, for instance the RTX list I am seeing:

(call_insn 32 35 33 (parallel [
            (set (reg:SI 2 $2)
                (call (mem:SI (reg:SI 25 $25 [198]) [0  S4 A32])
                    (const_int 16 [0x10])))
            (clobber (reg:SI 31 $31))
            (clobber (reg:SI 28 $28))
        ]) min.c:20 603 {call_value_split}
     (nil)
    (expr_list (use (reg:SI 79 $fakec))
        (expr_list (use (reg:SI 28 $28))
            (expr_list:SI (use (reg:SI 5 $5))
                (expr_list:SI (use (reg:SI 4 $4))
                    (nil))))))
(insn 33 32 34 (set (reg:SI 28 $28)
        (mem/c:SI (plus:SI (reg/f:SI 29 $sp)
                (const_int 16 [0x10])) [0  S4 A32])) min.c:20 288 {*movsi_internal}
     (nil))
(barrier 34 33 18)
(barrier 18 34 30)
(note 30 18 21 (expr_list:REG_DEP_TRUE (concat:SI (pc)
        (unspec:SI [
                (reg:SI 28 $28)
	        (const:SI (unspec:SI [
                            (symbol_ref:SI ("signal") [flags 0x41]  <function_decl 0xb71f6700 signal>)
		        ] 227))
                (reg:SI 79 $fakec)
            ] UNSPEC_LOAD_CALL))
    (expr_list:REG_DEP_TRUE (concat:SI (reg:SI 5 $5)
            (const_int 0 [0]))
        (expr_list:REG_DEP_TRUE (concat:SI (reg:SI 4 $4)
	        (const_int 2 [0x2]))
            (nil)))) NOTE_INSN_CALL_ARG_LOCATION)
(note 21 30 0 NOTE_INSN_DELETED)
Comment 11 baoshan 2014-09-11 21:50:33 UTC
And I don't thing it is the best place to fix this bug in function try_split().
Why not fix it at where the ICE occurs? It is just the wrong expectation from function dwarf2out_var_location(). Why not just look forward further if the 'prev'is not what we want? I like to add this code before gcc_assert() to fix this issue:

       while(prev && !CALL_P(prev) && !(GET_CODE (PATTERN (prev)) == SEQUENCE
                                 && CALL_P (XVECEXP (PATTERN (prev), 0, 0)))){
          gcc_assert(NONJUMP_INSN_P (prev));
	  prev = prev_real_insn (prev);
        }