Commit dcc74ead by Richard Sandiford

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
parent 96b4d193
2015-08-05 Richard Sandiford <richard.sandiford@arm.com> 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. * target-insns.def (can_extend): Delete.
2015-08-05 Richard Biener <rguenther@suse.de> 2015-08-05 Richard Biener <rguenther@suse.de>
......
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> 2015-08-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/67121 PR tree-optimization/67121
......
! { 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
...@@ -252,13 +252,15 @@ wi::from_mpz (const_tree type, mpz_t x, bool wrap) ...@@ -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 /* 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": extracted from the GMP manual, section "Integer Import and Export":
http://gmplib.org/manual/Integer-Import-and-Export.html */ http://gmplib.org/manual/Integer-Import-and-Export.html */
numb = CHAR_BIT * sizeof (HOST_WIDE_INT); numb = CHAR_BIT * sizeof (HOST_WIDE_INT);
count = (mpz_sizeinbase (x, 2) + numb - 1) / numb; count = (mpz_sizeinbase (x, 2) + numb - 1) / numb;
HOST_WIDE_INT *val = res.write_val (); 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 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 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 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) ...@@ -276,7 +278,12 @@ wi::from_mpz (const_tree type, mpz_t x, bool wrap)
memcpy (val, valres, count * sizeof (HOST_WIDE_INT)); memcpy (val, valres, count * sizeof (HOST_WIDE_INT));
free (valres); 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) if (mpz_sgn (x) < 0)
res = -res; res = -res;
......
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