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" } } */

Reply via email to