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 <[email protected]>
* 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" } } */