re PR middle-end/66311 (Problems with some integer(16) values)

gcc/
	PR middle-end/66311
	* wide-int.cc (wi::from_mpz): Make sure that absolute mpz value
	is zero- rather than sign-extended.

gcc/testsuite/
2015-08-05  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>

	PR middle-end/66311
	* gfortran.dg/pr66311.f90: New file.

From-SVN: r226632
This commit is contained in:
Richard Sandiford 2015-08-05 14:23:42 +00:00
parent 96b4d19305
commit dcc74ead1e
4 changed files with 81 additions and 3 deletions

View file

@ -1,3 +1,9 @@
2015-08-05 Richard Sandiford <richard.sandiford@arm.com>
PR middle-end/66311
* wide-int.cc (wi::from_mpz): Make sure that absolute mpz value
is zero- rather than sign-extended.
2015-08-05 Richard Sandiford <richard.sandiford@arm.com>
* target-insns.def (can_extend): Delete.

View file

@ -1,3 +1,8 @@
2015-08-05 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR middle-end/66311
* gfortran.dg/pr66311.f90: New file.
2015-08-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/67121

View file

@ -0,0 +1,60 @@
! { dg-do run }
! { dg-additional-options "-fno-range-check -w" }
!
! Check that we can print large constants
!
! "-fno-range-check -w" is used so the testcase compiles even with targets
! that don't support large integer kinds.
program test
use iso_fortran_env, only : ikinds => integer_kinds
implicit none
! Largest integer kind
integer, parameter :: k = ikinds(size(ikinds))
integer, parameter :: hk = k / 2
if (k <= 8) stop
call check(9000000000000000000_k, "9000000000000000000")
call check(90000000000000000000_k, "90000000000000000000")
call check(int(huge(1_hk), kind=k), "9223372036854775807")
call check(2_k**63, "9223372036854775808")
call check(10000000000000000000_k, "10000000000000000000")
call check(18446744065119617024_k, "18446744065119617024")
call check(2_k**64 - 1, "18446744073709551615")
call check(2_k**64, "18446744073709551616")
call check(20000000000000000000_k, "20000000000000000000")
call check(huge(0_k), "170141183460469231731687303715884105727")
call check(huge(0_k)-1, "170141183460469231731687303715884105726")
call check(-9000000000000000000_k, "-9000000000000000000")
call check(-90000000000000000000_k, "-90000000000000000000")
call check(-int(huge(1_hk), kind=k), "-9223372036854775807")
call check(-2_k**63, "-9223372036854775808")
call check(-10000000000000000000_k, "-10000000000000000000")
call check(-18446744065119617024_k, "-18446744065119617024")
call check(-(2_k**64 - 1), "-18446744073709551615")
call check(-2_k**64, "-18446744073709551616")
call check(-20000000000000000000_k, "-20000000000000000000")
call check(-huge(0_k), "-170141183460469231731687303715884105727")
call check(-(huge(0_k)-1), "-170141183460469231731687303715884105726")
call check(-huge(0_k)-1, "-170141183460469231731687303715884105728")
call check(2_k * huge(1_hk), "18446744073709551614")
call check((-2_k) * huge(1_hk), "-18446744073709551614")
contains
subroutine check (i, str)
implicit none
integer(kind=k), intent(in), value :: i
character(len=*), intent(in) :: str
character(len=100) :: buffer
write(buffer,*) i
if (adjustl(buffer) /= adjustl(str)) call abort
end subroutine
end

View file

@ -252,13 +252,15 @@ wi::from_mpz (const_tree type, mpz_t x, bool wrap)
}
/* Determine the number of unsigned HOST_WIDE_INTs that are required
for representing the value. The code to calculate count is
for representing the absolute value. The code to calculate count is
extracted from the GMP manual, section "Integer Import and Export":
http://gmplib.org/manual/Integer-Import-and-Export.html */
numb = CHAR_BIT * sizeof (HOST_WIDE_INT);
count = (mpz_sizeinbase (x, 2) + numb - 1) / numb;
HOST_WIDE_INT *val = res.write_val ();
/* Write directly to the wide_int storage if possible, otherwise leave
/* Read the absolute value.
Write directly to the wide_int storage if possible, otherwise leave
GMP to allocate the memory for us. It might be slightly more efficient
to use mpz_tdiv_r_2exp for the latter case, but the situation is
pathological and it seems safer to operate on the original mpz value
@ -276,7 +278,12 @@ wi::from_mpz (const_tree type, mpz_t x, bool wrap)
memcpy (val, valres, count * sizeof (HOST_WIDE_INT));
free (valres);
}
res.set_len (canonize (val, count, prec));
/* Zero-extend the absolute value to PREC bits. */
if (count < BLOCKS_NEEDED (prec) && val[count - 1] < 0)
val[count++] = 0;
else
count = canonize (val, count, prec);
res.set_len (count);
if (mpz_sgn (x) < 0)
res = -res;