This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix tail merging (PR tree-optimization/51877)
- From: Richard Guenther <rguenther at suse dot de>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: Tom de Vries <vries at codesourcery dot com>, gcc-patches at gcc dot gnu dot org
- Date: Tue, 17 Jan 2012 11:40:00 +0100 (CET)
- Subject: Re: [PATCH] Fix tail merging (PR tree-optimization/51877)
- References: <20120117102527.GE18768@tyan-ft48-01.lab.bos.redhat.com>
On Tue, 17 Jan 2012, Jakub Jelinek wrote:
> Hi!
>
> We tail merge
> a = bar (7);
> with
> *x = bar (7);
> completely ignoring the case that the lhs are different.
> IMHO we can't merge if one of the calls has lhs and the other doesn't,
> or if both calls have non-SSA_NAME lhs and they aren't equal (this case).
> If both calls have SSA_NAME lhs, I can see why it might be nice to tail
> merge both if the calls have the same argument same destination even when
> the lhs don't valueize the same (sccvn will value number the same just
> pure/const calls, right), but I don't see how it can actually work,
> the SSA_NAMEs will be used somewhere later on in the BB or in the PHI,
> and there we compare vn_valueize anyway. We'd need to somehow mark
> those two SSA_NAMEs as equivalent for further VN.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok.
Thanks,
Richard.
> 2012-01-17 Jakub Jelinek <jakub@redhat.com>
>
> PR tree-optimization/51877
> * tree-ssa-tail-merge.c (gimple_equal_p): Don't return true whenever
> call arguments and fndecls compare equal, instead return false if they
> don't. Return true only if lhs1 and lhs2 are either both NULL, or
> both SSA_NAMEs that are valueized the same, or they satisfy
> operand_equal_p.
>
> * gcc.c-torture/execute/pr51877.c: New test.
>
> --- gcc/tree-ssa-tail-merge.c.jj 2011-12-12 22:10:26.000000000 +0100
> +++ gcc/tree-ssa-tail-merge.c 2012-01-17 08:28:56.903471558 +0100
> @@ -1071,14 +1071,18 @@ gimple_equal_p (same_succ same_succ, gim
> equal = false;
> break;
> }
> - if (equal)
> - return true;
> + if (!equal)
> + return false;
>
> lhs1 = gimple_get_lhs (s1);
> lhs2 = gimple_get_lhs (s2);
> - return (lhs1 != NULL_TREE && lhs2 != NULL_TREE
> - && TREE_CODE (lhs1) == SSA_NAME && TREE_CODE (lhs2) == SSA_NAME
> - && vn_valueize (lhs1) == vn_valueize (lhs2));
> + if (lhs1 == NULL_TREE && lhs2 == NULL_TREE)
> + return true;
> + if (lhs1 == NULL_TREE || lhs2 == NULL_TREE)
> + return false;
> + if (TREE_CODE (lhs1) == SSA_NAME && TREE_CODE (lhs2) == SSA_NAME)
> + return vn_valueize (lhs1) == vn_valueize (lhs2);
> + return operand_equal_p (lhs1, lhs2, 0);
>
> case GIMPLE_ASSIGN:
> lhs1 = gimple_get_lhs (s1);
> --- gcc/testsuite/gcc.c-torture/execute/pr51877.c.jj 2012-01-17 08:36:31.012781551 +0100
> +++ gcc/testsuite/gcc.c-torture/execute/pr51877.c 2012-01-17 08:35:26.000000000 +0100
> @@ -0,0 +1,50 @@
> +/* PR tree-optimization/51877 */
> +
> +extern void abort (void);
> +struct A { int a; char b[32]; } a, b;
> +
> +__attribute__((noinline, noclone))
> +struct A
> +bar (int x)
> +{
> + struct A r;
> + static int n;
> + r.a = ++n;
> + __builtin_memset (r.b, 0, sizeof (r.b));
> + r.b[0] = x;
> + return r;
> +}
> +
> +__attribute__((noinline, noclone))
> +void
> +baz (void)
> +{
> + asm volatile ("" : : : "memory");
> +}
> +
> +__attribute__((noinline, noclone))
> +void
> +foo (struct A *x, int y)
> +{
> + if (y == 6)
> + a = bar (7);
> + else
> + *x = bar (7);
> + baz ();
> +}
> +
> +int
> +main ()
> +{
> + a = bar (3);
> + b = bar (4);
> + if (a.a != 1 || a.b[0] != 3 || b.a != 2 || b.b[0] != 4)
> + abort ();
> + foo (&b, 0);
> + if (a.a != 1 || a.b[0] != 3 || b.a != 3 || b.b[0] != 7)
> + abort ();
> + foo (&b, 6);
> + if (a.a != 4 || a.b[0] != 7 || b.a != 3 || b.b[0] != 7)
> + abort ();
> + return 0;
> +}
>
> Jakub
>
>
--
Richard Guenther <rguenther@suse.de>
SUSE / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer