This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR41428, CCP not folding conditionals properly
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 22 Sep 2009 10:33:38 +0200 (CEST)
- Subject: [PATCH] Fix PR41428, CCP not folding conditionals properly
This fixes the cases where CCP during propagation notices that a
condition folds to true or false but propagating the constants necessary
to perform the folding during substitute_and_fold is not possible due
to type compatibility problems.
The solution is to provide a CCP specific folder similar to VRP that
handles this case specially.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
2009-09-22 Richard Guenther <rguenther@suse.de>
PR tree-optimization/41428
* tree-ssa-ccp.c (ccp_fold_stmt): New function.
(ccp_finalize): Pass it to substitute_and_fold.
* g++.dg/tree-ssa/pr41428.C: New testcase.
Index: trunk/gcc/testsuite/g++.dg/tree-ssa/pr41428.C
===================================================================
*** /dev/null 1970-01-01 00:00:00.000000000 +0000
--- trunk/gcc/testsuite/g++.dg/tree-ssa/pr41428.C 2009-09-21 17:18:01.000000000 +0200
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-ccp1-details" } */
+
+ extern "C" void abort (void);
+ inline void *operator new (__SIZE_TYPE__, void *__p) throw () { return __p; }
+
+ int foo(void)
+ {
+ float f = 0;
+ int *i = new (&f) int (1);
+ return *(int *)&f;
+ }
+
+ /* { dg-final { scan-tree-dump "Folded into: if \\\(1 != 0\\\)" "ccp1" } } */
+ /* { dg-final { cleanup-tree-dump "ccp1" } } */
Index: trunk/gcc/tree-ssa-ccp.c
===================================================================
*** trunk.orig/gcc/tree-ssa-ccp.c 2009-09-21 16:35:00.000000000 +0200
--- trunk/gcc/tree-ssa-ccp.c 2009-09-21 17:15:52.000000000 +0200
*************** typedef enum
*** 229,234 ****
--- 229,235 ----
static prop_value_t *const_val;
static void canonicalize_float_value (prop_value_t *);
+ static bool ccp_fold_stmt (gimple_stmt_iterator *);
/* Dump constant propagation value VAL to file OUTF prefixed by PREFIX. */
*************** ccp_finalize (void)
*** 724,730 ****
do_dbg_cnt ();
/* Perform substitutions based on the known constant values. */
! something_changed = substitute_and_fold (const_val, NULL);
free (const_val);
const_val = NULL;
--- 725,731 ----
do_dbg_cnt ();
/* Perform substitutions based on the known constant values. */
! something_changed = substitute_and_fold (const_val, ccp_fold_stmt);
free (const_val);
const_val = NULL;
*************** evaluate_stmt (gimple stmt)
*** 1472,1477 ****
--- 1473,1506 ----
return val;
}
+ /* Fold the stmt at *GSI with CCP specific information that propagating
+ and regular folding does not catch. */
+
+ static bool
+ ccp_fold_stmt (gimple_stmt_iterator *gsi)
+ {
+ gimple stmt = gsi_stmt (*gsi);
+ prop_value_t val;
+
+ if (gimple_code (stmt) != GIMPLE_COND)
+ return false;
+
+ /* Statement evaluation will handle type mismatches in constants
+ more gracefully than the final propagation. This allows us to
+ fold more conditionals here. */
+ val = evaluate_stmt (stmt);
+ if (val.lattice_val != CONSTANT
+ || TREE_CODE (val.value) != INTEGER_CST)
+ return false;
+
+ if (integer_zerop (val.value))
+ gimple_cond_make_false (stmt);
+ else
+ gimple_cond_make_true (stmt);
+
+ return true;
+ }
+
/* Visit the assignment statement STMT. Set the value of its LHS to the
value computed by the RHS and store LHS in *OUTPUT_P. If STMT
creates virtual definitions, set the value of each new name to that