aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc Glisse <marc.glisse@inria.fr>2017-11-20 14:26:39 +0100
committerMarc Glisse <glisse@gcc.gnu.org>2017-11-20 13:26:39 +0000
commit50dec459c62701af05e4cfb097ee2c95944495cc (patch)
treec2030da4e2fde65a2785961d95230a9465028600
parent9aab553436aa25a1306cdd03c0fae107828e8725 (diff)
downloadgcc-50dec459c62701af05e4cfb097ee2c95944495cc.zip
gcc-50dec459c62701af05e4cfb097ee2c95944495cc.tar.gz
gcc-50dec459c62701af05e4cfb097ee2c95944495cc.tar.bz2
VRP: x+1 and -x cannot be INT_MIN
2017-11-20 Marc Glisse <marc.glisse@inria.fr> gcc/ * vr-values.c (extract_range_from_binary_expr): Use a full range for VR_VARYING. gcc/testsuite/ PR testsuite/82951 * gcc.c-torture/execute/20040409-1.c: Move invalid tests... * gcc.c-torture/execute/20040409-1w.c: ... here with -fwrapv. * gcc.c-torture/execute/20040409-2.c: Move invalid tests... * gcc.c-torture/execute/20040409-2w.c: ... here with -fwrapv. * gcc.c-torture/execute/20040409-3.c: Move invalid tests... * gcc.c-torture/execute/20040409-3w.c: ... here with -fwrapv. * gcc.dg/tree-ssa/cmpmul-1.c: Tweak condition. * gcc.dg/tree-ssa/vrp118.c: New file. From-SVN: r254954
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/testsuite/ChangeLog12
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040409-1.c30
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040409-1w.c65
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040409-2.c64
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040409-2w.c99
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040409-3.c30
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20040409-3w.c65
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cmpmul-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp118.c13
-rw-r--r--gcc/vr-values.c19
11 files changed, 279 insertions, 125 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4df4d80..11e515e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2017-11-20 Marc Glisse <marc.glisse@inria.fr>
+
+ * vr-values.c (extract_range_from_binary_expr): Use a full range
+ for VR_VARYING.
+
2017-11-20 Thomas Preud'homme <thomas.preudhomme@arm.com>
* config/arm/arm.md (R4_REGNUM): Define constant.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 70dc992..35fd8df 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,15 @@
+2017-11-20 Marc Glisse <marc.glisse@inria.fr>
+
+ PR testsuite/82951
+ * gcc.c-torture/execute/20040409-1.c: Move invalid tests...
+ * gcc.c-torture/execute/20040409-1w.c: ... here with -fwrapv.
+ * gcc.c-torture/execute/20040409-2.c: Move invalid tests...
+ * gcc.c-torture/execute/20040409-2w.c: ... here with -fwrapv.
+ * gcc.c-torture/execute/20040409-3.c: Move invalid tests...
+ * gcc.c-torture/execute/20040409-3w.c: ... here with -fwrapv.
+ * gcc.dg/tree-ssa/cmpmul-1.c: Tweak condition.
+ * gcc.dg/tree-ssa/vrp118.c: New file.
+
2017-11-20 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* g++.dg/pr82836.C: Require int128, __float128 support.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040409-1.c b/gcc/testsuite/gcc.c-torture/execute/20040409-1.c
index 1e81edb..d9649ab 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20040409-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20040409-1.c
@@ -12,21 +12,11 @@ unsigned int test1u(unsigned int x)
return x ^ (unsigned int)INT_MIN;
}
-int test2(int x)
-{
- return x + INT_MIN;
-}
-
unsigned int test2u(unsigned int x)
{
return x + (unsigned int)INT_MIN;
}
-int test3(int x)
-{
- return x - INT_MIN;
-}
-
unsigned int test3u(unsigned int x)
{
return x - (unsigned int)INT_MIN;
@@ -44,24 +34,12 @@ unsigned int test4u(unsigned int x)
return x ^ y;
}
-int test5(int x)
-{
- int y = INT_MIN;
- return x + y;
-}
-
unsigned int test5u(unsigned int x)
{
unsigned int y = (unsigned int)INT_MIN;
return x + y;
}
-int test6(int x)
-{
- int y = INT_MIN;
- return x - y;
-}
-
unsigned int test6u(unsigned int x)
{
unsigned int y = (unsigned int)INT_MIN;
@@ -74,16 +52,8 @@ void test(int a, int b)
{
if (test1(a) != b)
abort();
- if (test2(a) != b)
- abort();
- if (test3(a) != b)
- abort();
if (test4(a) != b)
abort();
- if (test5(a) != b)
- abort();
- if (test6(a) != b)
- abort();
}
void testu(unsigned int a, unsigned int b)
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040409-1w.c b/gcc/testsuite/gcc.c-torture/execute/20040409-1w.c
new file mode 100644
index 0000000..bd0157d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20040409-1w.c
@@ -0,0 +1,65 @@
+/* { dg-additional-options "-fwrapv" } */
+
+#include <limits.h>
+
+extern void abort ();
+
+int test2(int x)
+{
+ return x + INT_MIN;
+}
+
+int test3(int x)
+{
+ return x - INT_MIN;
+}
+
+int test5(int x)
+{
+ int y = INT_MIN;
+ return x + y;
+}
+
+int test6(int x)
+{
+ int y = INT_MIN;
+ return x - y;
+}
+
+
+
+void test(int a, int b)
+{
+ if (test2(a) != b)
+ abort();
+ if (test3(a) != b)
+ abort();
+ if (test5(a) != b)
+ abort();
+ if (test6(a) != b)
+ abort();
+}
+
+
+int main()
+{
+#if INT_MAX == 2147483647
+ test(0x00000000,0x80000000);
+ test(0x80000000,0x00000000);
+ test(0x12345678,0x92345678);
+ test(0x92345678,0x12345678);
+ test(0x7fffffff,0xffffffff);
+ test(0xffffffff,0x7fffffff);
+#endif
+
+#if INT_MAX == 32767
+ test(0x0000,0x8000);
+ test(0x8000,0x0000);
+ test(0x1234,0x9234);
+ test(0x9234,0x1234);
+ test(0x7fff,0xffff);
+ test(0xffff,0x7fff);
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040409-2.c b/gcc/testsuite/gcc.c-torture/execute/20040409-2.c
index c83ff1a..c04c7be 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20040409-2.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20040409-2.c
@@ -22,41 +22,21 @@ unsigned int test2u(unsigned int x)
return (x ^ 0x1234) ^ (unsigned int)INT_MIN;
}
-int test3(int x)
-{
- return (x + INT_MIN) ^ 0x1234;
-}
-
unsigned int test3u(unsigned int x)
{
return (x + (unsigned int)INT_MIN) ^ 0x1234;
}
-int test4(int x)
-{
- return (x ^ 0x1234) + INT_MIN;
-}
-
unsigned int test4u(unsigned int x)
{
return (x ^ 0x1234) + (unsigned int)INT_MIN;
}
-int test5(int x)
-{
- return (x - INT_MIN) ^ 0x1234;
-}
-
unsigned int test5u(unsigned int x)
{
return (x - (unsigned int)INT_MIN) ^ 0x1234;
}
-int test6(int x)
-{
- return (x ^ 0x1234) - INT_MIN;
-}
-
unsigned int test6u(unsigned int x)
{
return (x ^ 0x1234) - (unsigned int)INT_MIN;
@@ -90,13 +70,6 @@ unsigned int test8u(unsigned int x)
return (x ^ y) ^ z;
}
-int test9(int x)
-{
- int y = INT_MIN;
- int z = 0x1234;
- return (x + y) ^ z;
-}
-
unsigned int test9u(unsigned int x)
{
unsigned int y = (unsigned int)INT_MIN;
@@ -104,13 +77,6 @@ unsigned int test9u(unsigned int x)
return (x + y) ^ z;
}
-int test10(int x)
-{
- int y = 0x1234;
- int z = INT_MIN;
- return (x ^ y) + z;
-}
-
unsigned int test10u(unsigned int x)
{
unsigned int y = 0x1234;
@@ -118,13 +84,6 @@ unsigned int test10u(unsigned int x)
return (x ^ y) + z;
}
-int test11(int x)
-{
- int y = INT_MIN;
- int z = 0x1234;
- return (x - y) ^ z;
-}
-
unsigned int test11u(unsigned int x)
{
unsigned int y = (unsigned int)INT_MIN;
@@ -132,13 +91,6 @@ unsigned int test11u(unsigned int x)
return (x - y) ^ z;
}
-int test12(int x)
-{
- int y = 0x1234;
- int z = INT_MIN;
- return (x ^ y) - z;
-}
-
unsigned int test12u(unsigned int x)
{
unsigned int y = 0x1234;
@@ -153,26 +105,10 @@ void test(int a, int b)
abort();
if (test2(a) != b)
abort();
- if (test3(a) != b)
- abort();
- if (test4(a) != b)
- abort();
- if (test5(a) != b)
- abort();
- if (test6(a) != b)
- abort();
if (test7(a) != b)
abort();
if (test8(a) != b)
abort();
- if (test9(a) != b)
- abort();
- if (test10(a) != b)
- abort();
- if (test11(a) != b)
- abort();
- if (test12(a) != b)
- abort();
}
void testu(unsigned int a, unsigned int b)
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040409-2w.c b/gcc/testsuite/gcc.c-torture/execute/20040409-2w.c
new file mode 100644
index 0000000..f6c5f2c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20040409-2w.c
@@ -0,0 +1,99 @@
+/* { dg-additional-options "-fwrapv" } */
+
+#include <limits.h>
+
+extern void abort ();
+
+int test3(int x)
+{
+ return (x + INT_MIN) ^ 0x1234;
+}
+
+int test4(int x)
+{
+ return (x ^ 0x1234) + INT_MIN;
+}
+
+int test5(int x)
+{
+ return (x - INT_MIN) ^ 0x1234;
+}
+
+int test6(int x)
+{
+ return (x ^ 0x1234) - INT_MIN;
+}
+
+int test9(int x)
+{
+ int y = INT_MIN;
+ int z = 0x1234;
+ return (x + y) ^ z;
+}
+
+int test10(int x)
+{
+ int y = 0x1234;
+ int z = INT_MIN;
+ return (x ^ y) + z;
+}
+
+int test11(int x)
+{
+ int y = INT_MIN;
+ int z = 0x1234;
+ return (x - y) ^ z;
+}
+
+int test12(int x)
+{
+ int y = 0x1234;
+ int z = INT_MIN;
+ return (x ^ y) - z;
+}
+
+
+void test(int a, int b)
+{
+ if (test3(a) != b)
+ abort();
+ if (test4(a) != b)
+ abort();
+ if (test5(a) != b)
+ abort();
+ if (test6(a) != b)
+ abort();
+ if (test9(a) != b)
+ abort();
+ if (test10(a) != b)
+ abort();
+ if (test11(a) != b)
+ abort();
+ if (test12(a) != b)
+ abort();
+}
+
+
+int main()
+{
+#if INT_MAX == 2147483647
+ test(0x00000000,0x80001234);
+ test(0x00001234,0x80000000);
+ test(0x80000000,0x00001234);
+ test(0x80001234,0x00000000);
+ test(0x7fffffff,0xffffedcb);
+ test(0xffffffff,0x7fffedcb);
+#endif
+
+#if INT_MAX == 32767
+ test(0x0000,0x9234);
+ test(0x1234,0x8000);
+ test(0x8000,0x1234);
+ test(0x9234,0x0000);
+ test(0x7fff,0xedcb);
+ test(0xffff,0x6dcb);
+#endif
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040409-3.c b/gcc/testsuite/gcc.c-torture/execute/20040409-3.c
index 07aa99c..279cab1 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20040409-3.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20040409-3.c
@@ -12,21 +12,11 @@ unsigned int test1u(unsigned int x)
return ~(x ^ (unsigned int)INT_MIN);
}
-int test2(int x)
-{
- return ~(x + INT_MIN);
-}
-
unsigned int test2u(unsigned int x)
{
return ~(x + (unsigned int)INT_MIN);
}
-int test3(int x)
-{
- return ~(x - INT_MIN);
-}
-
unsigned int test3u(unsigned int x)
{
return ~(x - (unsigned int)INT_MIN);
@@ -44,24 +34,12 @@ unsigned int test4u(unsigned int x)
return ~(x ^ y);
}
-int test5(int x)
-{
- int y = INT_MIN;
- return ~(x + y);
-}
-
unsigned int test5u(unsigned int x)
{
unsigned int y = (unsigned int)INT_MIN;
return ~(x + y);
}
-int test6(int x)
-{
- int y = INT_MIN;
- return ~(x - y);
-}
-
unsigned int test6u(unsigned int x)
{
unsigned int y = (unsigned int)INT_MIN;
@@ -74,16 +52,8 @@ void test(int a, int b)
{
if (test1(a) != b)
abort();
- if (test2(a) != b)
- abort();
- if (test3(a) != b)
- abort();
if (test4(a) != b)
abort();
- if (test5(a) != b)
- abort();
- if (test6(a) != b)
- abort();
}
void testu(unsigned int a, unsigned int b)
diff --git a/gcc/testsuite/gcc.c-torture/execute/20040409-3w.c b/gcc/testsuite/gcc.c-torture/execute/20040409-3w.c
new file mode 100644
index 0000000..3a1883d
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20040409-3w.c
@@ -0,0 +1,65 @@
+/* { dg-additional-options "-fwrapv" } */
+
+#include <limits.h>
+
+extern void abort ();
+
+int test2(int x)
+{
+ return ~(x + INT_MIN);
+}
+
+int test3(int x)
+{
+ return ~(x - INT_MIN);
+}
+
+int test5(int x)
+{
+ int y = INT_MIN;
+ return ~(x + y);
+}
+
+int test6(int x)
+{
+ int y = INT_MIN;
+ return ~(x - y);
+}
+
+
+void test(int a, int b)
+{
+ if (test2(a) != b)
+ abort();
+ if (test3(a) != b)
+ abort();
+ if (test5(a) != b)
+ abort();
+ if (test6(a) != b)
+ abort();
+}
+
+
+int main()
+{
+#if INT_MAX == 2147483647
+ test(0x00000000,0x7fffffff);
+ test(0x80000000,0xffffffff);
+ test(0x12345678,0x6dcba987);
+ test(0x92345678,0xedcba987);
+ test(0x7fffffff,0x00000000);
+ test(0xffffffff,0x80000000);
+#endif
+
+#if INT_MAX == 32767
+ test(0x0000,0x7fff);
+ test(0x8000,0xffff);
+ test(0x1234,0x6dcb);
+ test(0x9234,0xedcb);
+ test(0x7fff,0x0000);
+ test(0xffff,0x8000);
+#endif
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cmpmul-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cmpmul-1.c
index 1e303b1..1fa7f3e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cmpmul-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cmpmul-1.c
@@ -2,7 +2,7 @@
/* { dg-options "-O2 -fdump-tree-optimized-raw" } */
int f(int a, int b, int c){
- c |= 1; // c cannot be 0
+ if (c == 0) __builtin_unreachable();
a *= c;
b *= c;
return a == b;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp118.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp118.c
new file mode 100644
index 0000000..8c4cc36
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp118.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+void eliminate_me();
+void f(int x,int y){
+ if (y <= 0)
+ __builtin_unreachable();
+ x += y;
+ if (x == -__INT_MAX__ - 1)
+ eliminate_me ();
+}
+
+/* { dg-final { scan-tree-dump-not "eliminate_me" "optimized" } } */
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 3e760a3..2d11861 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -771,6 +771,25 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
else
set_value_range_to_varying (&vr1);
+ /* If one argument is varying, we can sometimes still deduce a
+ range for the output: any + [3, +INF] is in [MIN+3, +INF]. */
+ if (INTEGRAL_TYPE_P (TREE_TYPE (op0))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
+ {
+ if (vr0.type == VR_VARYING && vr1.type != VR_VARYING)
+ {
+ vr0.type = VR_RANGE;
+ vr0.min = vrp_val_min (expr_type);
+ vr0.max = vrp_val_max (expr_type);
+ }
+ else if (vr1.type == VR_VARYING && vr0.type != VR_VARYING)
+ {
+ vr1.type = VR_RANGE;
+ vr1.min = vrp_val_min (expr_type);
+ vr1.max = vrp_val_max (expr_type);
+ }
+ }
+
extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &vr1);
/* Try harder for PLUS and MINUS if the range of one operand is symbolic