aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2015-02-24 09:07:10 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2015-02-24 09:07:10 +0100
commit09901e8a732081950e0091b7d188ef8e4d609ef0 (patch)
tree5e91765b4416adf1f124fe1032b9124c5006a1b4 /gcc
parentd130cf43923325219ffbedb7ab302b1a6927efb6 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr65170.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp96.c53
-rw-r--r--gcc/wide-int.cc5
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