This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR22303, CCP not handling reads from constant strings
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: dnovillo at redhat dot com
- Date: Tue, 9 May 2006 14:33:41 +0200 (CEST)
- Subject: [PATCH] Fix PR22303, CCP not handling reads from constant strings
This fixes the PR by teaching fold_const_aggregate_ref about STRING_CSTs
and falling back to that if ccp_fold did not simplify the stmt.
Bootstrapped and tested on x86_64-unknown-linux-gnu.
Thanks,
Richard.
:ADDPATCH middle-end:
2006-05-08 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.
Index: tree-ssa-ccp.c
===================================================================
*** tree-ssa-ccp.c (revision 113628)
--- tree-ssa-ccp.c (working copy)
*************** fold_const_aggregate_ref (tree t)
*** 1011,1017 ****
}
if (ctor == NULL_TREE
! || TREE_CODE (ctor) != CONSTRUCTOR
|| !TREE_STATIC (ctor))
return NULL_TREE;
--- 1011,1018 ----
}
if (ctor == NULL_TREE
! || (TREE_CODE (ctor) != CONSTRUCTOR
! && TREE_CODE (ctor) != STRING_CST)
|| !TREE_STATIC (ctor))
return NULL_TREE;
*************** fold_const_aggregate_ref (tree t)
*** 1036,1041 ****
--- 1037,1056 ----
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))
*************** static prop_value_t
*** 1104,1110 ****
evaluate_stmt (tree stmt)
{
prop_value_t val;
! tree simplified;
ccp_lattice_t likelyvalue = likely_value (stmt);
val.mem_ref = NULL_TREE;
--- 1119,1125 ----
evaluate_stmt (tree stmt)
{
prop_value_t val;
! tree simplified = NULL_TREE;
ccp_lattice_t likelyvalue = likely_value (stmt);
val.mem_ref = NULL_TREE;
*************** evaluate_stmt (tree stmt)
*** 1115,1128 ****
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)
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
simplified = fold_const_aggregate_ref (get_rhs (stmt));
if (simplified && is_gimple_min_invariant (simplified))
--- 1130,1143 ----
simplified = ccp_fold (stmt);
/* If the statement is likely to have a VARYING result, then do not
bother folding the statement. */
! 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 if (!simplified)
simplified = fold_const_aggregate_ref (get_rhs (stmt));
if (simplified && is_gimple_min_invariant (simplified))
Index: testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c (revision 0)
--- testsuite/gcc.dg/tree-ssa/ssa-ccp-13.c (revision 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" } } */
+