http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46724
Summary: Wrong debug info: Invalid variable location Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: debug AssignedTo: unassig...@gcc.gnu.org ReportedBy: kreb...@gcc.gnu.org The guality/nrv-1.c testcase currently fails on s390x when compiled with -O2: Breakpoint 1, f () at /build3/gcc-head/gcc/testsuite/gcc.dg/guality/nrv-1.c:20 20 a2.i[4] = 7; /* { dg-final { gdb-test 20 "a2.i\[0\]" "42" } } */ Missing separate debuginfos, use: debuginfo-install glibc-2.12.1-2.s390x (gdb) p a2.i[0] $1 = -336596880 The memory location of 'a2' is given as being based on r1: readelf --debug-dump=info ... <2><85>: Abbrev Number: 9 (DW_TAG_variable) <86> DW_AT_name : a2 <89> DW_AT_decl_file : 1 <8a> DW_AT_decl_line : 16 <8b> DW_AT_type : <0x2d> <8f> DW_AT_location : 2 byte block: 71 0 (DW_OP_breg1: 0) ... But in fact r1 is not used at all. Instead the location is in r2: f: .LFB0: .file 1 "/build3/gcc-head/gcc/testsuite/gcc.dg/guality/nrv-1.c" .loc 1 15 0 .cfi_startproc .loc 1 17 0 lhi %r3,42 st %r3,0(%r2) <-- a2.i[0] = 42; ... a2 is returned by f. The address of the location where the return value should reside is passed to f as implicit first parameter in r2. Right before cprop_hardreg the code looks like this. r2 is copied into r1 and r1 is used to reference a2. DECL_RTL (<retval>) is (mem/s:SI (reg/f:DI 1 %r1 [orig:45 D.1986 ] [45]). nrv-1.c.201r.ce3: (insn 2 8 47 2 (set (reg/f:DI 1 %r1 [orig:45 D.1986 ] [45]) (reg:DI 2 %r2 [ D.1986 ])) /build3/gcc-head/gcc/testsuite/gcc.dg/guality/nrv-1.c:15 62 {*movdi_64} (nil)) (insn 47 2 6 2 (set (reg:SI 3 %r3) (const_int 42 [0x2a])) /build3/gcc-head/gcc/testsuite/gcc.dg/guality/nrv-1.c:17 66 {*movsi_zarch} (nil)) (insn 6 47 45 2 (set (mem/s:SI (reg/f:DI 1 %r1 [orig:45 D.1986 ] [45]) [2 <retval>.i+0 S4 A32]) (reg:SI 3 %r3)) /build3/gcc-head/gcc/testsuite/gcc.dg/guality/nrv-1.c:17 66 {*movsi_zarch} (expr_list:REG_DEAD (reg:SI 3 %r3) (nil))) Then r1 is propagated into insn 6 and insn 2 is removed in DCE while DECL_RTL (<retval>) still references r1. nrv-1.c.203r.cprop_hardreg: (insn 2 8 47 2 (set (reg/f:DI 1 %r1 [orig:45 D.1986 ] [45]) (reg:DI 2 %r2 [ D.1986 ])) /build3/gcc-head/gcc/testsuite/gcc.dg/guality/nrv-1.c:15 62 {*movdi_64} (nil)) (insn 47 2 6 2 (set (reg:SI 3 %r3) (const_int 42 [0x2a])) /build3/gcc-head/gcc/testsuite/gcc.dg/guality/nrv-1.c:17 66 {*movsi_zarch} (nil)) (insn 6 47 45 2 (set (mem/s:SI (reg/f:DI 2 %r2 [orig:45 D.1986 ] [45]) [2 <retval>.i+0 S4 A32]) (reg:SI 3 %r3)) /build3/gcc-head/gcc/testsuite/gcc.dg/guality/nrv-1.c:17 66 {*movsi_zarch} (expr_list:REG_DEAD (reg:SI 3 %r3) (nil))) When generating the debug info for a2 add_location_or_const_value_attribute first tries to find an RTX for a2 directly by invoking rtl_for_decl_location p on the VAR_DECL of a2 what returns NULL. It then invokes loc_list_from_tree which uses the DECL_VALUE_EXPR of the a2 decl - this is <retval>. rtl_for_decl_location then returns (mem/s:SI (reg/f:DI 1 %r1 [orig:45 D.1986 ] [45]) for <retval>.