Commit db7a2818 by Jakub Jelinek Committed by Jakub Jelinek

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
parent e520d5f0
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> 2016-01-29 Martin Jambor <mjambor@suse.cz>
* hsa-gen.c (get_memory_order_name): Mask with MEMMODEL_BASE_MASK. * hsa-gen.c (get_memory_order_name): Mask with MEMMODEL_BASE_MASK.
......
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> 2016-01-30 Paul Thomas <pault@gcc.gnu.org>
PR fortran/69566 PR fortran/69566
......
/* 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;
}
/* 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, ...@@ -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 o0 = dividend.to_uhwi ();
unsigned HOST_WIDE_INT o1 = divisor.to_uhwi (); unsigned HOST_WIDE_INT o1 = divisor.to_uhwi ();
unsigned int quotient_len = 1;
if (quotient) 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) if (remainder)
{ {
remainder[0] = o0 % o1; 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 /* Make the divisor and dividend positive and remember what we
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment