diff mbox

[RFC,PR68217] Improve value range for signed & sign-bit-CST

Message ID 5710C60B.2080308@linaro.org
State New
Headers show

Commit Message

Kugan Vivekanandarajah April 15, 2016, 10:44 a.m. UTC
As pointed out by Richard, for signed & sign-bit-CST value range should 
be [-INF, 0] range, not a [-INF, INF] range as happens now.

This patch fixes this. I bootstrapped and regression tested for 
x86-64-linux-gnu with no new regression. Is this OK for statege-1.

Thanks,
Kugan


gcc/ChangeLog:

2016-04-14  Kugan Vivekanandarajah  <kuganv@linaro.org>

	PR middle-end/68217
	* tree-vrp.c (extract_range_from_binary_expr_1): In case of signed & 
sign-bit-CST,
	 generate [-INF, 0] instead of [-INF, INF].


gcc/testsuite/ChangeLog:

2016-04-14  Kugan Vivekanandarajah  <kuganv@linaro.org>

	PR middle-end/68217
	* gcc.dg/pr68217.c: New test.

Comments

Richard Biener April 26, 2016, 2:14 p.m. UTC | #1
On Fri, Apr 15, 2016 at 12:44 PM, kugan
<kugan.vivekanandarajah@linaro.org> wrote:
> As pointed out by Richard, for signed & sign-bit-CST value range should be
> [-INF, 0] range, not a [-INF, INF] range as happens now.
>
> This patch fixes this. I bootstrapped and regression tested for
> x86-64-linux-gnu with no new regression. Is this OK for statege-1.

I think you need to check vr0 for singleton-constant == sign_bit as well,
there is nothing that canonicalizes this during propagation.

Otherwise ok.

Thanks,
Richard.

> Thanks,
> Kugan
>
>
> gcc/ChangeLog:
>
> 2016-04-14  Kugan Vivekanandarajah  <kuganv@linaro.org>
>
>         PR middle-end/68217
>         * tree-vrp.c (extract_range_from_binary_expr_1): In case of signed &
> sign-bit-CST,
>          generate [-INF, 0] instead of [-INF, INF].
>
>
> gcc/testsuite/ChangeLog:
>
> 2016-04-14  Kugan Vivekanandarajah  <kuganv@linaro.org>
>
>         PR middle-end/68217
>         * gcc.dg/pr68217.c: New test.
Kugan Vivekanandarajah July 29, 2016, 12:37 a.m. UTC | #2
Hi Richard,

Thanks for the review.

On 27/04/16 00:14, Richard Biener wrote:
> On Fri, Apr 15, 2016 at 12:44 PM, kugan
> <kugan.vivekanandarajah@linaro.org> wrote:
>> As pointed out by Richard, for signed & sign-bit-CST value range should be
>> [-INF, 0] range, not a [-INF, INF] range as happens now.
>>
>> This patch fixes this. I bootstrapped and regression tested for
>> x86-64-linux-gnu with no new regression. Is this OK for statege-1.
>
> I think you need to check vr0 for singleton-constant == sign_bit as well,
> there is nothing that canonicalizes this during propagation.
>
> Otherwise ok.

Committed as r238846 with the above change.

Thanks,
Kugan


>
> Thanks,
> Richard.
>
>> Thanks,
>> Kugan
>>
>>
>> gcc/ChangeLog:
>>
>> 2016-04-14  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>
>>         PR middle-end/68217
>>         * tree-vrp.c (extract_range_from_binary_expr_1): In case of signed &
>> sign-bit-CST,
>>          generate [-INF, 0] instead of [-INF, INF].
>>
>>
>> gcc/testsuite/ChangeLog:
>>
>> 2016-04-14  Kugan Vivekanandarajah  <kuganv@linaro.org>
>>
>>         PR middle-end/68217
>>         * gcc.dg/pr68217.c: New test.
diff mbox

Patch

diff --git a/gcc/testsuite/gcc.dg/pr68217.c b/gcc/testsuite/gcc.dg/pr68217.c
index e69de29..8197363 100644
--- a/gcc/testsuite/gcc.dg/pr68217.c
+++ b/gcc/testsuite/gcc.dg/pr68217.c
@@ -0,0 +1,14 @@ 
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+int foo (void)
+{
+    volatile int a = -1;
+    long long b = -9223372036854775807LL - 1; // LLONG_MIN
+    long long x = (a & b); // x == 0x8000000000000000
+    if (x < 1LL) { ; } else { __builtin_abort(); }
+    return 0;
+}
+
+/* { dg-final { scan-tree-dump "x_*: \\[-INF, 0\\]" "vrp1" } } */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index bbdf9ce..3a021f3 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3115,6 +3115,22 @@  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 (&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)
 	{