Hi!

The following testcase ICEs, because ranges[i].exp is x < y
with boolean type, but (*ops)[ranges[i].idx] is that result cast
to int and the code didn't take into account possible casts that
init_range_entry looks through.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

2016-10-11  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/77929
        * tree-ssa-reassoc.c (optimize_range_tests_var_bound): Handle
        (*ops)[ranges[i].idx]->op != ranges[i].exp case.

        * gcc.c-torture/compile/pr77929.c: New test.

--- gcc/tree-ssa-reassoc.c.jj   2016-10-09 13:18:21.000000000 +0200
+++ gcc/tree-ssa-reassoc.c      2016-10-11 13:28:08.406340143 +0200
@@ -2994,12 +2994,26 @@ optimize_range_tests_var_bound (enum tre
        }
       else
        {
-         g = gimple_build_assign (make_ssa_name (TREE_TYPE (ranges[i].exp)),
-                                  ccode, rhs1, rhs2);
+         operand_entry *oe = (*ops)[ranges[i].idx];
+         tree ctype = oe->op ? TREE_TYPE (oe->op) : boolean_type_node;
+         if (!INTEGRAL_TYPE_P (ctype)
+             || (TREE_CODE (ctype) != BOOLEAN_TYPE
+                 && TYPE_PRECISION (ctype) != 1))
+           ctype = boolean_type_node;
+         g = gimple_build_assign (make_ssa_name (ctype), ccode, rhs1, rhs2);
          gimple_set_uid (g, uid);
          gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+         if (oe->op && ctype != TREE_TYPE (oe->op))
+           {
+             g = gimple_build_assign (make_ssa_name (TREE_TYPE (oe->op)),
+                                      NOP_EXPR, gimple_assign_lhs (g));
+             gimple_set_uid (g, uid);
+             gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+           }
          ranges[i].exp = gimple_assign_lhs (g);
-         (*ops)[ranges[i].idx]->op = ranges[i].exp;
+         oe->op = ranges[i].exp;
+         ranges[i].low = build_zero_cst (TREE_TYPE (ranges[i].exp));
+         ranges[i].high = ranges[i].low;
        }
       ranges[i].strict_overflow_p = false;
       operand_entry *oe = (*ops)[ranges[*idx].idx];
--- gcc/testsuite/gcc.c-torture/compile/pr77929.c.jj    2016-10-11 
14:00:07.840653109 +0200
+++ gcc/testsuite/gcc.c-torture/compile/pr77929.c       2016-10-11 
13:59:51.000000000 +0200
@@ -0,0 +1,13 @@
+/* PR tree-optimization/77929 */
+
+void bar (void);
+
+void
+foo (int x, unsigned short int y)
+{
+  int a = 0;
+  int b = (y != 0) ? (x < y) : (a < 0);
+
+  if (x >= 0 & b)
+    bar ();
+}

        Jakub

Reply via email to