diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-02-24 09:07:10 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-02-24 09:07:10 +0100 |
commit | 09901e8a732081950e0091b7d188ef8e4d609ef0 (patch) | |
tree | 5e91765b4416adf1f124fe1032b9124c5006a1b4 /gcc | |
parent | d130cf43923325219ffbedb7ab302b1a6927efb6 (diff) | |
download | gcc-09901e8a732081950e0091b7d188ef8e4d609ef0.zip gcc-09901e8a732081950e0091b7d188ef8e4d609ef0.tar.gz gcc-09901e8a732081950e0091b7d188ef8e4d609ef0.tar.bz2 |
re PR tree-optimization/65170 (curve25519-donna-c64 miscompilation)
PR tree-optimization/65170
* wide-int.cc (wi::mul_internal): For the umul_ppmm optimization,
if val[1] < 0, clear also val[2] and return 3.
* gcc.c-torture/execute/pr65170.c: New test.
* gcc.dg/tree-ssa/vrp96.c: New test.
From-SVN: r220931
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr65170.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/vrp96.c | 53 | ||||
-rw-r--r-- | gcc/wide-int.cc | 5 |
5 files changed, 98 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d039c0a..4bbdfe3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2015-02-24 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/65170 + * wide-int.cc (wi::mul_internal): For the umul_ppmm optimization, + if val[1] < 0, clear also val[2] and return 3. + 2015-02-24 Alan Modra <amodra@gmail.com> PR target/65172 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 11f06fc..daf3e18 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2015-02-24 Jakub Jelinek <jakub@redhat.com> + + PR tree-optimization/65170 + * gcc.c-torture/execute/pr65170.c: New test. + * gcc.dg/tree-ssa/vrp96.c: New test. + 2015-02-24 Tom de Vries <tom@codesourcery.com> * gfortran.dg/readwrite_unf_direct_eor_1.f90: Add missing close. @@ -27,7 +33,7 @@ registers have the right values. Save register state into static data rather than on the stack. -2015-02-20 Jakub Jelinek <jakub@redhat.com> +2015-02-23 Jakub Jelinek <jakub@redhat.com> PR bootstrap/63888 * c-c++-common/asan/pr63888.c: New test. diff --git a/gcc/testsuite/gcc.c-torture/execute/pr65170.c b/gcc/testsuite/gcc.c-torture/execute/pr65170.c new file mode 100644 index 0000000..60c0052 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr65170.c @@ -0,0 +1,27 @@ +/* PR tree-optimization/65170 */ + +#ifdef __SIZEOF_INT128__ +typedef unsigned __int128 V; +typedef unsigned long long int H; +#else +typedef unsigned long long int V; +typedef unsigned int H; +#endif + +__attribute__((noinline, noclone)) void +foo (V b, V c) +{ + V a; + b &= (H) -1; + c &= (H) -1; + a = b * c; + if (a != 1) + __builtin_abort (); +} + +int +main () +{ + foo (1, 1); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp96.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp96.c new file mode 100644 index 0000000..e17e424 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp96.c @@ -0,0 +1,53 @@ +/* PR tree-optimization/65170 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -fdump-tree-vrp1" } */ + +typedef unsigned __int128 T; +extern void link_error (void); +extern void required_check (void); + +T +foo (T b, T c) +{ + T a; + b &= 0xffffffffffffffffULL; + c &= 0xffffffffffffffffULL; + if (b < 7 || c < 7) + return 0; + a = b * c; + if (a < 49 || a > (((T) 0xfffffffffffffffeULL << 64) | 1)) + link_error (); + return a; +} + +T +bar (T b, T c) +{ + T a; + b &= 0xffffffffffffffffULL; + c &= 0xffffffffffffffffULL; + if (b < 7 || c < 7) + return 0; + a = b * c; + if (a == 49) + required_check (); + return a; +} + +T +baz (T b, T c) +{ + T a; + b &= 0xffffffffffffffffULL; + c &= 0xffffffffffffffffULL; + if (b < 7 || c < 7) + return 0; + a = b * c; + if (a == (((T) 0xfffffffffffffffeULL << 64) | 1)) + required_check (); + return a; +} + +/* { dg-final { scan-tree-dump-not "link_error" "vrp1" } } */ +/* { dg-final { scan-tree-dump-times "required_check" 2 "vrp1" } } */ +/* { dg-final { cleanup-tree-dump "vrp1" } } */ diff --git a/gcc/wide-int.cc b/gcc/wide-int.cc index 7662648..1a7fc14 100644 --- a/gcc/wide-int.cc +++ b/gcc/wide-int.cc @@ -1309,6 +1309,11 @@ wi::mul_internal (HOST_WIDE_INT *val, const HOST_WIDE_INT *op1val, return 1; } umul_ppmm (val[1], val[0], op1.ulow (), op2.ulow ()); + if (val[1] < 0 && prec > HOST_BITS_PER_WIDE_INT * 2) + { + val[2] = 0; + return 3; + } return 1 + (val[1] != 0 || val[0] < 0); } /* Likewise if the output is a full single HWI, except that the |