aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 77c3014..41c870f 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3067,6 +3067,24 @@ extract_range_from_binary_expr_1 (value_range *vr,
if (int_cst_range1 && tree_int_cst_sgn (vr1.min) >= 0)
wmax = wi::min (wmax, vr1.max, TYPE_SIGN (expr_type));
max = wide_int_to_tree (expr_type, wmax);
+ cmp = compare_values (min, max);
+ /* PR68217: In case of signed & sign-bit-CST should
+ result in [-INF, 0] instead of [-INF, INF]. */
+ if (cmp == -2 || cmp == 1)
+ {
+ wide_int sign_bit
+ = wi::set_bit_in_zero (TYPE_PRECISION (expr_type) - 1,
+ TYPE_PRECISION (expr_type));
+ if (!TYPE_UNSIGNED (expr_type)
+ && ((value_range_constant_singleton (&vr0)
+ && !wi::cmps (vr0.min, sign_bit))
+ || (value_range_constant_singleton (&vr1)
+ && !wi::cmps (vr1.min, sign_bit))))
+ {
+ min = TYPE_MIN_VALUE (expr_type);
+ max = build_int_cst (expr_type, 0);
+ }
+ }
}
else if (code == BIT_IOR_EXPR)
{