From b55deb213a41cc84bfc47901960dc014f5412f35 Mon Sep 17 00:00:00 2001 From: jakub Date: Thu, 17 Dec 2015 13:52:25 +0000 Subject: 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 --- gcc/ChangeLog | 10 ++++++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/pr68835-1.c | 12 ++++++++++++ gcc/testsuite/gcc.dg/pr68835-2.c | 23 +++++++++++++++++++++++ gcc/tree.c | 11 +++++------ 5 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr68835-1.c create mode 100644 gcc/testsuite/gcc.dg/pr68835-2.c 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 + + 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 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 + + PR tree-optimization/68835 + * gcc.dg/pr68835-1.c: New test. + * gcc.dg/pr68835-2.c: New test. + 2015-12-17 Richard Biener 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; } -- cgit v1.2.1