diff options
-rw-r--r-- | gcc/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20040409-1.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20040409-1w.c | 65 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20040409-2.c | 64 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20040409-2w.c | 99 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20040409-3.c | 30 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/20040409-3w.c | 65 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/cmpmul-1.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/vrp118.c | 13 | ||||
-rw-r--r-- | gcc/vr-values.c | 19 |
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 |