Hi! This patch fixes two issues (that could be committed separately, but the testcase depends on both of them fixed).
The first one is in LRA, where my recent fix to move_plus_up fixed ICE on the testcase, but actually turned it into a wrong-debug - on the testcase the outer mode is SImode and inner mode is SFmode and the constant is SFmode 2.0 CONST_DOUBLE. Of course trying to subreg it into SImode and performing plus in SImode rather than adding 2.0 in SFmode is something completely different, so the patch limits it to the only case that can be supported, if both modes are integral. The second issue is that when expanding the SImode subreg of SFmode, we use typed DWARF stack for the SFmode, and then DW_OP_GNU_reinterpret it into unsigned 32-bit typed type (needed, so that the debugger knows to which type the reinterpretation happens). But, as the outer mode is integral with <= DWARF2_ADDR_SIZE, the callers expect that it gives us untyped value on the DWARF stack, while without the patch we get typed unsigned int. So, when we perform some further operations, as on the testcase subtraction of DW_OP_lit4, the debugger rightly complains about inconsistent DWARF stack (type mismatch on it). Fixed by converting the result using DW_OP_GNU_convert to the untyped type. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2016-01-12 Jakub Jelinek <ja...@redhat.com> PR debug/69244 * lra-eliminations.c (move_plus_up): Don't change anything if either the outer or inner subreg mode is not MODE_INT. * dwarf2out.c (mem_loc_descriptor): For SUBREG, if outer mode is integral <= DWARF2_ADDR_SIZE, convert to untyped afterwards. * gcc.dg/guality/pr69244.c: New test. --- gcc/lra-eliminations.c.jj 2016-01-11 20:05:59.000000000 +0100 +++ gcc/lra-eliminations.c 2016-01-12 16:05:08.283310272 +0100 @@ -295,7 +295,9 @@ move_plus_up (rtx x) subreg_reg_mode = GET_MODE (subreg_reg); if (GET_CODE (x) == SUBREG && GET_CODE (subreg_reg) == PLUS && GET_MODE_SIZE (x_mode) <= GET_MODE_SIZE (subreg_reg_mode) - && CONSTANT_P (XEXP (subreg_reg, 1))) + && CONSTANT_P (XEXP (subreg_reg, 1)) + && GET_MODE_CLASS (x_mode) == MODE_INT + && GET_MODE_CLASS (subreg_reg_mode) == MODE_INT) { rtx cst = simplify_subreg (x_mode, XEXP (subreg_reg, 1), subreg_reg_mode, subreg_lowpart_offset (x_mode, --- gcc/dwarf2out.c.jj 2016-01-04 14:55:51.000000000 +0100 +++ gcc/dwarf2out.c 2016-01-12 16:12:03.171587550 +0100 @@ -13239,6 +13239,13 @@ mem_loc_descriptor (rtx rtl, machine_mod cvt->dw_loc_oprnd1.v.val_die_ref.die = type_die; cvt->dw_loc_oprnd1.v.val_die_ref.external = 0; add_loc_descr (&mem_loc_result, cvt); + if (GET_MODE_CLASS (mode) == MODE_INT + && GET_MODE_SIZE (mode) <= DWARF2_ADDR_SIZE) + { + /* Convert it to untyped afterwards. */ + cvt = new_loc_descr (DW_OP_GNU_convert, 0, 0); + add_loc_descr (&mem_loc_result, cvt); + } } break; --- gcc/testsuite/gcc.dg/guality/pr69244.c.jj 2016-01-12 16:15:41.127579175 +0100 +++ gcc/testsuite/gcc.dg/guality/pr69244.c 2016-01-12 16:16:19.873041718 +0100 @@ -0,0 +1,30 @@ +/* PR debug/69244 */ +/* { dg-do run } */ +/* { dg-options "-g" } */ + +#include "../nop.h" + +union U { float f; int i; }; +float a, b; + +__attribute__((noinline, noclone)) void +foo (void) +{ + asm volatile ("" : : "g" (&a), "g" (&b) : "memory"); +} + +int +main () +{ + float e = a; + foo (); + float d = e; + union U p; + p.f = d += 2; + int c = p.i - 4; + asm (NOP : : : "memory"); + b = c; + return 0; +} + +/* { dg-final { gdb-test 25 "c" "p.i-4" } } */ Jakub