re PR middle-end/69546 (wrong code with -O and simple int128 arithmetics)
PR tree-optimization/69546 * wide-int.cc (wi::divmod_internal): For unsigned division where both operands fit into uhwi, if o1 is 1 and o0 has msb set, if divident_prec is larger than bits per hwi, clear another quotient word and return 2 instead of 1. Similarly for remainder with msb in HWI set, if dividend_prec is larger than bits per hwi. * gcc.dg/torture/pr69546.c: New test. From-SVN: r233012
This commit is contained in:
parent
e520d5f02a
commit
db7a281800
5 changed files with 79 additions and 3 deletions
|
@ -1,3 +1,13 @@
|
|||
2016-01-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/69546
|
||||
* wide-int.cc (wi::divmod_internal): For unsigned division
|
||||
where both operands fit into uhwi, if o1 is 1 and o0 has
|
||||
msb set, if divident_prec is larger than bits per hwi,
|
||||
clear another quotient word and return 2 instead of 1.
|
||||
Similarly for remainder with msb in HWI set, if dividend_prec
|
||||
is larger than bits per hwi.
|
||||
|
||||
2016-01-29 Martin Jambor <mjambor@suse.cz>
|
||||
|
||||
* hsa-gen.c (get_memory_order_name): Mask with MEMMODEL_BASE_MASK.
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2016-01-30 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR tree-optimization/69546
|
||||
* gcc.dg/torture/pr69546.c: New test.
|
||||
|
||||
2016-01-30 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/69566
|
||||
|
|
26
gcc/testsuite/gcc.dg/torture/pr69546-1.c
Normal file
26
gcc/testsuite/gcc.dg/torture/pr69546-1.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
/* PR tree-optimization/69546 */
|
||||
/* { dg-do run { target int128 } } */
|
||||
|
||||
unsigned __int128 __attribute__ ((noinline, noclone))
|
||||
foo (unsigned long long x)
|
||||
{
|
||||
unsigned __int128 y = ~0ULL;
|
||||
x >>= 63;
|
||||
return y / (x | 1);
|
||||
}
|
||||
|
||||
unsigned __int128 __attribute__ ((noinline, noclone))
|
||||
bar (unsigned long long x)
|
||||
{
|
||||
unsigned __int128 y = ~33ULL;
|
||||
x >>= 63;
|
||||
return y / (x | 1);
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (foo (1) != ~0ULL || bar (17) != ~33ULL)
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
18
gcc/testsuite/gcc.dg/torture/pr69546-2.c
Normal file
18
gcc/testsuite/gcc.dg/torture/pr69546-2.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
/* PR tree-optimization/69546 */
|
||||
/* { dg-do run { target int128 } } */
|
||||
|
||||
unsigned __int128
|
||||
foo (void)
|
||||
{
|
||||
unsigned __int128 a = 0xfffffffffffffffeULL;
|
||||
unsigned __int128 b = 0xffffffffffffffffULL;
|
||||
return a % b;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
if (foo () != 0xfffffffffffffffeULL)
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
|
@ -1788,15 +1788,32 @@ wi::divmod_internal (HOST_WIDE_INT *quotient, unsigned int *remainder_len,
|
|||
{
|
||||
unsigned HOST_WIDE_INT o0 = dividend.to_uhwi ();
|
||||
unsigned HOST_WIDE_INT o1 = divisor.to_uhwi ();
|
||||
unsigned int quotient_len = 1;
|
||||
|
||||
if (quotient)
|
||||
quotient[0] = o0 / o1;
|
||||
{
|
||||
quotient[0] = o0 / o1;
|
||||
if (o1 == 1
|
||||
&& (HOST_WIDE_INT) o0 < 0
|
||||
&& dividend_prec > HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
quotient[1] = 0;
|
||||
quotient_len = 2;
|
||||
}
|
||||
}
|
||||
if (remainder)
|
||||
{
|
||||
remainder[0] = o0 % o1;
|
||||
*remainder_len = 1;
|
||||
if ((HOST_WIDE_INT) remainder[0] < 0
|
||||
&& dividend_prec > HOST_BITS_PER_WIDE_INT)
|
||||
{
|
||||
remainder[1] = 0;
|
||||
*remainder_len = 2;
|
||||
}
|
||||
else
|
||||
*remainder_len = 1;
|
||||
}
|
||||
return 1;
|
||||
return quotient_len;
|
||||
}
|
||||
|
||||
/* Make the divisor and dividend positive and remember what we
|
||||
|
|
Loading…
Add table
Reference in a new issue