I've just noticed that DOM doesn't handle if (x >= y) return 1;
if (y == x) abort (); in that it records y != x on the else edge but not !(y == x). The following fixes that. Bootstrap & regtest running on x86_64-unknown-linux-gnu. Richard. 2015-07-01 Richard Biener <rguent...@suse.de> * tree-ssa-dom.c (build_and_record_new_cond): Add optional parameter to record a condition that is false. (record_conditions): When recording an extra NE_EXPR that is true also record a EQ_EXPR that is false. * gcc.dg/tree-ssa/ssa-dom-cse-4.c: New testcase. Index: gcc/tree-ssa-dom.c =================================================================== *** gcc/tree-ssa-dom.c (revision 225225) --- gcc/tree-ssa-dom.c (working copy) *************** free_all_edge_infos (void) *** 813,819 **** static void build_and_record_new_cond (enum tree_code code, tree op0, tree op1, ! vec<cond_equivalence> *p) { cond_equivalence c; struct hashable_expr *cond = &c.cond; --- 813,820 ---- static void build_and_record_new_cond (enum tree_code code, tree op0, tree op1, ! vec<cond_equivalence> *p, ! bool val = true) { cond_equivalence c; struct hashable_expr *cond = &c.cond; *************** build_and_record_new_cond (enum tree_cod *** 826,832 **** cond->ops.binary.opnd0 = op0; cond->ops.binary.opnd1 = op1; ! c.value = boolean_true_node; p->safe_push (c); } --- 827,833 ---- cond->ops.binary.opnd0 = op0; cond->ops.binary.opnd1 = op1; ! c.value = val ? boolean_true_node : boolean_false_node; p->safe_push (c); } *************** record_conditions (struct edge_info *edg *** 865,870 **** --- 866,873 ---- op0, op1, &edge_info->cond_equivalences); build_and_record_new_cond (NE_EXPR, op0, op1, &edge_info->cond_equivalences); + build_and_record_new_cond (EQ_EXPR, op0, op1, + &edge_info->cond_equivalences, false); break; case GE_EXPR: Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-4.c =================================================================== --- gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-4.c (revision 0) +++ gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-4.c (revision 0) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-optimized" } */ + +extern void abort (void); + +unsigned int +foo (unsigned int x, unsigned int y) +{ + unsigned int z; + + if (x >= y) + return 1; + + if (y == x) + abort (); + + return 0; +} + +/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */