This mirrors a fix that was made to DOM a while back. Essentially we've got a test of a boolean ranged object against a value outside the range of a boolean. That's not correctly handled by uncprop at the moment, and is fixed by this patch.

There's clearly a missed optimization there (and I'll file a separate bug for that). But even so, uncprop should handle that case gracefully.

Bootstrapped and regression tested on x86-64-linux-gnu. Installed on the trunk.

Jeff
commit e1c1832e8e5d338b1b4357be0dcf98cadeda9b2e
Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Tue Mar 1 00:04:48 2016 +0000

        PR tree-optimization/70005
        * tree-ssa-uncprop.c (associate_equivalences_with_edges): Handle case
        where an object with a boolean range is compared against a value
        outside [0..1].
    
        PR tree-optimization/70005
        * gcc.c-torture/execute/pr70005.c New test.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233829 
138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 653b51e..ccbcfe8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,10 @@
 2016-02-28  Jeff Law  <l...@redhat.com>
 
+       PR tree-optimization/70005
+       * tree-ssa-uncprop.c (associate_equivalences_with_edges): Handle case
+       where an object with a boolean range is compared against a value
+       outside [0..1].
+
        PR tree-optimization/69999
        * gimple-ssa-split-paths.c (split_paths): When duplicating a block
        with an outgoing edge marked with EDGE_IRREDUCIBLE_LOOP, schedule
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 49577ee..3743d34 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
 2016-02-29  Jeff Law  <l...@redhat.com>
 
+       PR tree-optimization/70005
+       * gcc.c-torture/execute/pr70005.c New test.
+
        PR tree-optimization/69999
        * gcc.c-torture/compile/pr69999.c: New test.
 
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr70005.c 
b/gcc/testsuite/gcc.c-torture/execute/pr70005.c
new file mode 100644
index 0000000..bc37efe
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr70005.c
@@ -0,0 +1,25 @@
+
+unsigned char a = 6;
+int b, c;
+
+static void
+fn1 ()
+{
+  int i = a > 1 ? 1 : a, j = 6 & (c = a && (b = a));
+  int d = 0, e = a, f = ~c, g = b || a;
+  unsigned char h = ~a;
+  if (a)
+    f = j;
+  if (h && g)
+    d = a;
+  i = -~(f * d * h) + c && (e || i) ^ f;
+  if (i != 1) 
+    __builtin_abort (); 
+}
+
+int
+main ()
+{
+  fn1 ();
+  return 0; 
+}
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 307bb1f..e2e8212 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -95,7 +95,8 @@ associate_equivalences_with_edges (void)
              if (TREE_CODE (op0) == SSA_NAME
                  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op0)
                  && ssa_name_has_boolean_range (op0)
-                 && is_gimple_min_invariant (op1))
+                 && is_gimple_min_invariant (op1)
+                 && (integer_zerop (op1) || integer_onep (op1)))
                {
                  tree true_val = constant_boolean_node (true, TREE_TYPE (op0));
                  tree false_val = constant_boolean_node (false,

Reply via email to