Retro68/gcc/libgomp/testsuite/libgomp.fortran/examples-4/simd-6.f90
2018-12-28 16:30:48 +01:00

152 lines
2.8 KiB
Fortran

! { dg-do run { target vect_simd_clones } }
! { dg-additional-options "-msse2" { target sse2_runtime } }
! { dg-additional-options "-mavx" { target avx_runtime } }
module SIMD6_mod
contains
function foo(p) result(r)
!$omp declare simd(foo) notinbranch
integer :: p, r
p = p + 10
r = p
end function foo
function myaddint(a, b, n) result(r)
implicit none
integer :: a(*), b(*), n, r
integer :: i
!$omp simd
do i=1, n
a(i) = foo(b(i)) ! foo is not called under a condition
end do
r = a(n)
end function myaddint
function myaddint_ref(a, b, n) result(r)
implicit none
integer :: a(*), b(*), n, r
integer :: i
do i=1, n
a(i) = foo(b(i))
end do
r = a(n)
end function myaddint_ref
function goo(p) result(r)
!$omp declare simd(goo) inbranch
real :: p, r
p = p + 18.5
r = p
end function goo
function myaddfloat(x, y, n) result(r)
implicit none
real :: x(*), y(*), r
integer :: n
integer :: i
!$omp simd
do i=1, n
if (x(i) > y(i)) then
x(i) = goo(y(i))
! goo is called under the condition (or within a branch)
else
x(i) = y(i)
endif
end do
r = x(n)
end function myaddfloat
function myaddfloat_ref(x, y, n) result(r)
implicit none
real :: x(*), y(*), r
integer :: n
integer :: i
do i=1, n
if (x(i) > y(i)) then
x(i) = goo(y(i))
else
x(i) = y(i)
endif
end do
r = x(n)
end function myaddfloat_ref
subroutine init (b, y, n)
integer :: b(128)
real :: y(128)
s = -1
do i = 1, n
b(i) = i*i*s
y(i) = i*i*s
s = -s
end do
end subroutine
subroutine init2 (b, y, n)
integer :: b(128)
real :: y(128)
do i = 1, n
b(i) = i
y(i) = i
end do
end subroutine
subroutine checkfloat (a, b, n)
integer :: i, n
real, parameter :: EPS = 0.000001
real :: diff, a(*), b(*)
do i = 1, n
diff = a(i) - b(i)
if (diff > EPS .or. -diff > EPS) STOP 1
end do
end subroutine
subroutine checkint (a, b, n)
integer :: i, n, a(*), b(*)
do i = 1, n
if (a(i) .ne. b(i)) STOP 2
end do
end subroutine
subroutine test ()
integer :: a(128), a_ref(128), b(128), ri, ri_ref
real :: x(128), x_ref(128), y(128), rf, rf_ref
call init2(a, x, 128)
call init2(a_ref, x_ref, 128)
call init(b, y, 128)
ri = myaddint (a, b, 128)
rf = myaddfloat (x, y, 128)
call init(b, y, 128)
ri_ref = myaddint_ref (a_ref, b, 128)
rf_ref = myaddfloat_ref (x_ref, y, 128)
call checkint (a, a_ref, 128)
call checkfloat (x, x_ref, 128)
end subroutine
end module
program SIMD6
use SIMD6_mod, only: test
call test ()
end program