+2008-05-05 Andrew Pinski <Andrew.Pinski@playstation.sony.com>
+
+ * tree-ssa-forwprop.c (forward_propagate_addr_expr_1): If we have the
+ same size types for the indirect reference on the rhs, then create a VCE.
+
2008-05-05 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md
+2008-05-05 Andrew Pinski <andrew.pinski@playstation.sony.com>
+
+ * gcc.dg/tree-ssa/forwprop-5.c: New testcase.
+ * gcc.dg/tree-ssa/forwprop-6.c: New testcase.
+ * gcc.dg/tree-ssa/forwprop-7.c: New testcase.
+ * gcc.dg/tree-ssa/forwprop-8.c: New testcase.
+ * gcc.dg/tree-ssa/forwprop-9.c: New testcase.
+
2008-05-05 Ira Rosen <irar@il.ibm.com>
PR tree-optimization/36119
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-forwprop1 -w" } */
+
+#define vector __attribute__((vector_size(16) ))
+struct VecClass
+{
+ vector float v;
+};
+
+vector float foo( vector float v )
+{
+ vector float x = v;
+ x = x + x;
+ struct VecClass y = *(struct VecClass*)&x;
+ return y.v;
+}
+
+/* We should be able to convert the cast to a VCE in forwprop1. */
+/* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 1 "forwprop1"} } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
+
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1 -W -Wall" } */
+
+
+int b;
+void f(void)
+{
+ float a;
+ a = 1;
+ b = *(int*)&a; /* { dg-warning "aliasing" } */
+}
+
+/* We should be able to convert the cast to a VCE in forwprop1,
+ even if there is an aliasing violation. */
+/* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 1 "forwprop1"} } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-forwprop1 -W -Wall" } */
+
+int i;
+int foo(void)
+{
+ volatile int *p = (volatile int *)&i;
+ return *p + *p;
+}
+
+/* We should not convert the cast to a VCE in forwprop1 as we have a volatile reference. */
+/* { dg-final { scan-tree-dump-times "VIEW_CONVERT_EXPR" 0 "forwprop1"} } */
+/* { dg-final { scan-tree-dump-times "volatile int" 2 "forwprop1"} } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-forwprop1 -W -Wall" } */
+
+
+struct X { int a[5]; };
+int foo(struct X *q)
+{
+ int (*pointer)[5] = &q->a;
+ return (*pointer)[0];
+}
+
+
+/* We should have propragated &q->a into (*pointer). */
+/* { dg-final { scan-tree-dump-times "pointer" 0 "forwprop1"} } */
+/* { dg-final { scan-tree-dump "->a\\\[0\\\]" "forwprop1" } } */
+/* { dg-final { cleanup-tree-dump "forwprop1" } } */
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-tree-final_cleanup -W -Wall -fno-early-inlining" } */
+
+
+int b;
+unsigned a;
+static inline int *g(void)
+{
+ a = 1;
+ return (int*)&a;
+}
+void f(void)
+{
+ b = *g();
+}
+/* We should have converted the assignments to two = 1. */
+/* { dg-final { scan-tree-dump-times " = 1" 2 "final_cleanup"} } */
+/* { dg-final { cleanup-tree-dump "final_cleanup" } } */
res = x->y->z;
+ Or
+ ptr = (type1*)&type2var;
+ res = *ptr
+
+ Will get turned into (if type1 and type2 are the same size
+ and neither have volatile on them):
+ res = VIEW_CONVERT_EXPR<type1>(type2var)
+
Or
ptr = &x[0];
return true;
}
+ /* Now see if the RHS node is an INDIRECT_REF using NAME. If so,
+ propagate the ADDR_EXPR into the use of NAME and try to
+ create a VCE and fold the result. */
+ if (TREE_CODE (rhs) == INDIRECT_REF
+ && TREE_OPERAND (rhs, 0) == name
+ && TYPE_SIZE (TREE_TYPE (rhs))
+ && TYPE_SIZE (TREE_TYPE (TREE_OPERAND (def_rhs, 0)))
+ /* We should not convert volatile loads to non volatile loads. */
+ && !TYPE_VOLATILE (TREE_TYPE (rhs))
+ && !TYPE_VOLATILE (TREE_TYPE (TREE_OPERAND (def_rhs, 0)))
+ && operand_equal_p (TYPE_SIZE (TREE_TYPE (rhs)),
+ TYPE_SIZE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))), 0))
+ {
+ bool res = true;
+ tree new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
+ new_rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), new_rhs);
+ /* If we have folded the VCE, then we have to create a new statement. */
+ if (TREE_CODE (new_rhs) != VIEW_CONVERT_EXPR)
+ {
+ block_stmt_iterator bsi = bsi_for_stmt (use_stmt);
+ new_rhs = force_gimple_operand_bsi (&bsi, new_rhs, true, NULL, true, BSI_SAME_STMT);
+ /* As we change the deference to a SSA_NAME, we need to return false to make sure that
+ the statement does not get removed. */
+ res = false;
+ }
+ *rhsp = new_rhs;
+ fold_stmt_inplace (use_stmt);
+ tidy_after_forward_propagate_addr (use_stmt);
+ return res;
+ }
+
/* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there
is nothing to do. */
if (TREE_CODE (rhs) != POINTER_PLUS_EXPR