1! { dg-do run } 2! { dg-options "-fopenmp -fcray-pointer" } 3 4 use iso_c_binding, only : c_ptr, c_ptrdiff_t, c_loc 5 interface 6 subroutine foo (x, y, z, w) 7 use iso_c_binding, only : c_ptr 8 real, pointer :: x(:), y(:), w(:) 9 type(c_ptr) :: z 10 end subroutine 11 subroutine bar (x, y, z, w) 12 use iso_c_binding, only : c_ptr 13 real, pointer :: x(:), y(:), w(:) 14 type(c_ptr) :: z 15 end subroutine 16 subroutine baz (x, c) 17 real, pointer :: x(:) 18 real, allocatable :: c(:) 19 end subroutine 20 end interface 21 type dt 22 real, allocatable :: a(:) 23 end type 24 type (dt) :: b(64) 25 real, target :: a(4096+63) 26 real, pointer :: p(:), q(:), r(:), s(:) 27 real, allocatable :: c(:) 28 integer(c_ptrdiff_t) :: o 29 integer :: i 30 o = 64 - mod (loc (a), 64) 31 if (o == 64) o = 0 32 o = o / sizeof(0.0) 33 p => a(o + 1:o + 1024) 34 q => a(o + 1025:o + 2048) 35 r => a(o + 2049:o + 3072) 36 s => a(o + 3073:o + 4096) 37 do i = 1, 1024 38 p(i) = i 39 q(i) = i 40 r(i) = i 41 s(i) = i 42 end do 43 call foo (p, q, c_loc (r(1)), s) 44 do i = 1, 1024 45 if (p(i) /= i * i + 3 * i + 2) call abort 46 p(i) = i 47 end do 48 call bar (p, q, c_loc (r(1)), s) 49 do i = 1, 1024 50 if (p(i) /= i * i + 3 * i + 2) call abort 51 end do 52 ! Attempt to create 64-byte aligned allocatable 53 do i = 1, 64 54 allocate (c(1023 + i)) 55 if (iand (loc (c(1)), 63) == 0) exit 56 deallocate (c) 57 allocate (b(i)%a(1023 + i)) 58 allocate (c(1023 + i)) 59 if (iand (loc (c(1)), 63) == 0) exit 60 deallocate (c) 61 end do 62 if (allocated (c)) then 63 do i = 1, 1024 64 c(i) = 2 * i 65 end do 66 call baz (p, c) 67 do i = 1, 1024 68 if (p(i) /= i * i + 5 * i + 2) call abort 69 end do 70 end if 71end 72subroutine foo (x, y, z, w) 73 use iso_c_binding, only : c_ptr, c_f_pointer 74 real, pointer :: x(:), y(:), w(:), p(:) 75 type(c_ptr) :: z 76 integer :: i 77 real :: pt(1024) 78 pointer (ip, pt) 79 ip = loc (w) 80!$omp simd aligned (x, y : 64) 81 do i = 1, 1024 82 x(i) = x(i) * y(i) + 2.0 83 end do 84!$omp simd aligned (x, z : 64) private (p) 85 do i = 1, 1024 86 call c_f_pointer (z, p, shape=[1024]) 87 x(i) = x(i) + p(i) 88 end do 89!$omp simd aligned (x, ip : 64) 90 do i = 1, 1024 91 x(i) = x(i) + 2 * pt(i) 92 end do 93!$omp end simd 94end subroutine 95subroutine bar (x, y, z, w) 96 use iso_c_binding, only : c_ptr, c_f_pointer 97 real, pointer :: x(:), y(:), w(:), a(:), b(:) 98 type(c_ptr) :: z, c 99 integer :: i 100 real :: pt(1024) 101 pointer (ip, pt) 102 ip = loc (w) 103 a => x 104 b => y 105 c = z 106!$omp simd aligned (a, b : 64) 107 do i = 1, 1024 108 a(i) = a(i) * b(i) + 2.0 109 end do 110!$omp simd aligned (a, c : 64) 111 do i = 1, 1024 112 block 113 real, pointer :: p(:) 114 call c_f_pointer (c, p, shape=[1024]) 115 a(i) = a(i) + p(i) 116 end block 117 end do 118!$omp simd aligned (a, ip : 64) 119 do i = 1, 1024 120 a(i) = a(i) + 2 * pt(i) 121 end do 122!$omp end simd 123end subroutine 124subroutine baz (x, c) 125 real, pointer :: x(:) 126 real, allocatable :: c(:) 127 integer :: i 128!$omp simd aligned (x, c : 64) 129 do i = 1, 1024 130 x(i) = x(i) + c(i) 131 end do 132!$omp end simd 133end subroutine baz 134