This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix LRA and dwarf2out issues (PR debug/69244)


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.

--- 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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]