+2018-12-19 Alexandre Oliva <aoliva@redhat.com>
+
+ PR testsuite/86153
+ PR middle-end/83239
+ * vr-values.c
+ (vr_values::vrp_evaluate_conditional_warnv_with_ops): Extend
+ simplification of overflow tests to cover cases in which we
+ can determine the result of the comparison.
+
2018-12-19 Bin Cheng <bin.cheng@linux.alibaba.com>
* auto-profile.c (afdo_indirect_call): Skip generating histogram
--- /dev/null
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-tree-forwprop" } */
+
+extern void __attribute__((noreturn)) unreachable (void);
+
+int fle22 (int a)
+{
+ unsigned i = a / 4;
+ unsigned j = i - 2;
+
+ if (j == 7) /* A dynamic range excludes a value from j for the rest of f1. */
+ return -1;
+
+ if (i <= 2) /* This dynamic range cannot be combined or compared with that of j. */
+ return 0;
+
+ if (i <= j) /* And so we couldn't compute this result. */
+ unreachable ();
+
+ return 1;
+}
+
+int fle32 (int a)
+{
+ unsigned i = a / 4;
+ unsigned j = i - 3;
+
+ if (j == 7) /* A dynamic range excludes a value from j for the rest of f1. */
+ return -1;
+
+ if (i <= 2) /* This dynamic range cannot be combined or compared with that of j. */
+ return 0;
+
+ if (i <= j) /* And so we couldn't compute this result. */
+ unreachable ();
+
+ return 1;
+}
+
+int flt22 (int a)
+{
+ unsigned i = a / 4;
+ unsigned j = i - 2;
+
+ if (j == 7)
+ return -1;
+
+ if (i <= 2)
+ return 0;
+
+ if (i < j)
+ unreachable ();
+
+ return 1;
+}
+
+int flt32 (int a)
+{
+ unsigned i = a / 4;
+ unsigned j = i - 3;
+
+ if (j == 7)
+ return -1;
+
+ if (i <= 2)
+ return 0;
+
+ if (i < j)
+ unreachable ();
+
+ return 1;
+}
+
+int fgt22 (int a)
+{
+ unsigned i = a / 4;
+ unsigned j = i + 2;
+
+ if (j == -7)
+ return -1;
+
+ if (i >= -3)
+ return 0;
+
+ if (i > j)
+ unreachable ();
+
+ return 1;
+}
+
+int fgt32 (int a)
+{
+ unsigned i = a / 4;
+ unsigned j = i + 3;
+
+ if (j == -7)
+ return -1;
+
+ if (i >= -3)
+ return 0;
+
+ if (i > j)
+ unreachable ();
+
+ return 1;
+}
+
+int fge22 (int a)
+{
+ unsigned i = a / 4;
+ unsigned j = i + 2;
+
+ if (j == -7)
+ return -1;
+
+ if (i >= -3)
+ return 0;
+
+ if (i >= j)
+ unreachable ();
+
+ return 1;
+}
+
+int fge32 (int a)
+{
+ unsigned i = a / 4;
+ unsigned j = i + 3;
+
+ if (j == -7)
+ return -1;
+
+ if (i >= -3)
+ return 0;
+
+ if (i >= j)
+ unreachable ();
+
+ return 1;
+}
+
+int main (int argc, char *argv[]) {
+ fle22 (argc);
+ fle32 (argc);
+ flt22 (argc);
+ flt32 (argc);
+ fgt22 (argc);
+ fgt32 (argc);
+ fge22 (argc);
+ fge32 (argc);
+}
op1 = wide_int_to_tree (TREE_TYPE (op0), 0);
code = (code == GT_EXPR || code == GE_EXPR) ? EQ_EXPR : NE_EXPR;
}
+ else
+ {
+ value_range vro, vri;
+ if (code == GT_EXPR || code == GE_EXPR)
+ {
+ vro.set (VR_ANTI_RANGE, TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
+ vri.set (VR_RANGE, TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
+ }
+ else if (code == LT_EXPR || code == LE_EXPR)
+ {
+ vro.set (VR_RANGE, TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
+ vri.set (VR_ANTI_RANGE, TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
+ }
+ else
+ gcc_unreachable ();
+ value_range *vr0 = get_value_range (op0);
+ /* If vro, the range for OP0 to pass the overflow test, has
+ no intersection with *vr0, OP0's known range, then the
+ overflow test can't pass, so return the node for false.
+ If it is the inverted range, vri, that has no
+ intersection, then the overflow test must pass, so return
+ the node for true. In other cases, we could proceed with
+ a simplified condition comparing OP0 and X, with LE_EXPR
+ for previously LE_ or LT_EXPR and GT_EXPR otherwise, but
+ the comments next to the enclosing if suggest it's not
+ generally profitable to do so. */
+ vro.intersect (vr0);
+ if (vro.undefined_p ())
+ return boolean_false_node;
+ vri.intersect (vr0);
+ if (vri.undefined_p ())
+ return boolean_true_node;
+ }
}
if ((ret = vrp_evaluate_conditional_warnv_with_ops_using_ranges