[prev in list] [next in list] [prev in thread] [next in thread]
List: gcc-fortran
Subject: Re: [FORTRAN PATCH]: Improved integer SIGN intrinsic (& bug-fix)
From: FX Coudert <fxcoudert () gmail ! com>
Date: 2007-01-20 12:34:22
Message-ID: 8F1ADC02-76C7-48F2-A541-BF8D0F004AC7 () gmail ! com
[Download RAW message or body]
> 2007-01-19 Roger Sayle <roger@eyesopen.com>
>
> * trans-intrinsic.c (gfc_conv_intrinsic_sign): New branchless
> implementation for the SIGN intrinsic with integral operands.
> (gfc_conv_intrinsic_minmax): Fix whitespace.
OK for 4.3 and 4.2, as is. Please also include in your commit the
attached testcase, that includes Brooks' testcase and Steve's
comment, as well as tests for the largest integer value of each
integer kind.
For 4.1, it would be better to only add a call to gfc_evaluate_now.
If you don't intend to do it, could you file a PR so that it doesn't
get lost?
FX
["sign_1.f90" (sign_1.f90)]
! { dg-do run }
! Testcase for SIGN() with integer arguments
! Check that:
! + SIGN() evaluates its arguments only once
! + SIGN() works on large values
! + SIGN() works with parameter arguments
program sign1
implicit none
integer(kind=1), parameter :: one1 = 1_1, mone1 = -1_1
integer(kind=2), parameter :: one2 = 1_2, mone2 = -1_2
integer(kind=4), parameter :: one4 = 1_4, mone4 = -1_4
integer(kind=8), parameter :: one8 = 1_8, mone8 = -1_8
integer(kind=1) :: i1, j1
integer(kind=2) :: i2, j2
integer(kind=4) :: i4, j4
integer(kind=8) :: i8, j8
integer :: i = 1
i1 = huge(0_1) ; j1 = -huge(0_1)
if (sign(i1, j1) /= j1) call abort()
if (sign(j1, i1) /= i1) call abort()
if (sign(i1,one1) /= i1 .or. sign(j1,one1) /= i1) call abort()
if (sign(i1,mone1) /= j1 .or. sign(j1,mone1) /= j1) call abort()
i2 = huge(0_2) ; j2 = -huge(0_2)
if (sign(i2, j2) /= j2) call abort()
if (sign(j2, i2) /= i2) call abort()
if (sign(i2,one2) /= i2 .or. sign(j2,one2) /= i2) call abort()
if (sign(i2,mone2) /= j2 .or. sign(j2,mone2) /= j2) call abort()
i4 = huge(0_4) ; j4 = -huge(0_4)
if (sign(i4, j4) /= j4) call abort()
if (sign(j4, i4) /= i4) call abort()
if (sign(i4,one4) /= i4 .or. sign(j4,one4) /= i4) call abort()
if (sign(i4,mone4) /= j4 .or. sign(j4,mone4) /= j4) call abort()
i8 = huge(0_8) ; j8 = -huge(0_8)
if (sign(i8, j8) /= j8) call abort()
if (sign(j8, i8) /= i8) call abort()
if (sign(i8,one8) /= i8 .or. sign(j8,one8) /= i8) call abort()
if (sign(i8,mone8) /= j8 .or. sign(j8,mone8) /= j8) call abort()
if (sign(foo(i), 1) /= 1) call abort
if (sign(foo(i), -1) /= -2) call abort
if (sign(42, foo(i)) /= 42) call abort
if (sign(42, -foo(i)) /= -42) call abort
if (i /= 5) call abort
if (sign(bar(), 1) /= 1) call abort
if (sign(bar(), -1) /= -2) call abort
if (sign(17, bar()) /= 17) call abort
if (sign(17, -bar()) /= -17) call abort
if (bar() /= 5) call abort
contains
integer function foo(i)
integer :: i
foo = i
i = i + 1
end function
integer function bar()
integer, save :: i = 0
i = i + 1
bar = i
end function
end
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic