! { 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