re PR fortran/90577 (FAIL: gfortran.dg/lrshift_1.f90 with -O(2|3) and -flto)
2019-06-14 Harald Anlauf <anlauf@gmx.de> PR fortran/90577 PR fortran/90578 * trans-intrinsic.c (gfc_conv_intrinsic_shift): Properly distinguish logical/arithmetic shifts. * intrinsic.texi: Update documentation for SHIFTR/SHIFTL/SHIFTA (Fortran 2008) and LSHIFT/RSHIFT (GNU extensions). PR fortran/90577 PR fortran/90578 * gfortran.dg/lrshift_1.f90: Adjust testcase. * gfortran.dg/shiftalr_3.f90: New testcase. From-SVN: r272309
This commit is contained in:
parent
a8566e938c
commit
d0442491d5
|
@ -1,3 +1,12 @@
|
||||||
|
2019-06-14 Harald Anlauf <anlauf@gmx.de>
|
||||||
|
|
||||||
|
PR fortran/90577
|
||||||
|
PR fortran/90578
|
||||||
|
* trans-intrinsic.c (gfc_conv_intrinsic_shift): Properly
|
||||||
|
distinguish logical/arithmetic shifts.
|
||||||
|
* intrinsic.texi: Update documentation for SHIFTR/SHIFTL/SHIFTA
|
||||||
|
(Fortran 2008) and LSHIFT/RSHIFT (GNU extensions).
|
||||||
|
|
||||||
2019-06-14 Steven G. Kargl <kargl@gcc.gnu.org>
|
2019-06-14 Steven G. Kargl <kargl@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/89646
|
PR fortran/89646
|
||||||
|
|
|
@ -9689,10 +9689,10 @@ The return value is a @code{INTEGER(4)} variable.
|
||||||
@table @asis
|
@table @asis
|
||||||
@item @emph{Description}:
|
@item @emph{Description}:
|
||||||
@code{LSHIFT} returns a value corresponding to @var{I} with all of the
|
@code{LSHIFT} returns a value corresponding to @var{I} with all of the
|
||||||
bits shifted left by @var{SHIFT} places. If the absolute value of
|
bits shifted left by @var{SHIFT} places. @var{SHIFT} shall be
|
||||||
@var{SHIFT} is greater than @code{BIT_SIZE(I)}, the value is undefined.
|
nonnegative and less than or equal to @code{BIT_SIZE(I)}, otherwise
|
||||||
Bits shifted out from the left end are lost; zeros are shifted in from
|
the result value is undefined. Bits shifted out from the left end are
|
||||||
the opposite end.
|
lost; zeros are shifted in from the opposite end.
|
||||||
|
|
||||||
This function has been superseded by the @code{ISHFT} intrinsic, which
|
This function has been superseded by the @code{ISHFT} intrinsic, which
|
||||||
is standard in Fortran 95 and later, and the @code{SHIFTL} intrinsic,
|
is standard in Fortran 95 and later, and the @code{SHIFTL} intrinsic,
|
||||||
|
@ -12244,11 +12244,12 @@ The value returned is equal to
|
||||||
@table @asis
|
@table @asis
|
||||||
@item @emph{Description}:
|
@item @emph{Description}:
|
||||||
@code{RSHIFT} returns a value corresponding to @var{I} with all of the
|
@code{RSHIFT} returns a value corresponding to @var{I} with all of the
|
||||||
bits shifted right by @var{SHIFT} places. If the absolute value of
|
bits shifted right by @var{SHIFT} places. @var{SHIFT} shall be
|
||||||
@var{SHIFT} is greater than @code{BIT_SIZE(I)}, the value is undefined.
|
nonnegative and less than or equal to @code{BIT_SIZE(I)}, otherwise
|
||||||
Bits shifted out from the right end are lost. The fill is arithmetic: the
|
the result value is undefined. Bits shifted out from the right end
|
||||||
bits shifted in from the left end are equal to the leftmost bit, which in
|
are lost. The fill is arithmetic: the bits shifted in from the left
|
||||||
two's complement representation is the sign bit.
|
end are equal to the leftmost bit, which in two's complement
|
||||||
|
representation is the sign bit.
|
||||||
|
|
||||||
This function has been superseded by the @code{SHIFTA} intrinsic, which
|
This function has been superseded by the @code{SHIFTA} intrinsic, which
|
||||||
is standard in Fortran 2008 and later.
|
is standard in Fortran 2008 and later.
|
||||||
|
@ -12783,11 +12784,12 @@ END PROGRAM
|
||||||
@table @asis
|
@table @asis
|
||||||
@item @emph{Description}:
|
@item @emph{Description}:
|
||||||
@code{SHIFTA} returns a value corresponding to @var{I} with all of the
|
@code{SHIFTA} returns a value corresponding to @var{I} with all of the
|
||||||
bits shifted right by @var{SHIFT} places. If the absolute value of
|
bits shifted right by @var{SHIFT} places. @var{SHIFT} that be
|
||||||
@var{SHIFT} is greater than @code{BIT_SIZE(I)}, the value is undefined.
|
nonnegative and less than or equal to @code{BIT_SIZE(I)}, otherwise
|
||||||
Bits shifted out from the right end are lost. The fill is arithmetic: the
|
the result value is undefined. Bits shifted out from the right end
|
||||||
bits shifted in from the left end are equal to the leftmost bit, which in
|
are lost. The fill is arithmetic: the bits shifted in from the left
|
||||||
two's complement representation is the sign bit.
|
end are equal to the leftmost bit, which in two's complement
|
||||||
|
representation is the sign bit.
|
||||||
|
|
||||||
@item @emph{Standard}:
|
@item @emph{Standard}:
|
||||||
Fortran 2008 and later
|
Fortran 2008 and later
|
||||||
|
@ -12823,10 +12825,10 @@ The return value is of type @code{INTEGER} and of the same kind as
|
||||||
@table @asis
|
@table @asis
|
||||||
@item @emph{Description}:
|
@item @emph{Description}:
|
||||||
@code{SHIFTL} returns a value corresponding to @var{I} with all of the
|
@code{SHIFTL} returns a value corresponding to @var{I} with all of the
|
||||||
bits shifted left by @var{SHIFT} places. If the absolute value of
|
bits shifted left by @var{SHIFT} places. @var{SHIFT} shall be
|
||||||
@var{SHIFT} is greater than @code{BIT_SIZE(I)}, the value is undefined.
|
nonnegative and less than or equal to @code{BIT_SIZE(I)}, otherwise
|
||||||
Bits shifted out from the left end are lost, and bits shifted in from
|
the result value is undefined. Bits shifted out from the left end are
|
||||||
the right end are set to 0.
|
lost, and bits shifted in from the right end are set to 0.
|
||||||
|
|
||||||
@item @emph{Standard}:
|
@item @emph{Standard}:
|
||||||
Fortran 2008 and later
|
Fortran 2008 and later
|
||||||
|
@ -12862,10 +12864,10 @@ The return value is of type @code{INTEGER} and of the same kind as
|
||||||
@table @asis
|
@table @asis
|
||||||
@item @emph{Description}:
|
@item @emph{Description}:
|
||||||
@code{SHIFTR} returns a value corresponding to @var{I} with all of the
|
@code{SHIFTR} returns a value corresponding to @var{I} with all of the
|
||||||
bits shifted right by @var{SHIFT} places. If the absolute value of
|
bits shifted right by @var{SHIFT} places. @var{SHIFT} shall be
|
||||||
@var{SHIFT} is greater than @code{BIT_SIZE(I)}, the value is undefined.
|
nonnegative and less than or equal to @code{BIT_SIZE(I)}, otherwise
|
||||||
Bits shifted out from the right end are lost, and bits shifted in from
|
the result value is undefined. Bits shifted out from the right end
|
||||||
the left end are set to 0.
|
are lost, and bits shifted in from the left end are set to 0.
|
||||||
|
|
||||||
@item @emph{Standard}:
|
@item @emph{Standard}:
|
||||||
Fortran 2008 and later
|
Fortran 2008 and later
|
||||||
|
|
|
@ -6346,6 +6346,7 @@ gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift,
|
||||||
bool arithmetic)
|
bool arithmetic)
|
||||||
{
|
{
|
||||||
tree args[2], type, num_bits, cond;
|
tree args[2], type, num_bits, cond;
|
||||||
|
tree bigshift;
|
||||||
|
|
||||||
gfc_conv_intrinsic_function_args (se, expr, args, 2);
|
gfc_conv_intrinsic_function_args (se, expr, args, 2);
|
||||||
|
|
||||||
|
@ -6365,6 +6366,18 @@ gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift,
|
||||||
if (!arithmetic)
|
if (!arithmetic)
|
||||||
se->expr = fold_convert (type, se->expr);
|
se->expr = fold_convert (type, se->expr);
|
||||||
|
|
||||||
|
if (!arithmetic)
|
||||||
|
bigshift = build_int_cst (type, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tree nonneg = fold_build2_loc (input_location, GE_EXPR,
|
||||||
|
logical_type_node, args[0],
|
||||||
|
build_int_cst (TREE_TYPE (args[0]), 0));
|
||||||
|
bigshift = fold_build3_loc (input_location, COND_EXPR, type, nonneg,
|
||||||
|
build_int_cst (type, 0),
|
||||||
|
build_int_cst (type, -1));
|
||||||
|
}
|
||||||
|
|
||||||
/* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
|
/* The Fortran standard allows shift widths <= BIT_SIZE(I), whereas
|
||||||
gcc requires a shift width < BIT_SIZE(I), so we have to catch this
|
gcc requires a shift width < BIT_SIZE(I), so we have to catch this
|
||||||
special case. */
|
special case. */
|
||||||
|
@ -6373,7 +6386,7 @@ gfc_conv_intrinsic_shift (gfc_se * se, gfc_expr * expr, bool right_shift,
|
||||||
args[1], num_bits);
|
args[1], num_bits);
|
||||||
|
|
||||||
se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
|
se->expr = fold_build3_loc (input_location, COND_EXPR, type, cond,
|
||||||
build_int_cst (type, 0), se->expr);
|
bigshift, se->expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
|
/* ISHFT (I, SHIFT) = (abs (shift) >= BIT_SIZE (i))
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
2019-06-14 Harald Anlauf <anlauf@gmx.de>
|
||||||
|
|
||||||
|
PR fortran/90577
|
||||||
|
PR fortran/90578
|
||||||
|
* gfortran.dg/lrshift_1.f90: Adjust testcase.
|
||||||
|
* gfortran.dg/shiftalr_3.f90: New testcase.
|
||||||
|
|
||||||
2019-06-14 Steven G. Kargl <kargl@gcc.gnu.org>
|
2019-06-14 Steven G. Kargl <kargl@gcc.gnu.org>
|
||||||
|
|
||||||
PR fortran/89646
|
PR fortran/89646
|
||||||
|
|
|
@ -10,7 +10,7 @@ program test_rshift_lshift
|
||||||
1, 2, 127, 128, 129, huge(i)/2, huge(i) /)
|
1, 2, 127, 128, 129, huge(i)/2, huge(i) /)
|
||||||
|
|
||||||
do n = 1, size(i)
|
do n = 1, size(i)
|
||||||
do j = -30, 30
|
do j = 0, 31
|
||||||
if (lshift(i(n),j) /= c_lshift(i(n),j)) STOP 1
|
if (lshift(i(n),j) /= c_lshift(i(n),j)) STOP 1
|
||||||
if (rshift(i(n),j) /= c_rshift(i(n),j)) STOP 2
|
if (rshift(i(n),j) /= c_rshift(i(n),j)) STOP 2
|
||||||
end do
|
end do
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
! { dg-do run }
|
||||||
|
!
|
||||||
|
! Test shift intrinsics when the SHIFT argument equals BIT_SIZE(arg1).
|
||||||
|
|
||||||
|
program test
|
||||||
|
implicit none
|
||||||
|
! Test compile-time simplifications
|
||||||
|
if (ishft (-1, 32) /= 0) stop 1 ! 0 -> simplify_shift OK
|
||||||
|
if (ishft (-1,-32) /= 0) stop 2 ! 0 -> simplify_shift OK
|
||||||
|
if (shiftl (-1, 32) /= 0) stop 3 ! 0 -> simplify_shift OK
|
||||||
|
if (shiftr (-1, 32) /= 0) stop 4 ! 0 -> simplify_shift OK
|
||||||
|
if (shifta (-1, 32) /= -1) stop 5 ! -1 -> simplify_shift OK
|
||||||
|
if (rshift (-1, 32) /= -1) stop 6 ! -1 -> simplify_shift OK
|
||||||
|
if (lshift (-1, 32) /= 0) stop 7 ! 0 -> simplify_shift OK
|
||||||
|
! Test run-time
|
||||||
|
call foo (-1)
|
||||||
|
contains
|
||||||
|
subroutine foo (n)
|
||||||
|
integer(4) :: i, j, k, n
|
||||||
|
integer, parameter :: bb = bit_size (n)
|
||||||
|
! Test code generated by gfc_conv_intrinsic_ishft
|
||||||
|
i = ishft (n, bb) ! Logical (left) shift (Fortran 2008)
|
||||||
|
j = ishft (n,-bb) ! Logical (right) shift (Fortran 2008)
|
||||||
|
if (i /= 0) stop 11
|
||||||
|
if (j /= 0) stop 12
|
||||||
|
! Test code generated by gfc_conv_intrinsic_shift:
|
||||||
|
i = shiftl (n, bb) ! Logical left shift (Fortran 2008)
|
||||||
|
j = shiftr (n, bb) ! Logical right shift (Fortran 2008)
|
||||||
|
k = shifta (n, bb) ! Arithmetic right shift (Fortran 2008)
|
||||||
|
if (i /= 0) stop 13
|
||||||
|
if (j /= 0) stop 14
|
||||||
|
if (k /= -1) stop 15
|
||||||
|
i = lshift (n, bb) ! Logical left shift (GNU extension)
|
||||||
|
j = rshift (n, bb) ! Arithmetic right shift (GNU extension)
|
||||||
|
if (i /= 0) stop 16
|
||||||
|
if (j /= -1) stop 17
|
||||||
|
do i = bb-1,bb
|
||||||
|
if (shifta (n, i) /= -1) stop 18
|
||||||
|
if (rshift (n, i) /= -1) stop 19
|
||||||
|
end do
|
||||||
|
end subroutine foo
|
||||||
|
end program test
|
Loading…
Reference in New Issue