This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]