On Mon, 26 Jan 2015, Jakub Jelinek wrote:

> Hi!
> 
> On the following testcase we generate wrong code, because
> apparently divmod_internal_2 relies on 0 being the topmost
> element (at b_dividend[m]):
>    algorithm.  M is the number of significant elements of U however
>    there needs to be at least one extra element of B_DIVIDEND
>    allocated, N is the number of elements of B_DIVISOR.  */
> The comment talks just about allocation, but from the code
> it seems it really relies on it being 0.
> There is space for it:
>   unsigned HOST_HALF_WIDE_INT
>     b_dividend[(4 * MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_HALF_WIDE_INT) + 
> 1];
>   unsigned HOST_HALF_WIDE_INT
>     b_divisor[4 * MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_HALF_WIDE_INT];
> (the + 1), and usually there already is a zero in there:
>   m = dividend_blocks_needed;
>   while (m > 1 && b_dividend[m - 1] == 0)
>     m--;
> so the only problematic case is if m isn't decreased.
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
> ok for trunk?

Ok.

Thanks,
Richard.

> 2015-01-26  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR tree-optimization/64807
>       * wide-int.cc (wi::divmod_internal): Clear
>       b_dividend[dividend_blocks_needed].
> 
>       * gcc.dg/pr64807.c: New test.
> 
> --- gcc/wide-int.cc.jj        2015-01-09 21:59:38.000000000 +0100
> +++ gcc/wide-int.cc   2015-01-26 19:21:56.114316481 +0100
> @@ -1819,6 +1819,7 @@ wi::divmod_internal (HOST_WIDE_INT *quot
>            divisor_blocks_needed, divisor_prec, sgn);
>  
>    m = dividend_blocks_needed;
> +  b_dividend[m] = 0;
>    while (m > 1 && b_dividend[m - 1] == 0)
>      m--;
>  
> --- gcc/testsuite/gcc.dg/pr64807.c.jj 2015-01-26 19:24:13.612943033 +0100
> +++ gcc/testsuite/gcc.dg/pr64807.c    2015-01-26 19:32:34.502237566 +0100
> @@ -0,0 +1,19 @@
> +/* PR tree-optimization/64807 */
> +/* { dg-do run { target int128 } } */
> +/* { dg-options "-O2" } */
> +
> +__uint128_t
> +foo (void)
> +{
> +  __uint128_t a = -1;
> +  __uint128_t b = -1;
> +  return a / b;
> +}
> +
> +int
> +main ()
> +{
> +  if (foo () != 1)
> +    __builtin_abort ();
> +  return 0;
> +}
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Jennifer Guild,
Dilip Upmanyu, Graham Norton HRB 21284 (AG Nuernberg)

Reply via email to