diff mbox

Ensure DEBUG_INSNs don't contain MEMs with non-canonical MEM_EXPRs (PR debug/48134)

Message ID 20110316233202.GQ30899@tyan-ft48-01.lab.bos.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek March 16, 2011, 11:32 p.m. UTC
Hi!

Currently expand_debug_expr doesn't always guarantee canonical
MEM_EXPRs, if MEM_EXPR isn't canonical, sometimes aliasing code ICEs on it
(since recent Richard's change fortunately only if --enable-checking=yes).

The following patch canonicalizes those using fold and if canonicalization
isn't successful, just clears the MEM_EXPR.

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

2011-03-17  Jakub Jelinek  <jakub@redhat.com>

	PR debug/48134
	* cfgexpand.c (expand_debug_expr) <component_ref>: Use fold to
	canonicalize MEM_EXPR, if it still isn't canonical afterwards, just
	clear MEM_EXPR.

	* gcc.dg/pr48134.c: New test.


	Jakub

Comments

Richard Biener March 17, 2011, 8:41 a.m. UTC | #1
On Thu, Mar 17, 2011 at 12:32 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> Currently expand_debug_expr doesn't always guarantee canonical
> MEM_EXPRs, if MEM_EXPR isn't canonical, sometimes aliasing code ICEs on it
> (since recent Richard's change fortunately only if --enable-checking=yes).
>
> The following patch canonicalizes those using fold and if canonicalization
> isn't successful, just clears the MEM_EXPR.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and
> 4.6.1?
>
> 2011-03-17  Jakub Jelinek  <jakub@redhat.com>
>
>        PR debug/48134
>        * cfgexpand.c (expand_debug_expr) <component_ref>: Use fold to
>        canonicalize MEM_EXPR, if it still isn't canonical afterwards, just
>        clear MEM_EXPR.
>
>        * gcc.dg/pr48134.c: New test.
>
> --- gcc/cfgexpand.c.jj  2011-03-16 18:30:12.000000000 +0100
> +++ gcc/cfgexpand.c     2011-03-16 22:05:13.000000000 +0100
> @@ -2712,6 +2712,8 @@ expand_debug_expr (tree exp)
>
>        if (MEM_P (op0))
>          {
> +           tree mem_exp;
> +
>            if (mode1 == VOIDmode)
>              /* Bitfield.  */
>              mode1 = smallest_mode_for_size (bitsize, MODE_INT);
> @@ -2736,6 +2738,12 @@ expand_debug_expr (tree exp)
>            if (op0 == orig_op0)
>              op0 = shallow_copy_rtx (op0);
>            set_mem_attributes (op0, exp, 0);
> +           mem_exp = fold (exp);
> +           if (!SSA_VAR_P (mem_exp)
> +               && TREE_CODE (mem_exp) != MEM_REF
> +               && TREE_CODE (mem_exp) != TARGET_MEM_REF)
> +             mem_exp = NULL_TREE;
> +           set_mem_expr (op0, mem_exp);

That will, for the testcase drop the MEM[&t.s].w completely, right?
I think you eventually want to use maybe_fold_reference which does
canonicalize mem-refs after propagation (but also watch for bogus
debug information due to constant folding of initializers I
ran into because of setting DECL_INITIAL to error_mark_node for
unused globals - I'll try to dig up the patch I had to fix that).

Richard.

>          }
>
>        if (bitpos == 0 && mode == GET_MODE (op0))
> --- gcc/testsuite/gcc.dg/pr48134.c.jj   2011-03-16 22:04:35.000000000 +0100
> +++ gcc/testsuite/gcc.dg/pr48134.c      2011-03-16 22:02:13.000000000 +0100
> @@ -0,0 +1,25 @@
> +/* PR debug/48134 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -fstack-check=specific -fno-tree-dse -fno-tree-fre -fno-tree-loop-optimize -g" } */
> +
> +struct S { int w, z; };
> +struct T { struct S s; };
> +int i;
> +
> +static inline struct S
> +bar (struct S x)
> +{
> +  i++;
> +  return x;
> +}
> +
> +int
> +foo (struct T t, struct S s)
> +{
> +  struct S *c = &s;
> +  if (i)
> +    c = &t.s;
> +  t.s.w = 3;
> +  s = bar (*c);
> +  return t.s.w;
> +}
>
>        Jakub
>
Richard Biener March 17, 2011, 12:42 p.m. UTC | #2
On Thu, Mar 17, 2011 at 9:41 AM, Richard Guenther
<richard.guenther@gmail.com> wrote:
> On Thu, Mar 17, 2011 at 12:32 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>> Hi!
>>
>> Currently expand_debug_expr doesn't always guarantee canonical
>> MEM_EXPRs, if MEM_EXPR isn't canonical, sometimes aliasing code ICEs on it
>> (since recent Richard's change fortunately only if --enable-checking=yes).
>>
>> The following patch canonicalizes those using fold and if canonicalization
>> isn't successful, just clears the MEM_EXPR.
>>
>> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and
>> 4.6.1?
>>
>> 2011-03-17  Jakub Jelinek  <jakub@redhat.com>
>>
>>        PR debug/48134
>>        * cfgexpand.c (expand_debug_expr) <component_ref>: Use fold to
>>        canonicalize MEM_EXPR, if it still isn't canonical afterwards, just
>>        clear MEM_EXPR.
>>
>>        * gcc.dg/pr48134.c: New test.
>>
>> --- gcc/cfgexpand.c.jj  2011-03-16 18:30:12.000000000 +0100
>> +++ gcc/cfgexpand.c     2011-03-16 22:05:13.000000000 +0100
>> @@ -2712,6 +2712,8 @@ expand_debug_expr (tree exp)
>>
>>        if (MEM_P (op0))
>>          {
>> +           tree mem_exp;
>> +
>>            if (mode1 == VOIDmode)
>>              /* Bitfield.  */
>>              mode1 = smallest_mode_for_size (bitsize, MODE_INT);
>> @@ -2736,6 +2738,12 @@ expand_debug_expr (tree exp)
>>            if (op0 == orig_op0)
>>              op0 = shallow_copy_rtx (op0);
>>            set_mem_attributes (op0, exp, 0);
>> +           mem_exp = fold (exp);
>> +           if (!SSA_VAR_P (mem_exp)
>> +               && TREE_CODE (mem_exp) != MEM_REF
>> +               && TREE_CODE (mem_exp) != TARGET_MEM_REF)
>> +             mem_exp = NULL_TREE;
>> +           set_mem_expr (op0, mem_exp);
>
> That will, for the testcase drop the MEM[&t.s].w completely, right?
> I think you eventually want to use maybe_fold_reference which does
> canonicalize mem-refs after propagation (but also watch for bogus
> debug information due to constant folding of initializers I
> ran into because of setting DECL_INITIAL to error_mark_node for
> unused globals - I'll try to dig up the patch I had to fix that).

I am testing the following.

Richard.
diff mbox

Patch

--- gcc/cfgexpand.c.jj	2011-03-16 18:30:12.000000000 +0100
+++ gcc/cfgexpand.c	2011-03-16 22:05:13.000000000 +0100
@@ -2712,6 +2712,8 @@  expand_debug_expr (tree exp)
 
 	if (MEM_P (op0))
 	  {
+	    tree mem_exp;
+
 	    if (mode1 == VOIDmode)
 	      /* Bitfield.  */
 	      mode1 = smallest_mode_for_size (bitsize, MODE_INT);
@@ -2736,6 +2738,12 @@  expand_debug_expr (tree exp)
 	    if (op0 == orig_op0)
 	      op0 = shallow_copy_rtx (op0);
 	    set_mem_attributes (op0, exp, 0);
+	    mem_exp = fold (exp);
+	    if (!SSA_VAR_P (mem_exp)
+		&& TREE_CODE (mem_exp) != MEM_REF
+		&& TREE_CODE (mem_exp) != TARGET_MEM_REF)
+	      mem_exp = NULL_TREE;
+	    set_mem_expr (op0, mem_exp);
 	  }
 
 	if (bitpos == 0 && mode == GET_MODE (op0))
--- gcc/testsuite/gcc.dg/pr48134.c.jj	2011-03-16 22:04:35.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr48134.c	2011-03-16 22:02:13.000000000 +0100
@@ -0,0 +1,25 @@ 
+/* PR debug/48134 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fstack-check=specific -fno-tree-dse -fno-tree-fre -fno-tree-loop-optimize -g" } */
+
+struct S { int w, z; };
+struct T { struct S s; };
+int i;
+
+static inline struct S
+bar (struct S x)
+{
+  i++;
+  return x;
+}
+
+int
+foo (struct T t, struct S s)
+{
+  struct S *c = &s;
+  if (i)
+    c = &t.s;
+  t.s.w = 3;
+  s = bar (*c);
+  return t.s.w;
+}