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:
parent
96b4d19305
commit
dcc74ead1e
4 changed files with 81 additions and 3 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
60
gcc/testsuite/gfortran.dg/pr66311.f90
Normal file
60
gcc/testsuite/gfortran.dg/pr66311.f90
Normal 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
|
||||
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue