Hi! As discussed in the PR, these routines happily look through PHI nodes into previous loop iteration. f is initialized in the previous loop iteration with f_10 = d_6 == 3; and in the current iteration there is f_2 != 0 && d_6 == 4 test. As we look through # f_2 = PHI <0(2), f_10(6)> PHI, this is evaluated as 0 != 0 && d_6 == 4 (which is correctly false) and (d_6 == 3) != 0 && d_6 == 4 (this one is false due to d_6 being from one iteration in one case and next one in another case). The following patch fixes it, bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk/4.6?
2011-05-20 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/49073 * gimple-fold.c (and_comparisons_1, or_comparisons_1): Return NULL if PHI argument is SSA_NAME, whose def_stmt is dominated by the PHI. * tree-ssa-ifcombine.c (tree_ssa_ifcombine): Calculate dominators. * gcc.c-torture/execute/pr49073.c: New test. --- gcc/gimple-fold.c.jj 2011-05-11 19:39:04.000000000 +0200 +++ gcc/gimple-fold.c 2011-05-20 11:05:11.000000000 +0200 @@ -1,5 +1,5 @@ /* Statement simplification on GIMPLE. - Copyright (C) 2010 Free Software Foundation, Inc. + Copyright (C) 2010, 2011 Free Software Foundation, Inc. Split out from tree-ssa-ccp.c. This file is part of GCC. @@ -2278,8 +2278,19 @@ and_comparisons_1 (enum tree_code code1, } else if (TREE_CODE (arg) == SSA_NAME) { - tree temp = and_var_with_comparison (arg, invert, - code2, op2a, op2b); + tree temp; + gimple def_stmt = SSA_NAME_DEF_STMT (arg); + /* In simple cases we can look through PHI nodes, + but we have to be careful with loops. + See PR49073. */ + if (! dom_info_available_p (CDI_DOMINATORS) + || gimple_bb (def_stmt) == gimple_bb (stmt) + || dominated_by_p (CDI_DOMINATORS, + gimple_bb (def_stmt), + gimple_bb (stmt))) + return NULL_TREE; + temp = and_var_with_comparison (arg, invert, code2, + op2a, op2b); if (!temp) return NULL_TREE; else if (!result) @@ -2728,8 +2739,19 @@ or_comparisons_1 (enum tree_code code1, } else if (TREE_CODE (arg) == SSA_NAME) { - tree temp = or_var_with_comparison (arg, invert, - code2, op2a, op2b); + tree temp; + gimple def_stmt = SSA_NAME_DEF_STMT (arg); + /* In simple cases we can look through PHI nodes, + but we have to be careful with loops. + See PR49073. */ + if (! dom_info_available_p (CDI_DOMINATORS) + || gimple_bb (def_stmt) == gimple_bb (stmt) + || dominated_by_p (CDI_DOMINATORS, + gimple_bb (def_stmt), + gimple_bb (stmt))) + return NULL_TREE; + temp = or_var_with_comparison (arg, invert, code2, + op2a, op2b); if (!temp) return NULL_TREE; else if (!result) --- gcc/tree-ssa-ifcombine.c.jj 2011-05-20 08:14:08.000000000 +0200 +++ gcc/tree-ssa-ifcombine.c 2011-05-20 11:37:24.000000000 +0200 @@ -1,5 +1,5 @@ /* Combining of if-expressions on trees. - Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Contributed by Richard Guenther <rguent...@suse.de> This file is part of GCC. @@ -625,6 +625,7 @@ tree_ssa_ifcombine (void) int i; bbs = blocks_in_phiopt_order (); + calculate_dominance_info (CDI_DOMINATORS); for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i) { --- gcc/testsuite/gcc.c-torture/execute/pr49073.c.jj 2011-05-20 11:38:58.000000000 +0200 +++ gcc/testsuite/gcc.c-torture/execute/pr49073.c 2011-05-20 11:37:40.000000000 +0200 @@ -0,0 +1,26 @@ +/* PR tree-optimization/49073 */ + +extern void abort (void); +int a[] = { 1, 2, 3, 4, 5, 6, 7 }, c; + +int +main () +{ + int d = 1, i = 1; + _Bool f = 0; + do + { + d = a[i]; + if (f && d == 4) + { + ++c; + break; + } + i++; + f = (d == 3); + } + while (d < 7); + if (c != 1) + abort (); + return 0; +} Jakub