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]

Re: [PATCH] Fix PR37795




Sent from my iPhone

On Oct 12, 2008, at 11:50 AM, Richard Guenther <rguenther@suse.de> wrote:


This fixes PR37795, a missed optimization with optimizing consecutive (and-ed) tests as we already do for or-ed ones.

Does this do the correct thing for floating point comparisons? That is it if we had a >= b and b < a does not change as NaN would give true and the false.

Thanks,
Andrew Pinski


Bootstrapped and tested on x86_64-unknown-linux-gnu, queued for 4.5.

Richard.


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


   PR tree-optimization/37795
   * tree-ssa-ifcombine.c (ifcombine_ifandif): Optimize two successive
   comparisons.

* gcc.dg/tree-ssa/ssa-ifcombine-7.c: New testcase.

Index: gcc/tree-ssa-ifcombine.c
===================================================================
*** gcc/tree-ssa-ifcombine.c    (revision 141074)
--- gcc/tree-ssa-ifcombine.c    (working copy)
*************** ifcombine_ifandif (basic_block inner_con
*** 380,385 ****
--- 380,441 ----
       return true;
     }

+ /* See if we have two comparisons that we can merge into one. */
+ else if (TREE_CODE_CLASS (gimple_cond_code (inner_cond)) == tcc_comparison
+ && TREE_CODE_CLASS (gimple_cond_code (outer_cond)) == tcc_comparison
+ && operand_equal_p (gimple_cond_lhs (inner_cond),
+ gimple_cond_lhs (outer_cond), 0)
+ && operand_equal_p (gimple_cond_rhs (inner_cond),
+ gimple_cond_rhs (outer_cond), 0))
+ {
+ enum tree_code code1 = gimple_cond_code (inner_cond);
+ enum tree_code code2 = gimple_cond_code (outer_cond);
+ enum tree_code code;
+ tree t;
+
+ #define CHK(a,b) ((code1 == a ## _EXPR && code2 == b ## _EXPR) \
+ || (code2 == a ## _EXPR && code1 == b ## _EXPR))
+ /* Merge the two condition codes if possible. */
+ if (code1 == code2)
+ code = code1;
+ else if (CHK (EQ, LE))
+ code = EQ_EXPR;
+ else if (CHK (EQ, GE))
+ code = EQ_EXPR;
+ else if (CHK (NE, LE))
+ code = LT_EXPR;
+ else if (CHK (NE, GE))
+ code = GT_EXPR;
+ else if (CHK (LE, GE))
+ code = EQ_EXPR;
+ /* We could check for combinations leading to trivial true/ false. */
+ else
+ return false;
+ #undef CHK
+
+ /* Do it. */
+ t = fold_build2 (code, boolean_type_node, gimple_cond_lhs (outer_cond),
+ gimple_cond_rhs (outer_cond));
+ t = canonicalize_cond_expr_cond (t);
+ if (!t)
+ return false;
+ gimple_cond_set_condition_from_tree (inner_cond, t);
+ update_stmt (inner_cond);
+
+ /* Leave CFG optimization to cfg_cleanup. */
+ gimple_cond_set_condition_from_tree (outer_cond, boolean_true_node);
+ update_stmt (outer_cond);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "optimizing two comparisons to ");
+ print_generic_expr (dump_file, t, 0);
+ fprintf (dump_file, "\n");
+ }
+
+ return true;
+ }
+
return false;
}


Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-7.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-7.c    (revision 0)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-ifcombine-7.c    (revision 0)
***************
*** 0 ****
--- 1,15 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-optimized" } */
+
+ int test1 (int i, int j)
+ {
+   if (i >= j)
+     if (i != j)
+       return 0;
+   return -1;
+ }
+
+ /* The above should be optimized to a i > j test by ifcombine.  */
+
+ /* { dg-final { scan-tree-dump " > " "optimized" } } */
+ /* { dg-final { cleanup-tree-dump "optimized" } } */


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