summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-08 11:38:43 +0000
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-08 11:38:43 +0000
commit16952c2cac969ef045f63fe18764b4f1d719eac5 (patch)
tree222d856bd4e364f7cc1df6fadbcc8ad5bb0f1728
parent2cb9ef3991e49cca727e9b9959820473d666016f (diff)
downloadgcc-16952c2cac969ef045f63fe18764b4f1d719eac5.tar.gz
2010-07-08 Richard Guenther <rguenther@suse.de>
PR tree-optimization/44831 * tree-ssa-phiprop.c (phiprop_insert_phi): Properly build a MEM_REF preserving TBAA info of the original dereference. Dereference the original pointer if the address is not invariant. (propagate_with_phi): Fixup type checks wrt MEM_REFs. Require at least one invariant address that we are going to dereference. * gcc.c-torture/compile/pr44831.c: New testcase. * gcc.dg/tree-ssa/pr21463.c: Adjust. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161950 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr44831.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr21463.c4
-rw-r--r--gcc/tree-ssa-phiprop.c40
5 files changed, 65 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0d84f29d587..db4f910397b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,15 @@
2010-07-08 Richard Guenther <rguenther@suse.de>
+ PR tree-optimization/44831
+ * tree-ssa-phiprop.c (phiprop_insert_phi): Properly build
+ a MEM_REF preserving TBAA info of the original dereference.
+ Dereference the original pointer if the address is not
+ invariant.
+ (propagate_with_phi): Fixup type checks wrt MEM_REFs. Require
+ at least one invariant address that we are going to dereference.
+
+2010-07-08 Richard Guenther <rguenther@suse.de>
+
PR tree-optimization/44861
* tree-vect-stmts.c (vectorizable_store): Preserve TBAA
information when building MEM_REFs.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d332dc4a960..eb8d5f1bc21 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2010-07-08 Richard Guenther <rguenther@suse.de>
+ PR tree-optimization/44831
+ * gcc.c-torture/compile/pr44831.c: New testcase.
+ * gcc.dg/tree-ssa/pr21463.c: Adjust.
+
+2010-07-08 Richard Guenther <rguenther@suse.de>
+
PR tree-optimization/44861
* g++.dg/vect/pr44861.cc: New testcase.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr44831.c b/gcc/testsuite/gcc.c-torture/compile/pr44831.c
new file mode 100644
index 00000000000..5539583deb0
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr44831.c
@@ -0,0 +1,15 @@
+typedef unsigned char UCHAR, *PUCHAR;
+typedef void *HANDLE;
+typedef struct _NCB {
+ UCHAR ncb_reserve[10];
+} NCB, *PNCB;
+struct NBCmdQueue {
+ PNCB head;
+};
+PNCB *NBCmdQueueFindNBC(struct NBCmdQueue *queue, PNCB ncb)
+{
+ PNCB *ret = &queue->head;
+ while (ret && *ret != ncb)
+ ret = (PNCB *)((*ret)->ncb_reserve + sizeof(HANDLE));
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr21463.c b/gcc/testsuite/gcc.dg/tree-ssa/pr21463.c
index f490bf61e5a..3f63cdd8e8c 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr21463.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr21463.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-phiprop" } */
+/* { dg-options "-O -fdump-tree-phiprop-details" } */
struct f
{
@@ -16,5 +16,5 @@ int g(int i, int c, struct f *ff, int g)
return *t;
}
-/* { dg-final { scan-tree-dump-not "\\*t" "phiprop" } } */
+/* { dg-final { scan-tree-dump-times "Inserting PHI for result of load" 1 "phiprop" } } */
/* { dg-final { cleanup-tree-dump "phiprop" } } */
diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
index 6595515e1ad..84f22b956ed 100644
--- a/gcc/tree-ssa-phiprop.c
+++ b/gcc/tree-ssa-phiprop.c
@@ -187,10 +187,17 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
}
else
{
+ tree rhs = gimple_assign_rhs1 (use_stmt);
gcc_assert (TREE_CODE (old_arg) == ADDR_EXPR);
- old_arg = TREE_OPERAND (old_arg, 0);
- new_var = create_tmp_reg (TREE_TYPE (old_arg), NULL);
- tmp = gimple_build_assign (new_var, unshare_expr (old_arg));
+ new_var = create_tmp_reg (TREE_TYPE (rhs), NULL);
+ if (!is_gimple_min_invariant (old_arg))
+ old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
+ else
+ old_arg = unshare_expr (old_arg);
+ tmp = gimple_build_assign (new_var,
+ fold_build2 (MEM_REF, TREE_TYPE (rhs),
+ old_arg,
+ TREE_OPERAND (rhs, 1)));
gcc_assert (is_gimple_reg (new_var));
add_referenced_var (new_var);
new_var = make_ssa_name (new_var, tmp);
@@ -246,6 +253,8 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
use_operand_p arg_p, use;
ssa_op_iter i;
bool phi_inserted;
+ tree type = NULL_TREE;
+ bool one_invariant = false;
if (!POINTER_TYPE_P (TREE_TYPE (ptr))
|| !is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr))))
@@ -268,16 +277,29 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
return false;
arg = gimple_assign_rhs1 (def_stmt);
}
- if ((TREE_CODE (arg) != ADDR_EXPR
- /* Avoid to have to decay *&a to a[0] later. */
- || !is_gimple_reg_type (TREE_TYPE (TREE_OPERAND (arg, 0))))
+ if (TREE_CODE (arg) != ADDR_EXPR
&& !(TREE_CODE (arg) == SSA_NAME
&& SSA_NAME_VERSION (arg) < n
&& phivn[SSA_NAME_VERSION (arg)].value != NULL_TREE
+ && (!type
+ || types_compatible_p
+ (type, TREE_TYPE (phivn[SSA_NAME_VERSION (arg)].value)))
&& phivn_valid_p (phivn, arg, bb)))
return false;
+ if (!type
+ && TREE_CODE (arg) == SSA_NAME)
+ type = TREE_TYPE (phivn[SSA_NAME_VERSION (arg)].value);
+ if (TREE_CODE (arg) == ADDR_EXPR
+ && is_gimple_min_invariant (arg))
+ one_invariant = true;
}
+ /* If we neither have an address of a decl nor can reuse a previously
+ inserted load, do not hoist anything. */
+ if (!one_invariant
+ && !type)
+ return false;
+
/* Find a dereferencing use. First follow (single use) ssa
copy chains for ptr. */
while (single_imm_use (ptr, &use, &use_stmt)
@@ -298,8 +320,9 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
&& gimple_assign_rhs_code (use_stmt) == MEM_REF
&& TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 0) == ptr
&& integer_zerop (TREE_OPERAND (gimple_assign_rhs1 (use_stmt), 1))
- && types_compatible_p (TREE_TYPE (gimple_assign_rhs1 (use_stmt)),
- TREE_TYPE (TREE_TYPE (ptr)))
+ && (!type
+ || types_compatible_p
+ (TREE_TYPE (gimple_assign_lhs (use_stmt)), type))
/* We cannot replace a load that may throw or is volatile. */
&& !stmt_can_throw_internal (use_stmt)))
continue;
@@ -319,6 +342,7 @@ propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn,
if (!phi_inserted)
{
res = phiprop_insert_phi (bb, phi, use_stmt, phivn, n);
+ type = TREE_TYPE (res);
/* Remember the value we created for *ptr. */
phivn[SSA_NAME_VERSION (ptr)].value = res;