From 66e8b99c2aa6f09af3151d972da33d15e09a8d75 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Tue, 30 Dec 2008 21:20:08 +0000
Subject: [PATCH] re PR tree-optimization/38645 (ICE with volatile)

2008-12-30  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/38645
	* tree-ssa-ccp.c (fold_gimple_assign): Use the correct pointer
	type.
	* tree-ssa-dom.c (cprop_operand): Simplify.  Do not propagate
	volatileness changing operands.

	* gcc.dg/pr38645.c: New testcase.

From-SVN: r142967
---
 gcc/ChangeLog                  |  8 +++++++
 gcc/testsuite/ChangeLog        |  5 +++++
 gcc/testsuite/gcc.dg/pr38645.c | 17 +++++++++++++++
 gcc/tree-ssa-ccp.c             | 17 +++++++++++----
 gcc/tree-ssa-dom.c             | 40 +++++++++-------------------------
 5 files changed, 53 insertions(+), 34 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/pr38645.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5d437b6c2762..d680ff7140d9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2008-12-30  Richard Guenther  <rguenther@suse.de>
+
+	PR tree-optimization/38645
+	* tree-ssa-ccp.c (fold_gimple_assign): Use the correct pointer
+	type.
+	* tree-ssa-dom.c (cprop_operand): Simplify.  Do not propagate
+	volatileness changing operands.
+
 2008-12-30  Steven Bosscher  <steven@gcc.gnu.org>
 
 	* tree-cfg.c (verify_eh_throw_stmt_node): Return nonzero,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 81e86b30a1cb..969273eab686 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2008-12-30  Richard Guenther  <rguenther@suse.de>
+
+	PR tree-optimization/38645
+	* gcc.dg/pr38645.c: New testcase.
+
 2008-12-30  Andrew Pinski  <pinskia@gmail.com>
 
 	PR middle-end/38661
diff --git a/gcc/testsuite/gcc.dg/pr38645.c b/gcc/testsuite/gcc.dg/pr38645.c
new file mode 100644
index 000000000000..3268f2ac6734
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr38645.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo()
+{
+  volatile int a[1];
+  int i, *p = (int*)a;
+
+  a[0] = 1;
+  for (i = 0; i < 1; ++i)
+    if (p[i])
+      return -1;
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump "a.0. ={v} 1;" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 0908d546f00b..d68337fc402a 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2720,10 +2720,19 @@ fold_gimple_assign (gimple_stmt_iterator *si)
     case GIMPLE_BINARY_RHS:
       /* Try to fold pointer addition.  */
       if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
-        result = maybe_fold_stmt_addition (
-                   TREE_TYPE (gimple_assign_lhs (stmt)),
-                   gimple_assign_rhs1 (stmt),
-                   gimple_assign_rhs2 (stmt));
+	{
+	  tree type = TREE_TYPE (gimple_assign_rhs1 (stmt));
+	  if (TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
+	    {
+	      type = build_pointer_type (TREE_TYPE (TREE_TYPE (type)));
+	      if (!useless_type_conversion_p
+		    (TREE_TYPE (gimple_assign_lhs (stmt)), type))
+		type = TREE_TYPE (gimple_assign_rhs1 (stmt));
+	    }
+	  result = maybe_fold_stmt_addition (type,
+					     gimple_assign_rhs1 (stmt),
+					     gimple_assign_rhs2 (stmt));
+	}
 
       if (!result)
         result = fold_binary (subcode,
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index bf2049eb8d8c..6d6d02bc3057 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -2045,8 +2045,6 @@ cprop_operand (gimple stmt, use_operand_p op_p)
   val = SSA_NAME_VALUE (op);
   if (val && val != op)
     {
-      tree op_type, val_type;
-
       /* Do not change the base variable in the virtual operand
 	 tables.  That would make it impossible to reconstruct
 	 the renamed virtual operand if we later modify this
@@ -2063,38 +2061,20 @@ cprop_operand (gimple stmt, use_operand_p op_p)
 	  && !may_propagate_copy_into_asm (op))
 	return false;
 
-      /* Get the toplevel type of each operand.  */
-      op_type = TREE_TYPE (op);
-      val_type = TREE_TYPE (val);
-
-      /* While both types are pointers, get the type of the object
-	 pointed to.  */
-      while (POINTER_TYPE_P (op_type) && POINTER_TYPE_P (val_type))
-	{
-	  op_type = TREE_TYPE (op_type);
-	  val_type = TREE_TYPE (val_type);
-	}
-
-      /* Make sure underlying types match before propagating a constant by
-	 converting the constant to the proper type.  Note that convert may
-	 return a non-gimple expression, in which case we ignore this
-	 propagation opportunity.  */
-      if (TREE_CODE (val) != SSA_NAME)
-	{
-	  if (!useless_type_conversion_p (op_type, val_type))
-	    {
-	      val = fold_convert (TREE_TYPE (op), val);
-	      if (!is_gimple_min_invariant (val))
-		return false;
-	    }
-	}
-
       /* Certain operands are not allowed to be copy propagated due
 	 to their interaction with exception handling and some GCC
 	 extensions.  */
-      else if (!may_propagate_copy (op, val))
+      if (!may_propagate_copy (op, val))
 	return false;
-      
+
+      /* Do not propagate addresses that point to volatiles into memory
+	 stmts without volatile operands.  */
+      if (POINTER_TYPE_P (TREE_TYPE (val))
+	  && TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (val)))
+	  && gimple_has_mem_ops (stmt)
+	  && !gimple_has_volatile_ops (stmt))
+	return false;
+
       /* Do not propagate copies if the propagated value is at a deeper loop
 	 depth than the propagatee.  Otherwise, this may move loop variant
 	 variables outside of their loops and prevent coalescing
-- 
GitLab