Message ID | 20160113083511.GP3017@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On 01/13/2016 01:35 AM, Jakub Jelinek wrote: > 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 <jakub@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. OK. jeff
--- 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" } } */