From faaf14368b72d741b4ea5bcb6b8cb172fb847c43 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Tue, 16 May 2006 15:34:12 +0000
Subject: [PATCH] re PR tree-optimization/22303 (CCP does not handle
 STRING_CSTs)

2006-05-16  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/22303
	* tree-ssa-ccp.c (fold_const_aggregate_ref): Handle reads
	from STRING_CSTs.
	(evaluate_stmt): Fall back to fold_const_aggregate_ref, if
	ccp_fold did not simplify the statement.

	* gcc.dg/tree-ssa/ssa-ccp-13.c: New testcase.

From-SVN: r113826
---
 gcc/ChangeLog                              |  8 ++++++++
 gcc/testsuite/ChangeLog                    |  5 +++++
 gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c | 14 +++++++++++++
 gcc/tree-ssa-ccp.c                         | 23 ++++++++++++++++++----
 4 files changed, 46 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e5a58791f5ed..c7bfa59c0ec4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2006-05-16  Richard Guenther  <rguenther@suse.de>
+
+	PR tree-optimization/22303
+	* tree-ssa-ccp.c (fold_const_aggregate_ref): Handle reads
+	from STRING_CSTs.
+	(evaluate_stmt): Fall back to fold_const_aggregate_ref, if
+	ccp_fold did not simplify the statement.
+
 2006-05-16  H.J. Lu  <hongjiu.lu@intel.com>
 
 	PR driver/26885
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8e94d149213a..ec6b784ffd11 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-05-16  Richard Guenther  <rguenther@suse.de>
+
+	PR tree-optimization/22303
+	* gcc.dg/tree-ssa/ssa-ccp-13.c: New testcase.
+
 2006-05-16  Jakub Jelinek  <jakub@redhat.com>
 
 	PR middle-end/27573
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c
new file mode 100644
index 000000000000..d35adee514d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+static const char f[3] = "?";
+
+int foo()
+{
+  int i = 0;
+  return f[i] != '?';
+}
+
+/* { dg-final { scan-tree-dump "return 0;" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 83dce72770b1..53050e68429a 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -1011,7 +1011,8 @@ fold_const_aggregate_ref (tree t)
 	}
 
       if (ctor == NULL_TREE
-	  || TREE_CODE (ctor) != CONSTRUCTOR
+	  || (TREE_CODE (ctor) != CONSTRUCTOR
+	      && TREE_CODE (ctor) != STRING_CST)
 	  || !TREE_STATIC (ctor))
 	return NULL_TREE;
 
@@ -1036,6 +1037,20 @@ fold_const_aggregate_ref (tree t)
 	  return NULL_TREE;
 	}
 
+      /* Fold read from constant string.  */
+      if (TREE_CODE (ctor) == STRING_CST)
+	{
+	  if ((TYPE_MODE (TREE_TYPE (t))
+	       == TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor))))
+	      && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor))))
+	          == MODE_INT)
+	      && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor)))) == 1
+	      && compare_tree_int (idx, TREE_STRING_LENGTH (ctor)) < 0)
+	    return build_int_cst (TREE_TYPE (t), (TREE_STRING_POINTER (ctor)
+					          [TREE_INT_CST_LOW (idx)]));
+	  return NULL_TREE;
+	}
+
       /* Whoo-hoo!  I'll fold ya baby.  Yeah!  */
       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
 	if (tree_int_cst_equal (cfield, idx))
@@ -1104,7 +1119,7 @@ static prop_value_t
 evaluate_stmt (tree stmt)
 {
   prop_value_t val;
-  tree simplified;
+  tree simplified = NULL_TREE;
   ccp_lattice_t likelyvalue = likely_value (stmt);
 
   val.mem_ref = NULL_TREE;
@@ -1115,14 +1130,14 @@ evaluate_stmt (tree stmt)
     simplified = ccp_fold (stmt);
   /* If the statement is likely to have a VARYING result, then do not
      bother folding the statement.  */
-  else if (likelyvalue == VARYING)
+  if (likelyvalue == VARYING)
     simplified = get_rhs (stmt);
   /* If the statement is an ARRAY_REF or COMPONENT_REF into constant
      aggregates, extract the referenced constant.  Otherwise the
      statement is likely to have an UNDEFINED value, and there will be
      nothing to do.  Note that fold_const_aggregate_ref returns
      NULL_TREE if the first case does not match.  */
-  else
+  else if (!simplified)
     simplified = fold_const_aggregate_ref (get_rhs (stmt));
 
   if (simplified && is_gimple_min_invariant (simplified))
-- 
GitLab