1! Test lowering of arrays of POINTER. 2! 3! An array of pointer to T can be constructed by having an array of 4! derived type, where the derived type has a pointer to T 5! component. An entity with both the DIMENSION and POINTER attributes 6! is a pointer to an array of T and never an array of pointer to T in 7! Fortran. 8 9! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s 10 11module array_of_pointer_test 12 type t 13 integer, POINTER :: ip 14 end type t 15 16 type u 17 integer :: v 18 end type u 19 20 type tu 21 type(u), POINTER :: ip 22 end type tu 23 24 type ta 25 integer, POINTER :: ip(:) 26 end type ta 27 28 type tb 29 integer, POINTER :: ip(:,:) 30 end type tb 31 32 type tv 33 type(tu), POINTER :: jp(:) 34 end type tv 35 36 ! Derived types with type parameters hit a TODO. 37! type ct(l) 38! integer, len :: l 39! character(LEN=l), POINTER :: cp 40! end type ct 41 42! type cu(l) 43! integer, len :: l 44! character(LEN=l) :: cv 45! end type cu 46end module array_of_pointer_test 47 48subroutine s1(x,y) 49 use array_of_pointer_test 50 type(t) :: x(:) 51 integer :: y(:) 52 53 forall (i=1:10) 54 ! assign value to pointee variable 55 x(i)%ip = y(i) 56 end forall 57end subroutine s1 58 59! CHECK-LABEL: func @_QPs1( 60! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> {fir.bindc_name = "x"}, 61! CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "y"}) { 62! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 63! CHECK: %[[VAL_3:.*]] = arith.constant 1 : i32 64! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i32) -> index 65! CHECK: %[[VAL_5:.*]] = arith.constant 10 : i32 66! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index 67! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index 68! CHECK: %[[VAL_8:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 69! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32> 70! CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_4]] to %[[VAL_6]] step %[[VAL_7]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_8]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>) { 71! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_11]] : (index) -> i32 72! CHECK: fir.store %[[VAL_13]] to %[[VAL_2]] : !fir.ref<i32> 73! CHECK: %[[VAL_14:.*]] = arith.constant 1 : index 74! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 75! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64 76! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index 77! CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_14]] : index 78! CHECK: %[[VAL_19:.*]] = fir.array_fetch %[[VAL_9]], %[[VAL_18]] : (!fir.array<?xi32>, index) -> i32 79! CHECK: %[[VAL_20:.*]] = arith.constant 1 : index 80! CHECK: %[[VAL_21:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 81! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (i32) -> i64 82! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i64) -> index 83! CHECK: %[[VAL_24:.*]] = arith.subi %[[VAL_23]], %[[VAL_20]] : index 84! CHECK: %[[VAL_25:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}> 85! CHECK: %[[VAL_26:.*]] = fir.array_access %[[VAL_12]], %[[VAL_24]], %[[VAL_25]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, index, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<i32>>> 86! CHECK: %[[VAL_27:.*]] = fir.load %[[VAL_26]] : !fir.ref<!fir.box<!fir.ptr<i32>>> 87! CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_27]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32> 88! CHECK: fir.store %[[VAL_19]] to %[[VAL_28]] : !fir.ptr<i32> 89! CHECK: %[[VAL_29:.*]] = fir.array_amend %[[VAL_12]], %[[VAL_26]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.ref<!fir.box<!fir.ptr<i32>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 90! CHECK: fir.result %[[VAL_29]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 91! CHECK: } 92! CHECK: fir.array_merge_store %[[VAL_8]], %[[VAL_30:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> 93! CHECK: return 94! CHECK: } 95 96subroutine s1_1(x,y) 97 use array_of_pointer_test 98 type(t) :: x(10) 99 integer :: y(10) 100 101 forall (i=1:10) 102 ! assign value to pointee variable 103 x(i)%ip = y(i) 104 end forall 105end subroutine s1_1 106 107! CHECK-LABEL: func @_QPs1_1( 108! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref<!fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> {fir.bindc_name = "x"}, 109! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "y"}) { 110! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 111! CHECK: %[[VAL_3:.*]] = arith.constant 10 : index 112! CHECK: %[[VAL_4:.*]] = arith.constant 10 : index 113! CHECK: %[[VAL_5:.*]] = arith.constant 1 : i32 114! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index 115! CHECK: %[[VAL_7:.*]] = arith.constant 10 : i32 116! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i32) -> index 117! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index 118! CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> 119! CHECK: %[[VAL_11:.*]] = fir.array_load %[[VAL_0]](%[[VAL_10]]) : (!fir.ref<!fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>>, !fir.shape<1>) -> !fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 120! CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> 121! CHECK: %[[VAL_13:.*]] = fir.array_load %[[VAL_1]](%[[VAL_12]]) : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> !fir.array<10xi32> 122! CHECK: %[[VAL_14:.*]] = fir.do_loop %[[VAL_15:.*]] = %[[VAL_6]] to %[[VAL_8]] step %[[VAL_9]] unordered iter_args(%[[VAL_16:.*]] = %[[VAL_11]]) -> (!fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>) { 123! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_15]] : (index) -> i32 124! CHECK: fir.store %[[VAL_17]] to %[[VAL_2]] : !fir.ref<i32> 125! CHECK: %[[VAL_18:.*]] = arith.constant 1 : index 126! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 127! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (i32) -> i64 128! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index 129! CHECK: %[[VAL_22:.*]] = arith.subi %[[VAL_21]], %[[VAL_18]] : index 130! CHECK: %[[VAL_23:.*]] = fir.array_fetch %[[VAL_13]], %[[VAL_22]] : (!fir.array<10xi32>, index) -> i32 131! CHECK: %[[VAL_24:.*]] = arith.constant 1 : index 132! CHECK: %[[VAL_25:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 133! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i32) -> i64 134! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i64) -> index 135! CHECK: %[[VAL_28:.*]] = arith.subi %[[VAL_27]], %[[VAL_24]] : index 136! CHECK: %[[VAL_29:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}> 137! CHECK: %[[VAL_30:.*]] = fir.array_access %[[VAL_16]], %[[VAL_28]], %[[VAL_29]] : (!fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, index, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<i32>>> 138! CHECK: %[[VAL_31:.*]] = fir.load %[[VAL_30]] : !fir.ref<!fir.box<!fir.ptr<i32>>> 139! CHECK: %[[VAL_32:.*]] = fir.box_addr %[[VAL_31]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32> 140! CHECK: fir.store %[[VAL_23]] to %[[VAL_32]] : !fir.ptr<i32> 141! CHECK: %[[VAL_33:.*]] = fir.array_amend %[[VAL_16]], %[[VAL_30]] : (!fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.ref<!fir.box<!fir.ptr<i32>>>) -> !fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 142! CHECK: fir.result %[[VAL_33]] : !fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 143! CHECK: } 144! CHECK: fir.array_merge_store %[[VAL_11]], %[[VAL_34:.*]] to %[[VAL_0]] : !fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.ref<!fir.array<10x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> 145! CHECK: return 146! CHECK: } 147 148! Dependent type assignment, TODO 149!subroutine s1_2(x,y,l) 150! use array_of_pointer_test 151! type(ct(l)) :: x(10) 152! character(l) :: y(10) 153 154! forall (i=1:10) 155 ! assign value to pointee variable 156! x(i)%cp = y(i) 157! end forall 158!end subroutine s1_2 159 160subroutine s2(x,y) 161 use array_of_pointer_test 162 type(t) :: x(:) 163 integer, TARGET :: y(:) 164 165 forall (i=1:10) 166 ! assign address to POINTER 167 x(i)%ip => y(i) 168 end forall 169end subroutine s2 170 171! CHECK-LABEL: func @_QPs2( 172! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> {fir.bindc_name = "x"}, 173! CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "y", fir.target}) { 174! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 175! CHECK: %[[VAL_3:.*]] = arith.constant 1 : i32 176! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i32) -> index 177! CHECK: %[[VAL_5:.*]] = arith.constant 10 : i32 178! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index 179! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index 180! CHECK: %[[VAL_8:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 181! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32> 182! CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_4]] to %[[VAL_6]] step %[[VAL_7]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_8]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>) { 183! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_11]] : (index) -> i32 184! CHECK: fir.store %[[VAL_13]] to %[[VAL_2]] : !fir.ref<i32> 185! CHECK: %[[VAL_14:.*]] = arith.constant 1 : index 186! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 187! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64 188! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index 189! CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_14]] : index 190! CHECK: %[[VAL_19:.*]] = fir.array_access %[[VAL_9]], %[[VAL_18]] : (!fir.array<?xi32>, index) -> !fir.ref<i32> 191! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (!fir.ref<i32>) -> !fir.ptr<i32> 192! CHECK: %[[VAL_21:.*]] = fir.embox %[[VAL_20]] : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>> 193! CHECK: %[[VAL_22:.*]] = arith.constant 1 : index 194! CHECK: %[[VAL_23:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 195! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_23]] : (i32) -> i64 196! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (i64) -> index 197! CHECK: %[[VAL_26:.*]] = arith.subi %[[VAL_25]], %[[VAL_22]] : index 198! CHECK: %[[VAL_27:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}> 199! CHECK: %[[VAL_28:.*]] = fir.array_update %[[VAL_12]], %[[VAL_21]], %[[VAL_26]], %[[VAL_27]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.ptr<i32>>, index, !fir.field) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 200! CHECK: fir.result %[[VAL_28]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 201! CHECK: } 202! CHECK: fir.array_merge_store %[[VAL_8]], %[[VAL_29:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> 203! CHECK: return 204! CHECK: } 205 206subroutine s2_1(x,y) 207 use array_of_pointer_test 208 type(t) :: x(:) 209 integer, POINTER :: y(:) 210 211 forall (i=1:10) 212 ! assign address to POINTER 213 x(i)%ip => y(i) 214 end forall 215end subroutine s2_1 216 217! CHECK-LABEL: func @_QPs2_1( 218! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> {fir.bindc_name = "x"}, 219! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {fir.bindc_name = "y"}) { 220! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 221! CHECK: %[[VAL_3:.*]] = arith.constant 1 : i32 222! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i32) -> index 223! CHECK: %[[VAL_5:.*]] = arith.constant 10 : i32 224! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index 225! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index 226! CHECK: %[[VAL_8:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 227! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> 228! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index 229! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_9]], %[[VAL_10]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index) 230! CHECK: %[[VAL_12:.*]] = fir.shift %[[VAL_11]]#0 : (index) -> !fir.shift<1> 231! CHECK: %[[VAL_13:.*]] = fir.array_load %[[VAL_9]](%[[VAL_12]]) : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shift<1>) -> !fir.array<?xi32> 232! CHECK: %[[VAL_14:.*]] = fir.do_loop %[[VAL_15:.*]] = %[[VAL_4]] to %[[VAL_6]] step %[[VAL_7]] unordered iter_args(%[[VAL_16:.*]] = %[[VAL_8]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>) { 233! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_15]] : (index) -> i32 234! CHECK: fir.store %[[VAL_17]] to %[[VAL_2]] : !fir.ref<i32> 235! CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 236! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> i64 237! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (i64) -> index 238! CHECK: %[[VAL_21:.*]] = arith.subi %[[VAL_20]], %[[VAL_11]]#0 : index 239! CHECK: %[[VAL_22:.*]] = fir.array_access %[[VAL_13]], %[[VAL_21]] : (!fir.array<?xi32>, index) -> !fir.ref<i32> 240! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (!fir.ref<i32>) -> !fir.ptr<i32> 241! CHECK: %[[VAL_24:.*]] = fir.embox %[[VAL_23]] : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>> 242! CHECK: %[[VAL_25:.*]] = arith.constant 1 : index 243! CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 244! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i32) -> i64 245! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i64) -> index 246! CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_28]], %[[VAL_25]] : index 247! CHECK: %[[VAL_30:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}> 248! CHECK: %[[VAL_31:.*]] = fir.array_update %[[VAL_16]], %[[VAL_24]], %[[VAL_29]], %[[VAL_30]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.ptr<i32>>, index, !fir.field) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 249! CHECK: fir.result %[[VAL_31]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 250! CHECK: } 251! CHECK: fir.array_merge_store %[[VAL_8]], %[[VAL_32:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> 252! CHECK: return 253! CHECK: } 254 255subroutine s2_2(x,y) 256 use array_of_pointer_test 257 type(t) :: x(:) 258 integer, ALLOCATABLE, TARGET :: y(:) 259 260 forall (i=1:10) 261 ! assign address to POINTER 262 x(i)%ip => y(i) 263 end forall 264end subroutine s2_2 265 266! CHECK-LABEL: func @_QPs2_2( 267! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> {fir.bindc_name = "x"}, 268! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "y", fir.target}) { 269! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 270! CHECK: %[[VAL_3:.*]] = arith.constant 1 : i32 271! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i32) -> index 272! CHECK: %[[VAL_5:.*]] = arith.constant 10 : i32 273! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index 274! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index 275! CHECK: %[[VAL_8:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 276! CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> 277! CHECK: %[[VAL_10:.*]] = arith.constant 0 : index 278! CHECK: %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_9]], %[[VAL_10]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index) 279! CHECK: %[[VAL_12:.*]] = fir.box_addr %[[VAL_9]] : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>> 280! CHECK: %[[VAL_13:.*]] = fir.shape_shift %[[VAL_11]]#0, %[[VAL_11]]#1 : (index, index) -> !fir.shapeshift<1> 281! CHECK: %[[VAL_14:.*]] = fir.array_load %[[VAL_12]](%[[VAL_13]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.array<?xi32> 282! CHECK: %[[VAL_15:.*]] = fir.do_loop %[[VAL_16:.*]] = %[[VAL_4]] to %[[VAL_6]] step %[[VAL_7]] unordered iter_args(%[[VAL_17:.*]] = %[[VAL_8]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>) { 283! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_16]] : (index) -> i32 284! CHECK: fir.store %[[VAL_18]] to %[[VAL_2]] : !fir.ref<i32> 285! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 286! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (i32) -> i64 287! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i64) -> index 288! CHECK: %[[VAL_22:.*]] = arith.subi %[[VAL_21]], %[[VAL_11]]#0 : index 289! CHECK: %[[VAL_23:.*]] = fir.array_access %[[VAL_14]], %[[VAL_22]] : (!fir.array<?xi32>, index) -> !fir.ref<i32> 290! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_23]] : (!fir.ref<i32>) -> !fir.ptr<i32> 291! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_24]] : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>> 292! CHECK: %[[VAL_26:.*]] = arith.constant 1 : index 293! CHECK: %[[VAL_27:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 294! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i32) -> i64 295! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_28]] : (i64) -> index 296! CHECK: %[[VAL_30:.*]] = arith.subi %[[VAL_29]], %[[VAL_26]] : index 297! CHECK: %[[VAL_31:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}> 298! CHECK: %[[VAL_32:.*]] = fir.array_update %[[VAL_17]], %[[VAL_25]], %[[VAL_30]], %[[VAL_31]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.ptr<i32>>, index, !fir.field) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 299! CHECK: fir.result %[[VAL_32]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 300! CHECK: } 301! CHECK: fir.array_merge_store %[[VAL_8]], %[[VAL_33:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> 302! CHECK: return 303! CHECK: } 304 305subroutine s2_3(x) 306 use array_of_pointer_test 307 type(t) :: x(:) 308 ! This is legal, but a bad idea. 309 integer, ALLOCATABLE, TARGET :: y(:) 310 311 forall (i=1:10) 312 ! assign address to POINTER 313 x(i)%ip => y(i) 314 end forall 315 ! x's pointers will remain associated, and may point to deallocated y. 316end subroutine s2_3 317 318! CHECK-LABEL: func @_QPs2_3( 319! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> {fir.bindc_name = "x"}) { 320! CHECK: %[[VAL_1:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 321! CHECK: %[[VAL_2:.*]] = fir.alloca !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "y", fir.target, uniq_name = "_QFs2_3Ey"} 322! CHECK: %[[VAL_3:.*]] = fir.alloca !fir.heap<!fir.array<?xi32>> {uniq_name = "_QFs2_3Ey.addr"} 323! CHECK: %[[VAL_4:.*]] = fir.alloca index {uniq_name = "_QFs2_3Ey.lb0"} 324! CHECK: %[[VAL_5:.*]] = fir.alloca index {uniq_name = "_QFs2_3Ey.ext0"} 325! CHECK: %[[VAL_6:.*]] = fir.zero_bits !fir.heap<!fir.array<?xi32>> 326! CHECK: fir.store %[[VAL_6]] to %[[VAL_3]] : !fir.ref<!fir.heap<!fir.array<?xi32>>> 327! CHECK: %[[VAL_7:.*]] = arith.constant 1 : i32 328! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i32) -> index 329! CHECK: %[[VAL_9:.*]] = arith.constant 10 : i32 330! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index 331! CHECK: %[[VAL_11:.*]] = arith.constant 1 : index 332! CHECK: %[[VAL_12:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 333! CHECK: %[[VAL_13:.*]] = fir.load %[[VAL_4]] : !fir.ref<index> 334! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_5]] : !fir.ref<index> 335! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_3]] : !fir.ref<!fir.heap<!fir.array<?xi32>>> 336! CHECK: %[[VAL_16:.*]] = fir.shape_shift %[[VAL_13]], %[[VAL_14]] : (index, index) -> !fir.shapeshift<1> 337! CHECK: %[[VAL_17:.*]] = fir.array_load %[[VAL_15]](%[[VAL_16]]) : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>) -> !fir.array<?xi32> 338! CHECK: %[[VAL_18:.*]] = fir.do_loop %[[VAL_19:.*]] = %[[VAL_8]] to %[[VAL_10]] step %[[VAL_11]] unordered iter_args(%[[VAL_20:.*]] = %[[VAL_12]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>) { 339! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (index) -> i32 340! CHECK: fir.store %[[VAL_21]] to %[[VAL_1]] : !fir.ref<i32> 341! CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32> 342! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i32) -> i64 343! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_23]] : (i64) -> index 344! CHECK: %[[VAL_25:.*]] = arith.subi %[[VAL_24]], %[[VAL_13]] : index 345! CHECK: %[[VAL_26:.*]] = fir.array_access %[[VAL_17]], %[[VAL_25]] : (!fir.array<?xi32>, index) -> !fir.ref<i32> 346! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (!fir.ref<i32>) -> !fir.ptr<i32> 347! CHECK: %[[VAL_28:.*]] = fir.embox %[[VAL_27]] : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>> 348! CHECK: %[[VAL_29:.*]] = arith.constant 1 : index 349! CHECK: %[[VAL_30:.*]] = fir.load %[[VAL_1]] : !fir.ref<i32> 350! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (i32) -> i64 351! CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (i64) -> index 352! CHECK: %[[VAL_33:.*]] = arith.subi %[[VAL_32]], %[[VAL_29]] : index 353! CHECK: %[[VAL_34:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}> 354! CHECK: %[[VAL_35:.*]] = fir.array_update %[[VAL_20]], %[[VAL_28]], %[[VAL_33]], %[[VAL_34]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.ptr<i32>>, index, !fir.field) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 355! CHECK: fir.result %[[VAL_35]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 356! CHECK: } 357! CHECK: fir.array_merge_store %[[VAL_12]], %[[VAL_36:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> 358! CHECK: return 359! CHECK: } 360 361! Dependent type - TODO 362!subroutine s2_4(x,y,l) 363! use array_of_pointer_test 364! type(ct(l)) :: x(:) 365! character(l), TARGET :: y(:) 366 367! forall (i=1:10) 368 ! assign address to POINTER 369! x(i)%cp => y(i) 370! end forall 371!end subroutine s2_4 372 373subroutine s3(x,y) 374 use array_of_pointer_test 375 type(tu) :: x(:) 376 integer :: y(:) 377 378 forall (i=1:10) 379 ! assign value to variable, indirecting through box 380 x(i)%ip%v = y(i) 381 end forall 382end subroutine s3 383 384! CHECK-LABEL: func @_QPs3( 385! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>> {fir.bindc_name = "x"}, 386! CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "y"}) { 387! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 388! CHECK: %[[VAL_3:.*]] = arith.constant 1 : i32 389! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i32) -> index 390! CHECK: %[[VAL_5:.*]] = arith.constant 10 : i32 391! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index 392! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index 393! CHECK: %[[VAL_8:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>> 394! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32> 395! CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_4]] to %[[VAL_6]] step %[[VAL_7]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_8]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>) { 396! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_11]] : (index) -> i32 397! CHECK: fir.store %[[VAL_13]] to %[[VAL_2]] : !fir.ref<i32> 398! CHECK: %[[VAL_14:.*]] = arith.constant 1 : index 399! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 400! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64 401! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index 402! CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_14]] : index 403! CHECK: %[[VAL_19:.*]] = fir.array_fetch %[[VAL_9]], %[[VAL_18]] : (!fir.array<?xi32>, index) -> i32 404! CHECK: %[[VAL_20:.*]] = arith.constant 1 : index 405! CHECK: %[[VAL_21:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 406! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (i32) -> i64 407! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i64) -> index 408! CHECK: %[[VAL_24:.*]] = arith.subi %[[VAL_23]], %[[VAL_20]] : index 409! CHECK: %[[VAL_25:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}> 410! CHECK: %[[VAL_26:.*]] = fir.field_index v, !fir.type<_QMarray_of_pointer_testTu{v:i32}> 411! CHECK: %[[VAL_27:.*]] = fir.array_access %[[VAL_12]], %[[VAL_24]], %[[VAL_25]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>, index, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>> 412! CHECK: %[[VAL_28:.*]] = fir.load %[[VAL_27]] : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>> 413! CHECK: %[[VAL_29:.*]] = fir.coordinate_of %[[VAL_28]], %[[VAL_26]] : (!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>, !fir.field) -> !fir.ref<i32> 414! CHECK: fir.store %[[VAL_19]] to %[[VAL_29]] : !fir.ref<i32> 415! CHECK: %[[VAL_30:.*]] = fir.array_amend %[[VAL_12]], %[[VAL_27]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>, !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>> 416! CHECK: fir.result %[[VAL_30]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>> 417! CHECK: } 418! CHECK: fir.array_merge_store %[[VAL_8]], %[[VAL_31:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>> 419! CHECK: return 420! CHECK: } 421 422subroutine s3_1(x,y) 423 use array_of_pointer_test 424 type(tu) :: x(:) 425 integer :: y(:) 426 427 forall (i=1:10) 428 ! assign value to variable, indirecting through box 429 x(i)%ip%v = y(i) 430 end forall 431end subroutine s3_1 432 433! CHECK-LABEL: func @_QPs3_1( 434! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>> {fir.bindc_name = "x"}, 435! CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "y"}) { 436! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 437! CHECK: %[[VAL_3:.*]] = arith.constant 1 : i32 438! CHECK: %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i32) -> index 439! CHECK: %[[VAL_5:.*]] = arith.constant 10 : i32 440! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index 441! CHECK: %[[VAL_7:.*]] = arith.constant 1 : index 442! CHECK: %[[VAL_8:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>> 443! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32> 444! CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_4]] to %[[VAL_6]] step %[[VAL_7]] unordered iter_args(%[[VAL_12:.*]] = %[[VAL_8]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>) { 445! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_11]] : (index) -> i32 446! CHECK: fir.store %[[VAL_13]] to %[[VAL_2]] : !fir.ref<i32> 447! CHECK: %[[VAL_14:.*]] = arith.constant 1 : index 448! CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 449! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64 450! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (i64) -> index 451! CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]], %[[VAL_14]] : index 452! CHECK: %[[VAL_19:.*]] = fir.array_fetch %[[VAL_9]], %[[VAL_18]] : (!fir.array<?xi32>, index) -> i32 453! CHECK: %[[VAL_20:.*]] = arith.constant 1 : index 454! CHECK: %[[VAL_21:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 455! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (i32) -> i64 456! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i64) -> index 457! CHECK: %[[VAL_24:.*]] = arith.subi %[[VAL_23]], %[[VAL_20]] : index 458! CHECK: %[[VAL_25:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}> 459! CHECK: %[[VAL_26:.*]] = fir.field_index v, !fir.type<_QMarray_of_pointer_testTu{v:i32}> 460! CHECK: %[[VAL_27:.*]] = fir.array_access %[[VAL_12]], %[[VAL_24]], %[[VAL_25]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>, index, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>> 461! CHECK: %[[VAL_28:.*]] = fir.load %[[VAL_27]] : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>> 462! CHECK: %[[VAL_29:.*]] = fir.coordinate_of %[[VAL_28]], %[[VAL_26]] : (!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>, !fir.field) -> !fir.ref<i32> 463! CHECK: fir.store %[[VAL_19]] to %[[VAL_29]] : !fir.ref<i32> 464! CHECK: %[[VAL_30:.*]] = fir.array_amend %[[VAL_12]], %[[VAL_27]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>, !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>> 465! CHECK: fir.result %[[VAL_30]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>> 466! CHECK: } 467! CHECK: fir.array_merge_store %[[VAL_8]], %[[VAL_31:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>> 468! CHECK: return 469! CHECK: } 470 471! Slice a target array and assign the box to a pointer of rank-1 field. 472! RHS is an array section. Hits a TODO. 473subroutine s4(x,y) 474 use array_of_pointer_test 475 type(ta) :: x(:) 476 integer, TARGET :: y(:) 477 478 forall (i=1:10) 479 ! TODO: auto boxing of ranked RHS 480! x(i)%ip => y(i:i+1) 481 end forall 482end subroutine s4 483 484! Most other Fortran implementations cannot compile the following 2 cases, s5 485! and s5_1. 486subroutine s5(x,y,z,n1,n2) 487 use array_of_pointer_test 488 type(ta) :: x(:) 489 type(tb) :: y(:) 490 type(ta), TARGET :: z(:) 491 492 forall (i=1:10) 493 ! Convert the rank-1 array to a rank-2 array on assignment 494 y(i)%ip(1:n1,1:n2) => z(i)%ip 495 end forall 496end subroutine s5 497 498! CHECK-LABEL: func @_QPs5( 499! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>> {fir.bindc_name = "x"}, 500! CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}>>> {fir.bindc_name = "y"}, 501! CHECK-SAME: %[[VAL_2:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>> {fir.bindc_name = "z", fir.target}, 502! CHECK-SAME: %[[VAL_3:.*]]: !fir.ref<i32> {fir.bindc_name = "n1"}, 503! CHECK-SAME: %[[VAL_4:.*]]: !fir.ref<i32> {fir.bindc_name = "n2"}) { 504! CHECK: %[[VAL_5:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 505! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 506! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> index 507! CHECK: %[[VAL_8:.*]] = arith.constant 10 : i32 508! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (i32) -> index 509! CHECK: %[[VAL_10:.*]] = arith.constant 1 : index 510! CHECK: %[[VAL_11:.*]] = fir.array_load %[[VAL_1]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}>> 511! CHECK: %[[VAL_12:.*]] = fir.array_load %[[VAL_2]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> 512! CHECK: %[[VAL_13:.*]] = fir.do_loop %[[VAL_14:.*]] = %[[VAL_7]] to %[[VAL_9]] step %[[VAL_10]] unordered iter_args(%[[VAL_15:.*]] = %[[VAL_11]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}>>) { 513! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_14]] : (index) -> i32 514! CHECK: fir.store %[[VAL_16]] to %[[VAL_5]] : !fir.ref<i32> 515! CHECK: %[[VAL_17:.*]] = arith.constant 1 : i64 516! CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> 517! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> i64 518! CHECK: %[[VAL_20:.*]] = arith.constant 1 : i64 519! CHECK: %[[VAL_21:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32> 520! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (i32) -> i64 521! CHECK: %[[VAL_23:.*]] = arith.constant 1 : index 522! CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32> 523! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (i32) -> i64 524! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i64) -> index 525! CHECK: %[[VAL_27:.*]] = arith.subi %[[VAL_26]], %[[VAL_23]] : index 526! CHECK: %[[VAL_28:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}> 527! CHECK: %[[VAL_29:.*]] = fir.array_fetch %[[VAL_12]], %[[VAL_27]], %[[VAL_28]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, index, !fir.field) -> !fir.box<!fir.ptr<!fir.array<?xi32>>> 528! CHECK: %[[VAL_30:.*]] = arith.constant 1 : index 529! CHECK: %[[VAL_31:.*]] = fir.load %[[VAL_5]] : !fir.ref<i32> 530! CHECK: %[[VAL_32:.*]] = fir.convert %[[VAL_31]] : (i32) -> i64 531! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (i64) -> index 532! CHECK: %[[VAL_34:.*]] = arith.subi %[[VAL_33]], %[[VAL_30]] : index 533! CHECK: %[[VAL_35:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}> 534! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_29]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>) -> !fir.box<!fir.ptr<!fir.array<?x?xi32>>> 535! CHECK: %[[VAL_37:.*]] = fir.shape_shift %[[VAL_17]], %[[VAL_19]], %[[VAL_20]], %[[VAL_22]] : (i64, i64, i64, i64) -> !fir.shapeshift<2> 536! CHECK: %[[VAL_38:.*]] = fir.rebox %[[VAL_36]](%[[VAL_37]]) : (!fir.box<!fir.ptr<!fir.array<?x?xi32>>>, !fir.shapeshift<2>) -> !fir.box<!fir.ptr<!fir.array<?x?xi32>>> 537! CHECK: %[[VAL_39:.*]] = fir.array_update %[[VAL_15]], %[[VAL_38]], %[[VAL_34]], %[[VAL_35]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}>>, !fir.box<!fir.ptr<!fir.array<?x?xi32>>>, index, !fir.field) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}>> 538! CHECK: fir.result %[[VAL_39]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}>> 539! CHECK: } 540! CHECK: fir.array_merge_store %[[VAL_11]], %[[VAL_40:.*]] to %[[VAL_1]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtb{ip:!fir.box<!fir.ptr<!fir.array<?x?xi32>>>}>>> 541! CHECK: return 542! CHECK: } 543 544! RHS is an array section. Hits a TODO. 545subroutine s5_1(x,y,z,n1,n2) 546 use array_of_pointer_test 547 type(ta) :: x(:) 548 type(tb) :: y(:) 549 type(ta), TARGET :: z(:) 550 551 forall (i=1:10) 552 ! Slice a rank 1 array and save the slice to the box. 553! x(i)%ip => z(i)%ip(1::n1+1) 554 end forall 555end subroutine s5_1 556 557subroutine s6(x,y) 558 use array_of_pointer_test 559 type(tv) :: x(:) 560 integer, target :: y(:) 561 562 forall (i=1:10, j=2:20:2) 563 ! Two box indirections. 564 x(i)%jp(j)%ip%v = y(i) 565 end forall 566end subroutine s6 567 568! CHECK-LABEL: func @_QPs6( 569! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>>> {fir.bindc_name = "x"}, 570! CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "y", fir.target}) { 571! CHECK: %[[VAL_2:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "j"} 572! CHECK: %[[VAL_3:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 573! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 574! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> index 575! CHECK: %[[VAL_6:.*]] = arith.constant 10 : i32 576! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> index 577! CHECK: %[[VAL_8:.*]] = arith.constant 1 : index 578! CHECK: %[[VAL_9:.*]] = arith.constant 2 : i32 579! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> index 580! CHECK: %[[VAL_11:.*]] = arith.constant 20 : i32 581! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i32) -> index 582! CHECK: %[[VAL_13:.*]] = arith.constant 2 : i32 583! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i32) -> index 584! CHECK: %[[VAL_15:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>> 585! CHECK: %[[VAL_16:.*]] = fir.array_load %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32> 586! CHECK: %[[VAL_17:.*]] = fir.do_loop %[[VAL_18:.*]] = %[[VAL_5]] to %[[VAL_7]] step %[[VAL_8]] unordered iter_args(%[[VAL_19:.*]] = %[[VAL_15]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>>) { 587! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_18]] : (index) -> i32 588! CHECK: fir.store %[[VAL_20]] to %[[VAL_3]] : !fir.ref<i32> 589! CHECK: %[[VAL_21:.*]] = fir.do_loop %[[VAL_22:.*]] = %[[VAL_10]] to %[[VAL_12]] step %[[VAL_14]] unordered iter_args(%[[VAL_23:.*]] = %[[VAL_19]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>>) { 590! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_22]] : (index) -> i32 591! CHECK: fir.store %[[VAL_24]] to %[[VAL_2]] : !fir.ref<i32> 592! CHECK: %[[VAL_25:.*]] = arith.constant 1 : index 593! CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> 594! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i32) -> i64 595! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i64) -> index 596! CHECK: %[[VAL_29:.*]] = arith.subi %[[VAL_28]], %[[VAL_25]] : index 597! CHECK: %[[VAL_30:.*]] = fir.array_fetch %[[VAL_16]], %[[VAL_29]] : (!fir.array<?xi32>, index) -> i32 598! CHECK: %[[VAL_31:.*]] = arith.constant 1 : index 599! CHECK: %[[VAL_32:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> 600! CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (i32) -> i64 601! CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_33]] : (i64) -> index 602! CHECK: %[[VAL_35:.*]] = arith.subi %[[VAL_34]], %[[VAL_31]] : index 603! CHECK: %[[VAL_36:.*]] = fir.field_index jp, !fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}> 604! CHECK: %[[VAL_37:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 605! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (i32) -> i64 606! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_38]] : (i64) -> index 607! CHECK: %[[VAL_40:.*]] = arith.subi %[[VAL_39]], %[[VAL_31]] : index 608! CHECK: %[[VAL_41:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}> 609! CHECK: %[[VAL_42:.*]] = fir.field_index v, !fir.type<_QMarray_of_pointer_testTu{v:i32}> 610! CHECK: %[[VAL_43:.*]] = fir.array_access %[[VAL_23]], %[[VAL_35]], %[[VAL_36]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>>, index, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>> 611! CHECK: %[[VAL_44:.*]] = fir.load %[[VAL_43]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>> 612! CHECK: %[[VAL_45:.*]] = fir.coordinate_of %[[VAL_44]], %[[VAL_40]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>, index) -> !fir.ref<!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>> 613! CHECK: %[[VAL_46:.*]] = fir.coordinate_of %[[VAL_45]], %[[VAL_41]] : (!fir.ref<!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>> 614! CHECK: %[[VAL_47:.*]] = fir.load %[[VAL_46]] : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>> 615! CHECK: %[[VAL_48:.*]] = fir.coordinate_of %[[VAL_47]], %[[VAL_42]] : (!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>, !fir.field) -> !fir.ref<i32> 616! CHECK: fir.store %[[VAL_30]] to %[[VAL_48]] : !fir.ref<i32> 617! CHECK: %[[VAL_49:.*]] = fir.array_amend %[[VAL_23]], %[[VAL_43]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>>, !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>> 618! CHECK: fir.result %[[VAL_49]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>> 619! CHECK: } 620! CHECK: fir.result %[[VAL_50:.*]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>> 621! CHECK: } 622! CHECK: fir.array_merge_store %[[VAL_15]], %[[VAL_51:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtv{jp:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QMarray_of_pointer_testTtu{ip:!fir.box<!fir.ptr<!fir.type<_QMarray_of_pointer_testTu{v:i32}>>>}>>>>}>>> 623! CHECK: return 624! CHECK: } 625 626subroutine s7(x,y,n) 627 use array_of_pointer_test 628 type(t) x(:) 629 integer, TARGET :: y(:) 630 ! Introduce a crossing dependence 631 forall (i=1:n) 632 x(i)%ip => y(x(n+1-i)%ip) 633 end forall 634end subroutine s7 635 636! CHECK-LABEL: func @_QPs7( 637! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> {fir.bindc_name = "x"}, 638! CHECK-SAME: %[[VAL_1:.*]]: !fir.box<!fir.array<?xi32>> {fir.bindc_name = "y", fir.target}, 639! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) { 640! CHECK: %[[VAL_3:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 641! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 642! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> index 643! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 644! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> index 645! CHECK: %[[VAL_8:.*]] = arith.constant 1 : index 646! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 647! CHECK: %[[VAL_10:.*]] = fir.array_load %[[VAL_1]] : (!fir.box<!fir.array<?xi32>>) -> !fir.array<?xi32> 648! CHECK: %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_5]] to %[[VAL_7]] step %[[VAL_8]] unordered iter_args(%[[VAL_13:.*]] = %[[VAL_9]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>) { 649! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (index) -> i32 650! CHECK: fir.store %[[VAL_14]] to %[[VAL_3]] : !fir.ref<i32> 651! CHECK: %[[VAL_15:.*]] = arith.constant 1 : index 652! CHECK: %[[VAL_16:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 653! CHECK: %[[VAL_17:.*]] = arith.constant 1 : i32 654! CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_16]], %[[VAL_17]] : i32 655! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> 656! CHECK: %[[VAL_20:.*]] = arith.subi %[[VAL_18]], %[[VAL_19]] : i32 657! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_20]] : (i32) -> i64 658! CHECK: %[[VAL_22:.*]] = arith.constant 1 : i64 659! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_21]], %[[VAL_22]] : i64 660! CHECK: %[[VAL_24:.*]] = fir.coordinate_of %[[VAL_0]], %[[VAL_23]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>>, i64) -> !fir.ref<!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 661! CHECK: %[[VAL_25:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}> 662! CHECK: %[[VAL_26:.*]] = fir.coordinate_of %[[VAL_24]], %[[VAL_25]] : (!fir.ref<!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<i32>>> 663! CHECK: %[[VAL_27:.*]] = fir.load %[[VAL_26]] : !fir.ref<!fir.box<!fir.ptr<i32>>> 664! CHECK: %[[VAL_28:.*]] = fir.box_addr %[[VAL_27]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32> 665! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_28]] : !fir.ptr<i32> 666! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i32) -> i64 667! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (i64) -> index 668! CHECK: %[[VAL_32:.*]] = arith.subi %[[VAL_31]], %[[VAL_15]] : index 669! CHECK: %[[VAL_33:.*]] = fir.array_access %[[VAL_10]], %[[VAL_32]] : (!fir.array<?xi32>, index) -> !fir.ref<i32> 670! CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_33]] : (!fir.ref<i32>) -> !fir.ptr<i32> 671! CHECK: %[[VAL_35:.*]] = fir.embox %[[VAL_34]] : (!fir.ptr<i32>) -> !fir.box<!fir.ptr<i32>> 672! CHECK: %[[VAL_36:.*]] = arith.constant 1 : index 673! CHECK: %[[VAL_37:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> 674! CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_37]] : (i32) -> i64 675! CHECK: %[[VAL_39:.*]] = fir.convert %[[VAL_38]] : (i64) -> index 676! CHECK: %[[VAL_40:.*]] = arith.subi %[[VAL_39]], %[[VAL_36]] : index 677! CHECK: %[[VAL_41:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}> 678! CHECK: %[[VAL_42:.*]] = fir.array_update %[[VAL_13]], %[[VAL_35]], %[[VAL_40]], %[[VAL_41]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.ptr<i32>>, index, !fir.field) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 679! CHECK: fir.result %[[VAL_42]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>> 680! CHECK: } 681! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_43:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTt{ip:!fir.box<!fir.ptr<i32>>}>>> 682! CHECK: return 683! CHECK: } 684 685subroutine s8(x,y,n) 686 use array_of_pointer_test 687 type(ta) x(:) 688 integer, POINTER :: y(:) 689 forall (i=1:n) 690 x(i)%ip(i:) => y 691 end forall 692end subroutine s8 693 694! CHECK-LABEL: func @_QPs8( 695! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>> {fir.bindc_name = "x"}, 696! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {fir.bindc_name = "y"}, 697! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"}) { 698! CHECK: %[[VAL_3:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 699! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 700! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> index 701! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 702! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> index 703! CHECK: %[[VAL_8:.*]] = arith.constant 1 : index 704! CHECK: %[[VAL_9:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> 705! CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> 706! CHECK: %[[VAL_11:.*]] = arith.constant 0 : index 707! CHECK: %[[VAL_12:.*]]:3 = fir.box_dims %[[VAL_10]], %[[VAL_11]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index) 708! CHECK: %[[VAL_13:.*]] = fir.shift %[[VAL_12]]#0 : (index) -> !fir.shift<1> 709! CHECK: %[[VAL_14:.*]] = fir.do_loop %[[VAL_15:.*]] = %[[VAL_5]] to %[[VAL_7]] step %[[VAL_8]] unordered iter_args(%[[VAL_16:.*]] = %[[VAL_9]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) { 710! CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_15]] : (index) -> i32 711! CHECK: fir.store %[[VAL_17]] to %[[VAL_3]] : !fir.ref<i32> 712! CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> 713! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> i64 714! CHECK: %[[VAL_20:.*]] = fir.rebox %[[VAL_10]](%[[VAL_13]]) : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>> 715! CHECK: %[[VAL_21:.*]] = arith.constant 1 : index 716! CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> 717! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i32) -> i64 718! CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_23]] : (i64) -> index 719! CHECK: %[[VAL_25:.*]] = arith.subi %[[VAL_24]], %[[VAL_21]] : index 720! CHECK: %[[VAL_26:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}> 721! CHECK: %[[VAL_27:.*]] = fir.shift %[[VAL_19]] : (i64) -> !fir.shift<1> 722! CHECK: %[[VAL_28:.*]] = fir.rebox %[[VAL_20]](%[[VAL_27]]) : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>> 723! CHECK: %[[VAL_29:.*]] = fir.array_update %[[VAL_16]], %[[VAL_28]], %[[VAL_25]], %[[VAL_26]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.box<!fir.ptr<!fir.array<?xi32>>>, index, !fir.field) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> 724! CHECK: fir.result %[[VAL_29]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> 725! CHECK: } 726! CHECK: fir.array_merge_store %[[VAL_9]], %[[VAL_30:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>> 727! CHECK: return 728! CHECK: } 729 730subroutine s8_1(x,y,n1,n2) 731 use array_of_pointer_test 732 type(ta) x(:) 733 integer, POINTER :: y(:) 734 forall (i=1:n1) 735 x(i)%ip(i:n2+1+i) => y 736 end forall 737end subroutine s8_1 738 739! CHECK-LABEL: func @_QPs8_1( 740! CHECK-SAME: %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>> {fir.bindc_name = "x"}, 741! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> {fir.bindc_name = "y"}, 742! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref<i32> {fir.bindc_name = "n1"}, 743! CHECK-SAME: %[[VAL_3:.*]]: !fir.ref<i32> {fir.bindc_name = "n2"}) { 744! CHECK: %[[VAL_4:.*]] = fir.alloca i32 {adapt.valuebyref, bindc_name = "i"} 745! CHECK: %[[VAL_5:.*]] = arith.constant 1 : i32 746! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> index 747! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_2]] : !fir.ref<i32> 748! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i32) -> index 749! CHECK: %[[VAL_9:.*]] = arith.constant 1 : index 750! CHECK: %[[VAL_10:.*]] = fir.array_load %[[VAL_0]] : (!fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>>) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> 751! CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_1]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>> 752! CHECK: %[[VAL_12:.*]] = arith.constant 0 : index 753! CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_11]], %[[VAL_12]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index) 754! CHECK: %[[VAL_14:.*]] = fir.shift %[[VAL_13]]#0 : (index) -> !fir.shift<1> 755! CHECK: %[[VAL_15:.*]] = fir.do_loop %[[VAL_16:.*]] = %[[VAL_6]] to %[[VAL_8]] step %[[VAL_9]] unordered iter_args(%[[VAL_17:.*]] = %[[VAL_10]]) -> (!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) { 756! CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_16]] : (index) -> i32 757! CHECK: fir.store %[[VAL_18]] to %[[VAL_4]] : !fir.ref<i32> 758! CHECK: %[[VAL_19:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32> 759! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (i32) -> i64 760! CHECK: %[[VAL_21:.*]] = fir.load %[[VAL_3]] : !fir.ref<i32> 761! CHECK: %[[VAL_22:.*]] = arith.constant 1 : i32 762! CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_21]], %[[VAL_22]] : i32 763! CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32> 764! CHECK: %[[VAL_25:.*]] = arith.addi %[[VAL_23]], %[[VAL_24]] : i32 765! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i32) -> i64 766! CHECK: %[[VAL_27:.*]] = fir.rebox %[[VAL_11]](%[[VAL_14]]) : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>> 767! CHECK: %[[VAL_28:.*]] = arith.constant 1 : index 768! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_4]] : !fir.ref<i32> 769! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i32) -> i64 770! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_30]] : (i64) -> index 771! CHECK: %[[VAL_32:.*]] = arith.subi %[[VAL_31]], %[[VAL_28]] : index 772! CHECK: %[[VAL_33:.*]] = fir.field_index ip, !fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}> 773! CHECK: %[[VAL_34:.*]] = fir.shape_shift %[[VAL_20]], %[[VAL_26]] : (i64, i64) -> !fir.shapeshift<1> 774! CHECK: %[[VAL_35:.*]] = fir.rebox %[[VAL_27]](%[[VAL_34]]) : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shapeshift<1>) -> !fir.box<!fir.ptr<!fir.array<?xi32>>> 775! CHECK: %[[VAL_36:.*]] = fir.array_update %[[VAL_17]], %[[VAL_35]], %[[VAL_32]], %[[VAL_33]] : (!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.box<!fir.ptr<!fir.array<?xi32>>>, index, !fir.field) -> !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> 776! CHECK: fir.result %[[VAL_36]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> 777! CHECK: } 778! CHECK: fir.array_merge_store %[[VAL_10]], %[[VAL_37:.*]] to %[[VAL_0]] : !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.box<!fir.array<?x!fir.type<_QMarray_of_pointer_testTta{ip:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>> 779! CHECK: return 780! CHECK: } 781 782subroutine s8_2(x,y,n) 783 use array_of_pointer_test 784 type(ta) x(:) 785 integer, TARGET :: y(:) 786 forall (i=1:n) 787! x(i)%ip(i:) => y 788 end forall 789end subroutine s8_2 790 791subroutine s8_3(x,y,n1,n2) 792 use array_of_pointer_test 793 type(ta) x(:) 794 integer, TARGET :: y(:) 795 forall (i=1:n1) 796! x(i)%ip(i:n2+1+i) => y 797 end forall 798end subroutine s8_3 799 800subroutine s8_4(x,y,n) 801 use array_of_pointer_test 802 type(ta) x(:) 803 integer, ALLOCATABLE, TARGET :: y(:) 804 forall (i=1:n) 805! x(i)%ip(i:) => y 806 end forall 807end subroutine s8_4 808 809subroutine s8_5(x,y,n1,n2) 810 use array_of_pointer_test 811 type(ta) x(:) 812 integer, ALLOCATABLE, TARGET :: y(:) 813 forall (i=1:n1) 814! x(i)%ip(i:n2+1+i) => y 815 end forall 816end subroutine s8_5 817