diff mbox series

Fix dwarf2out ICE with UNSPEC_GOTOFF (PR debug/82837)

Message ID 20171106213540.GB14653@tucnak
State New
Headers show
Series Fix dwarf2out ICE with UNSPEC_GOTOFF (PR debug/82837) | expand

Commit Message

Jakub Jelinek Nov. 6, 2017, 9:35 p.m. UTC
Hi!

My recent changes to const_ok_for_output_1 to allow UNSPEC if target hook
says it is ok for debug regressed the following testcase, where creative
simplify-rtx.c changes result in (const (neg (unspec ... UNSPEC_GOTOFF)))
being emitted and the backend not being able to assemble that (assembler
has no such relocations).
We already have a hack to avoid ICEing on NOT in similar cases, this patch
adds NEG to that.  And, in mem_loc_descriptor tries harder to handle these
cases right - while if we have say (const (not (symbol_ref))) the current
code would handle it right already, if there is the unspec, we really need
it to be wrapped inside of CONST, otherwise it is dropped on the floor.

The patch in that case emits (const (neg (unspec ... UNSPEC_GOTOFF)))
as (neg (const (unspec ... UNSPEC_GOTOFF))).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-11-06  Jakub Jelinek  <jakub@redhat.com>

	PR debug/82837
	* dwarf2out.c (const_ok_for_output_1): Reject NEG in addition to NOT.
	(mem_loc_descriptor): Handle (const (neg (...))) as (neg (const (...)))
	and similarly for not instead of neg.

	* gcc.dg/debug/dwarf2/pr82837.c: New test.


	Jakub

Comments

Jeff Law Nov. 8, 2017, 11:34 p.m. UTC | #1
On 11/06/2017 02:35 PM, Jakub Jelinek wrote:
> Hi!
> 
> My recent changes to const_ok_for_output_1 to allow UNSPEC if target hook
> says it is ok for debug regressed the following testcase, where creative
> simplify-rtx.c changes result in (const (neg (unspec ... UNSPEC_GOTOFF)))
> being emitted and the backend not being able to assemble that (assembler
> has no such relocations).
> We already have a hack to avoid ICEing on NOT in similar cases, this patch
> adds NEG to that.  And, in mem_loc_descriptor tries harder to handle these
> cases right - while if we have say (const (not (symbol_ref))) the current
> code would handle it right already, if there is the unspec, we really need
> it to be wrapped inside of CONST, otherwise it is dropped on the floor.
> 
> The patch in that case emits (const (neg (unspec ... UNSPEC_GOTOFF)))
> as (neg (const (unspec ... UNSPEC_GOTOFF))).
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2017-11-06  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR debug/82837
> 	* dwarf2out.c (const_ok_for_output_1): Reject NEG in addition to NOT.
> 	(mem_loc_descriptor): Handle (const (neg (...))) as (neg (const (...)))
> 	and similarly for not instead of neg.
> 
> 	* gcc.dg/debug/dwarf2/pr82837.c: New test.
OK.
jeff
diff mbox series

Patch

--- gcc/dwarf2out.c.jj	2017-11-01 22:49:18.000000000 +0100
+++ gcc/dwarf2out.c	2017-11-06 18:52:28.047287983 +0100
@@ -13782,10 +13782,14 @@  const_ok_for_output_1 (rtx rtl)
      We should really identify / validate expressions
      enclosed in CONST that can be handled by assemblers on various
      targets and only handle legitimate cases here.  */
-  if (GET_CODE (rtl) != SYMBOL_REF)
+  switch (GET_CODE (rtl))
     {
-      if (GET_CODE (rtl) == NOT)
-	return false;
+    case SYMBOL_REF:
+      break;
+    case NOT:
+    case NEG:
+      return false;
+    default:
       return true;
     }
 
@@ -14958,8 +14962,32 @@  mem_loc_descriptor (rtx rtl, machine_mod
       if (!const_ok_for_output (rtl))
 	{
 	  if (GET_CODE (rtl) == CONST)
-	    mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), int_mode,
-						 mem_mode, initialized);
+	    switch (GET_CODE (XEXP (rtl, 0)))
+	      {
+	      case NOT:
+		op = DW_OP_not;
+		goto try_const_unop;
+	      case NEG:
+		op = DW_OP_neg;
+		goto try_const_unop;
+	      try_const_unop:
+		rtx arg;
+		arg = XEXP (XEXP (rtl, 0), 0);
+		if (!CONSTANT_P (arg))
+		  arg = gen_rtx_CONST (int_mode, arg);
+		op0 = mem_loc_descriptor (arg, int_mode, mem_mode,
+					  initialized);
+		if (op0)
+		  {
+		    mem_loc_result = op0;
+		    add_loc_descr (&mem_loc_result, new_loc_descr (op, 0, 0));
+		  }
+		break;
+	      default:
+		mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), int_mode,
+						     mem_mode, initialized);
+		break;
+	      }
 	  break;
 	}
 
--- gcc/testsuite/gcc.dg/debug/dwarf2/pr82837.c.jj	2017-11-06 18:38:19.365703290 +0100
+++ gcc/testsuite/gcc.dg/debug/dwarf2/pr82837.c	2017-11-06 18:52:07.759536945 +0100
@@ -0,0 +1,29 @@ 
+/* PR debug/82837 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -g" } */
+/* { dg-additional-options "-march=athlon" { target ia32 } } */
+/* { dg-additional-options "-fPIE" { target pie } } */
+
+static char b[100];
+static int *c;
+char *e;
+void a(char *f, char *i) {
+  int d = __builtin_object_size(f, 1);
+  __builtin___strcpy_chk(f, i, d);
+}
+void g(void) {
+  int h;
+  switch (*c) {
+  case 8:
+    e = "swapgs";
+    break;
+  case 9:
+    e = "rdtscp";
+    break;
+  default:
+    return;
+  }
+  h = __builtin_strlen(b);
+  a(b + h - 6, e);
+  c++;
+}