1! { dg-do run { target vect_simd_clones } } 2! { dg-additional-options "-msse2" { target sse2_runtime } } 3! { dg-additional-options "-mavx" { target avx_runtime } } 4 5module SIMD6_mod 6contains 7 function foo(p) result(r) 8 !$omp declare simd(foo) notinbranch 9 integer :: p, r 10 p = p + 10 11 r = p 12 end function foo 13 14 function myaddint(a, b, n) result(r) 15 implicit none 16 integer :: a(*), b(*), n, r 17 integer :: i 18 19 !$omp simd 20 do i=1, n 21 a(i) = foo(b(i)) ! foo is not called under a condition 22 end do 23 r = a(n) 24 25 end function myaddint 26 27 function myaddint_ref(a, b, n) result(r) 28 implicit none 29 integer :: a(*), b(*), n, r 30 integer :: i 31 32 do i=1, n 33 a(i) = foo(b(i)) 34 end do 35 r = a(n) 36 37 end function myaddint_ref 38 39 function goo(p) result(r) 40 !$omp declare simd(goo) inbranch 41 real :: p, r 42 p = p + 18.5 43 r = p 44 end function goo 45 46 function myaddfloat(x, y, n) result(r) 47 implicit none 48 real :: x(*), y(*), r 49 integer :: n 50 integer :: i 51 52 !$omp simd 53 do i=1, n 54 if (x(i) > y(i)) then 55 x(i) = goo(y(i)) 56 ! goo is called under the condition (or within a branch) 57 else 58 x(i) = y(i) 59 endif 60 end do 61 62 r = x(n) 63 end function myaddfloat 64 65 function myaddfloat_ref(x, y, n) result(r) 66 implicit none 67 real :: x(*), y(*), r 68 integer :: n 69 integer :: i 70 71 do i=1, n 72 if (x(i) > y(i)) then 73 x(i) = goo(y(i)) 74 else 75 x(i) = y(i) 76 endif 77 end do 78 79 r = x(n) 80 end function myaddfloat_ref 81 82 subroutine init (b, y, n) 83 integer :: b(128) 84 real :: y(128) 85 86 s = -1 87 do i = 1, n 88 b(i) = i*i*s 89 y(i) = i*i*s 90 s = -s 91 end do 92 93 end subroutine 94 95 subroutine init2 (b, y, n) 96 integer :: b(128) 97 real :: y(128) 98 99 do i = 1, n 100 b(i) = i 101 y(i) = i 102 end do 103 104 end subroutine 105 106 subroutine checkfloat (a, b, n) 107 integer :: i, n 108 real, parameter :: EPS = 0.000001 109 real :: diff, a(*), b(*) 110 do i = 1, n 111 diff = a(i) - b(i) 112 if (diff > EPS .or. -diff > EPS) stop 1 113 end do 114 end subroutine 115 116 subroutine checkint (a, b, n) 117 integer :: i, n, a(*), b(*) 118 do i = 1, n 119 if (a(i) .ne. b(i)) stop 2 120 end do 121 end subroutine 122 123 subroutine test () 124 integer :: a(128), a_ref(128), b(128), ri, ri_ref 125 real :: x(128), x_ref(128), y(128), rf, rf_ref 126 127 call init2(a, x, 128) 128 call init2(a_ref, x_ref, 128) 129 130 call init(b, y, 128) 131 132 ri = myaddint (a, b, 128) 133 rf = myaddfloat (x, y, 128) 134 135 call init(b, y, 128) 136 137 ri_ref = myaddint_ref (a_ref, b, 128) 138 rf_ref = myaddfloat_ref (x_ref, y, 128) 139 140 call checkint (a, a_ref, 128) 141 call checkfloat (x, x_ref, 128) 142 end subroutine 143 144end module 145 146program SIMD6 147 use SIMD6_mod, only: test 148 149 call test () 150 151end program 152