On Fri, Sep 30, 2011 at 09:50:09AM +0200, Richard Guenther wrote:
> Hmm, in fwprop can you limit your change to non-invariant addresses?
> That is, we do want to propagate invariant addresses over
> restrict casts, because that will give us _more_ precise alias info
> than restrict.
Will it?
I'd think we instead want add the non-restrict -> restrict check
in another spot (ssa_forward_propagate_and_combine) below.
Without that I'm afraid it is harder to disambiguate the accesses
(though, it still fails). Or should PTA be able to disambiguate
it even without the ssa_forward_propagate_and_combine hunk?
One store will be through p1 + variableoffset with PT { a, <restrict decl for
p1> } (restr)
and the other either with the hunk to p2 + constoffset with PT { a, <restrict
decl for p2> } (restr)
or without the hunk a + constoffset.
2011-09-30 Jakub Jelinek <[email protected]>
* fold-const.c (fold_unary_loc): Don't optimize
POINTER_PLUS_EXPR casted to TYPE_RESTRICT pointer by
casting the inner pointer if it isn't TYPE_RESTRICT.
* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Don't through
casts from non-TYPE_RESTRICT pointer to TYPE_RESTRICT pointer.
* gcc.dg/tree-ssa/restrict-4.c: New test.
* gcc.dg/tree-ssa/restrict-5.c: New test.
--- gcc/fold-const.c.jj 2011-09-29 14:25:46.000000000 +0200
+++ gcc/fold-const.c 2011-09-29 18:20:04.000000000 +0200
@@ -7929,6 +7929,7 @@ fold_unary_loc (location_t loc, enum tre
that this happens when X or Y is NOP_EXPR or Y is INTEGER_CST. */
if (POINTER_TYPE_P (type)
&& TREE_CODE (arg0) == POINTER_PLUS_EXPR
+ && (!TYPE_RESTRICT (type) || TYPE_RESTRICT (TREE_TYPE (arg0)))
&& (TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
|| TREE_CODE (TREE_OPERAND (arg0, 0)) == NOP_EXPR
|| TREE_CODE (TREE_OPERAND (arg0, 1)) == NOP_EXPR))
--- gcc/tree-ssa-forwprop.c.jj 2011-09-15 12:18:54.000000000 +0200
+++ gcc/tree-ssa-forwprop.c 2011-09-30 10:02:46.000000000 +0200
@@ -804,6 +804,10 @@ forward_propagate_addr_expr_1 (tree name
&& ((rhs_code == SSA_NAME && rhs == name)
|| CONVERT_EXPR_CODE_P (rhs_code)))
{
+ /* Don't propagate restrict pointer's RHS. */
+ if (TYPE_RESTRICT (TREE_TYPE (lhs))
+ && !TYPE_RESTRICT (TREE_TYPE (name)))
+ return false;
/* Only recurse if we don't deal with a single use or we cannot
do the propagation to the current statement. In particular
we can end up with a conversion needed for a non-invariant
@@ -2392,7 +2396,9 @@ ssa_forward_propagate_and_combine (void)
as well, as this is valid gimple. */
|| (CONVERT_EXPR_CODE_P (code)
&& TREE_CODE (rhs) == ADDR_EXPR
- && POINTER_TYPE_P (TREE_TYPE (lhs))))
+ && POINTER_TYPE_P (TREE_TYPE (lhs))
+ && (!TYPE_RESTRICT (TREE_TYPE (lhs))
+ || TYPE_RESTRICT (TREE_TYPE (rhs)))))
{
tree base = get_base_address (TREE_OPERAND (rhs, 0));
if ((!base
--- gcc/testsuite/gcc.dg/tree-ssa/restrict-4.c.jj 2011-09-29
20:21:00.000000000 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/restrict-4.c 2011-09-29 20:21:57.000000000
+0200
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int
+foo (int *x, int y)
+{
+ int *__restrict p1 = x;
+ int *__restrict p2 = x + 32;
+ p1[y] = 1;
+ p2[4] = 2;
+ return p1[y];
+}
+
+int
+bar (int *x, int y)
+{
+ int *__restrict p1 = x;
+ int *p3 = x + 32;
+ int *__restrict p2 = p3;
+ p1[y] = 1;
+ p2[4] = 2;
+ return p1[y];
+}
+
+/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
--- gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c.jj 2011-09-30
10:04:45.000000000 +0200
+++ gcc/testsuite/gcc.dg/tree-ssa/restrict-5.c 2011-09-30 10:05:11.000000000
+0200
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int a[64];
+
+int
+foo (int x)
+{
+ int *__restrict p1 = a + 4;
+ int *__restrict p2 = a + 16;
+ p1[x] = 1;
+ p2[2] = 2;
+ return p1[x];
+}
+
+/* { dg-final { scan-tree-dump-times "return 1;" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
Jakub