Hi! On the following testcase we ICE in dwarf2out, because apparently reg-stack changed a (var_location:SI D#1 (subreg:SI (reg:SF 8) 0)) into (var_location:SI D#1 (reg:SF 8)) (note the subreg is gone and mismatching mode). The problem seems to be in get_true_reg function that subst_stack_regs_in_debug_insn calls, looks like that function is only prepared to handle subregs of the i387 regs that are valid in code sequences, where such SImode subreg of SF wouldn't be allowed. For DEBUG_INSNs, IMHO instead of tweaking that routine we can just adjust the REG itself (this fn is called through for_each_rtx) and keep around all the SUBREGs/FLOAT_EXTENDs and similar UNARY rtxes around it that get_true_reg likes to strip. This wasn't a problem before when just all floating point debug values were dropped on the floor in dwarf2out, but now that we have the typed DWARF stack support, they are actually emitted.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2012-02-06 Jakub Jelinek <ja...@redhat.com> PR debug/52132 * reg-stack.c (subst_stack_regs_in_debug_insn): Don't use get_true_reg. * gcc.dg/pr52132.c: New test. --- gcc/reg-stack.c.jj 2011-12-01 11:45:06.000000000 +0100 +++ gcc/reg-stack.c 2012-02-06 11:13:28.777795938 +0100 @@ -1323,14 +1323,10 @@ compare_for_stack_reg (rtx insn, stack r static int subst_stack_regs_in_debug_insn (rtx *loc, void *data) { - rtx *tloc = get_true_reg (loc); stack regstack = (stack)data; int hard_regno; - if (!STACK_REG_P (*tloc)) - return 0; - - if (tloc != loc) + if (!STACK_REG_P (*loc)) return 0; hard_regno = get_hard_regnum (regstack, *loc); --- gcc/testsuite/gcc.dg/pr52132.c.jj 2012-02-06 11:14:23.572547529 +0100 +++ gcc/testsuite/gcc.dg/pr52132.c 2012-02-06 11:14:46.656442861 +0100 @@ -0,0 +1,18 @@ +/* PR debug/52132 */ +/* { dg-do compile } */ +/* { dg-options "-std=c99 -O2 -g" } */ + +int l; +void bar (void); + +void +foo (int *x, float y) +{ + float b; + union { float f; int i; } u = { .f = y }; + u.i += 127 << 23; + u.f = ((-1.0f / 3) * u.f + 2) * u.f - 2.0f / 3; + b = 0.5 * (u.f + l); + if (b >= *x) + bar (); +} Jakub