summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-17 13:52:25 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2015-12-17 13:52:25 +0000
commitb55deb213a41cc84bfc47901960dc014f5412f35 (patch)
treeb72d48432f46da6493f758fd909b5dbd54dee777
parentfa79057be75f3575d14e3b8d917c745eeea4a35a (diff)
downloadgcc-b55deb213a41cc84bfc47901960dc014f5412f35.tar.gz
PR tree-optimization/68835
* tree.c (get_int_cst_ext_nunits): Return cst.get_precision () / HOST_BITS_PER_WIDE_INT + 1 for all unsigned wi::neg_p (cst) constants. (build_new_int_cst): If cst.get_precision is not a multiple of HOST_BITS_PER_WIDE_INT, zero extend -1 to the precision % HOST_BITS_PER_WIDE_INT. * gcc.dg/pr68835-1.c: New test. * gcc.dg/pr68835-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@231757 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/pr68835-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr68835-2.c23
-rw-r--r--gcc/tree.c11
5 files changed, 56 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 46cf0b0862c..f836652c9af 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2015-12-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/68835
+ * tree.c (get_int_cst_ext_nunits): Return
+ cst.get_precision () / HOST_BITS_PER_WIDE_INT + 1
+ for all unsigned wi::neg_p (cst) constants.
+ (build_new_int_cst): If cst.get_precision is not a multiple
+ of HOST_BITS_PER_WIDE_INT, zero extend -1 to the precision
+ % HOST_BITS_PER_WIDE_INT.
+
2015-12-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/68951
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7386f6b055c..193f9924463 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2015-12-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/68835
+ * gcc.dg/pr68835-1.c: New test.
+ * gcc.dg/pr68835-2.c: New test.
+
2015-12-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/68951
diff --git a/gcc/testsuite/gcc.dg/pr68835-1.c b/gcc/testsuite/gcc.dg/pr68835-1.c
new file mode 100644
index 00000000000..47aebe3c1c6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr68835-1.c
@@ -0,0 +1,12 @@
+/* PR tree-optimization/68835 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+
+unsigned __int128
+foo (unsigned long a, unsigned long b)
+{
+ unsigned __int128 x = (unsigned __int128) a * b;
+ struct { unsigned __int128 a : 96; } w;
+ w.a = x;
+ return w.a;
+}
diff --git a/gcc/testsuite/gcc.dg/pr68835-2.c b/gcc/testsuite/gcc.dg/pr68835-2.c
new file mode 100644
index 00000000000..dd355b17223
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr68835-2.c
@@ -0,0 +1,23 @@
+/* PR tree-optimization/68835 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O2" } */
+
+__attribute__((noinline, noclone)) unsigned __int128
+foo (void)
+{
+ unsigned __int128 x = (unsigned __int128) 0xffffffffffffffffULL;
+ struct { unsigned __int128 a : 65; } w;
+ w.a = x;
+ w.a += x;
+ return w.a;
+}
+
+int
+main ()
+{
+ unsigned __int128 x = foo ();
+ if ((unsigned long long) x != 0xfffffffffffffffeULL
+ || (unsigned long long) (x >> 64) != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 66c06c992f6..2190cae8475 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -1245,11 +1245,9 @@ static unsigned int
get_int_cst_ext_nunits (tree type, const wide_int &cst)
{
gcc_checking_assert (cst.get_precision () == TYPE_PRECISION (type));
- /* We need an extra zero HWI if CST is an unsigned integer with its
- upper bit set, and if CST occupies a whole number of HWIs. */
- if (TYPE_UNSIGNED (type)
- && wi::neg_p (cst)
- && (cst.get_precision () % HOST_BITS_PER_WIDE_INT) == 0)
+ /* We need extra HWIs if CST is an unsigned integer with its
+ upper bit set. */
+ if (TYPE_UNSIGNED (type) && wi::neg_p (cst))
return cst.get_precision () / HOST_BITS_PER_WIDE_INT + 1;
return cst.get_len ();
}
@@ -1266,7 +1264,8 @@ build_new_int_cst (tree type, const wide_int &cst)
if (len < ext_len)
{
--ext_len;
- TREE_INT_CST_ELT (nt, ext_len) = 0;
+ TREE_INT_CST_ELT (nt, ext_len)
+ = zext_hwi (-1, cst.get_precision () % HOST_BITS_PER_WIDE_INT);
for (unsigned int i = len; i < ext_len; ++i)
TREE_INT_CST_ELT (nt, i) = -1;
}