On Thu, Mar 17, 2011 at 12:32 AM, Jakub Jelinek <[email protected]> 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 <[email protected]>
>
> 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
>