xref: /llvm-project/flang/test/Lower/pointer-assignments.f90 (revision f35f863a88f83332bef9605ef4cfe4f05c066efb)
1a1425019SValentin Clement! Test lowering of pointer assignments
2*f35f863aSjeanPerier! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s
3a1425019SValentin Clement
4a1425019SValentin Clement
5a1425019SValentin Clement! Note that p => NULL() are tested in pointer-disassociate.f90
6a1425019SValentin Clement
7a1425019SValentin Clement! -----------------------------------------------------------------------------
8a1425019SValentin Clement!     Test simple pointer assignments to contiguous right-hand side
9a1425019SValentin Clement! -----------------------------------------------------------------------------
10a1425019SValentin Clement
11a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_scalar(
12a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<f32>>>{{.*}}, %[[x:.*]]: !fir.ref<f32> {{{.*}}, fir.target})
13a1425019SValentin Clementsubroutine test_scalar(p, x)
14a1425019SValentin Clement  real, target :: x
15a1425019SValentin Clement  real, pointer :: p
16a1425019SValentin Clement  ! CHECK: %[[box:.*]] = fir.embox %[[x]] : (!fir.ref<f32>) -> !fir.box<!fir.ptr<f32>>
17a1425019SValentin Clement  ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<f32>>>
18a1425019SValentin Clement  p => x
19a1425019SValentin Clementend subroutine
20a1425019SValentin Clement
21a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_scalar_char(
22a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>>{{.*}}, %[[x:.*]]: !fir.boxchar<1> {{{.*}}, fir.target})
23a1425019SValentin Clementsubroutine test_scalar_char(p, x)
24a1425019SValentin Clement  character(*), target :: x
25a1425019SValentin Clement  character(:), pointer :: p
26a1425019SValentin Clement  ! CHECK: %[[c:.*]]:2 = fir.unboxchar %arg1 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
27a1425019SValentin Clement  ! CHECK: %[[box:.*]] = fir.embox %[[c]]#0 typeparams %[[c]]#1 : (!fir.ref<!fir.char<1,?>>, index) -> !fir.box<!fir.ptr<!fir.char<1,?>>>
28a1425019SValentin Clement  ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<!fir.char<1,?>>>>
29a1425019SValentin Clement  p => x
30a1425019SValentin Clementend subroutine
31a1425019SValentin Clement
32a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array(
33a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>{{.*}}, %[[x:.*]]: !fir.ref<!fir.array<100xf32>> {{{.*}}, fir.target})
34a1425019SValentin Clementsubroutine test_array(p, x)
35a1425019SValentin Clement  real, target :: x(100)
36a1425019SValentin Clement  real, pointer :: p(:)
37a1425019SValentin Clement  ! CHECK: %[[shape:.*]] = fir.shape %c100{{.*}}
38a1425019SValentin Clement  ! CHECK: %[[box:.*]] = fir.embox %[[x]](%[[shape]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
39a1425019SValentin Clement  ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
40a1425019SValentin Clement  p => x
41a1425019SValentin Clementend subroutine
42a1425019SValentin Clement
43a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_char(
44a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>{{.*}}, %[[x:.*]]: !fir.boxchar<1> {{{.*}}, fir.target}) {
45a1425019SValentin Clementsubroutine test_array_char(p, x)
46a1425019SValentin Clement  character(*), target :: x(100)
47a1425019SValentin Clement  character(:), pointer :: p(:)
48a1425019SValentin Clement  ! CHECK: %[[c:.*]]:2 = fir.unboxchar %arg1 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
49a1425019SValentin Clement  ! CHECK: %[[xaddr:.*]] = fir.convert %[[c]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<100x!fir.char<1,?>>>
50a1425019SValentin Clement  ! CHECK-DAG: %[[xaddr2:.*]] = fir.convert %[[xaddr]] : (!fir.ref<!fir.array<100x!fir.char<1,?>>>) -> !fir.ref<!fir.array<?x!fir.char<1,?>>>
51a1425019SValentin Clement  ! CHECK-DAG: %[[shape:.*]] = fir.shape %c100{{.*}}
52a1425019SValentin Clement  ! CHECK: %[[box:.*]] = fir.embox %[[xaddr2]](%[[shape]]) typeparams %[[c]]#1
53a1425019SValentin Clement  ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.char<1,?>>>>>
54a1425019SValentin Clement  p => x
55a1425019SValentin Clementend subroutine
56a1425019SValentin Clement
57a1425019SValentin Clement! Test 10.2.2.3 point 10: lower bounds requirements:
58a1425019SValentin Clement! pointer takes lbounds from rhs if no bounds spec.
59a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_with_lbs(
60a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
61a1425019SValentin Clementsubroutine test_array_with_lbs(p, x)
62a1425019SValentin Clement  real, target :: x(51:150)
63a1425019SValentin Clement  real, pointer :: p(:)
64a1425019SValentin Clement  ! CHECK: %[[shape:.*]] = fir.shape_shift %c51{{.*}}, %c100{{.*}}
65a1425019SValentin Clement  ! CHECK: %[[box:.*]] = fir.embox %{{.*}}(%[[shape]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
66a1425019SValentin Clement  ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
67a1425019SValentin Clement  p => x
68a1425019SValentin Clementend subroutine
69a1425019SValentin Clement
701ee9080dSJonathon Penix! Test that the lhs takes the bounds from rhs.
711ee9080dSJonathon Penix! CHECK-LABEL: func @_QPtest_pointer_component(
721ee9080dSJonathon Penix! CHECK-SAME: %[[temp:.*]]: !fir.ref<!fir.type<_QFtest_pointer_componentTmytype{ptr:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>> {fir.bindc_name = "temp"}, %[[temp_ptr:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>> {fir.bindc_name = "temp_ptr"}) {
731ee9080dSJonathon Penixsubroutine test_pointer_component(temp, temp_ptr)
741ee9080dSJonathon Penix  type mytype
751ee9080dSJonathon Penix    real, pointer :: ptr(:)
761ee9080dSJonathon Penix  end type mytype
771ee9080dSJonathon Penix  type(mytype) :: temp
781ee9080dSJonathon Penix  real, pointer :: temp_ptr(:)
791ee9080dSJonathon Penix  ! CHECK: %[[ptr_addr:.*]] = fir.coordinate_of %[[temp]], %{{.*}} : (!fir.ref<!fir.type<_QFtest_pointer_componentTmytype{ptr:!fir.box<!fir.ptr<!fir.array<?xf32>>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
801ee9080dSJonathon Penix  ! CHECK: %[[ptr:.*]] = fir.load %[[ptr_addr]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
811ee9080dSJonathon Penix  ! CHECK: %[[dims:.*]]:3 = fir.box_dims %[[ptr]], %{{.*}} : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
821ee9080dSJonathon Penix  ! CHECK: %[[shift:.*]] = fir.shift %[[dims]]#0 : (index) -> !fir.shift<1>
831ee9080dSJonathon Penix  ! CHECK: %[[arr_box:.*]] = fir.rebox %[[ptr]](%[[shift]]) : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>) -> !fir.box<!fir.array<?xf32>>
841ee9080dSJonathon Penix  ! CHECK: %[[shift2:.*]] = fir.shift %[[dims]]#0 : (index) -> !fir.shift<1>
851ee9080dSJonathon Penix  ! CHECK: %[[final_box:.*]] = fir.rebox %[[arr_box]](%[[shift2]]) : (!fir.box<!fir.array<?xf32>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
861ee9080dSJonathon Penix  ! CHECK: fir.store %[[final_box]] to %[[temp_ptr]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
871ee9080dSJonathon Penix  temp_ptr => temp%ptr
881ee9080dSJonathon Penixend subroutine
891ee9080dSJonathon Penix
90a1425019SValentin Clement! -----------------------------------------------------------------------------
91a1425019SValentin Clement!    Test pointer assignments with bound specs to contiguous right-hand side
92a1425019SValentin Clement! -----------------------------------------------------------------------------
93a1425019SValentin Clement
94a1425019SValentin Clement! Test 10.2.2.3 point 10: lower bounds requirements:
95a1425019SValentin Clement! pointer takes lbounds from bound spec if specified
96a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_with_new_lbs(
97a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
98a1425019SValentin Clementsubroutine test_array_with_new_lbs(p, x)
99a1425019SValentin Clement  real, target :: x(51:150)
100a1425019SValentin Clement  real, pointer :: p(:)
101a1425019SValentin Clement  ! CHECK: %[[shape:.*]] = fir.shape_shift %c4{{.*}}, %c100{{.*}}
102a1425019SValentin Clement  ! CHECK: %[[box:.*]] = fir.embox %{{.*}}(%[[shape]]) : (!fir.ref<!fir.array<100xf32>>, !fir.shapeshift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
103a1425019SValentin Clement  ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
104a1425019SValentin Clement  p(4:) => x
105a1425019SValentin Clementend subroutine
106a1425019SValentin Clement
107a1425019SValentin Clement! Test F2018 10.2.2.3 point 9: bounds remapping
108a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_remap(
109a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>>{{.*}}, %[[x:.*]]: !fir.ref<!fir.array<100xf32>> {{{.*}}, fir.target})
110a1425019SValentin Clementsubroutine test_array_remap(p, x)
111a1425019SValentin Clement  real, target :: x(100)
112a1425019SValentin Clement  real, pointer :: p(:, :)
113a1425019SValentin Clement  ! CHECK-DAG: %[[c2_idx:.*]] = fir.convert %c2{{.*}} : (i64) -> index
114a1425019SValentin Clement  ! CHECK-DAG: %[[c11_idx:.*]] = fir.convert %c11{{.*}} : (i64) -> index
115a1425019SValentin Clement  ! CHECK-DAG: %[[diff0:.*]] = arith.subi %[[c11_idx]], %[[c2_idx]] : index
116a1425019SValentin Clement  ! CHECK-DAG: %[[ext0:.*]] = arith.addi %[[diff0:.*]], %c1{{.*}} : index
117a1425019SValentin Clement  ! CHECK-DAG: %[[c3_idx:.*]] = fir.convert %c3{{.*}} : (i64) -> index
118a1425019SValentin Clement  ! CHECK-DAG: %[[c12_idx:.*]] = fir.convert %c12{{.*}} : (i64) -> index
119a1425019SValentin Clement  ! CHECK-DAG: %[[diff1:.*]] = arith.subi %[[c12_idx]], %[[c3_idx]] : index
120a1425019SValentin Clement  ! CHECK-DAG: %[[ext1:.*]] = arith.addi %[[diff1]], %c1{{.*}} : index
121a1425019SValentin Clement  ! CHECK-DAG: %[[addrCast:.*]] = fir.convert %[[x]] : (!fir.ref<!fir.array<100xf32>>) -> !fir.ref<!fir.array<?x?xf32>>
122a1425019SValentin Clement  ! CHECK: %[[shape:.*]] = fir.shape_shift %c2{{.*}}, %[[ext0]], %c3{{.*}}, %[[ext1]]
123a1425019SValentin Clement  ! CHECK: %[[box:.*]] = fir.embox %[[addrCast]](%[[shape]]) : (!fir.ref<!fir.array<?x?xf32>>, !fir.shapeshift<2>) -> !fir.box<!fir.ptr<!fir.array<?x?xf32>>>
124a1425019SValentin Clement  ! CHECK: fir.store %[[box]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>>
125a1425019SValentin Clement  p(2:11, 3:12) => x
126a1425019SValentin Clementend subroutine
127a1425019SValentin Clement
128a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_char_remap(
129a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?x!fir.char<1,?>>>>>{{.*}}, %[[x:.*]]: !fir.boxchar<1> {{{.*}}, fir.target})
130a1425019SValentin Clementsubroutine test_array_char_remap(p, x)
131a1425019SValentin Clement  ! CHECK: %[[unbox:.*]]:2 = fir.unboxchar %[[x]]
132a1425019SValentin Clement  character(*), target :: x(100)
133a1425019SValentin Clement  character(:), pointer :: p(:, :)
134a1425019SValentin Clement  ! CHECK: subi
135a1425019SValentin Clement  ! CHECK: %[[ext0:.*]] = arith.addi
136a1425019SValentin Clement  ! CHECK: subi
137a1425019SValentin Clement  ! CHECK: %[[ext1:.*]] = arith.addi
138a1425019SValentin Clement  ! CHECK: %[[shape:.*]] = fir.shape_shift %c2{{.*}}, %[[ext0]], %c3{{.*}}, %[[ext1]]
139a1425019SValentin Clement  ! CHECK: %[[box:.*]] = fir.embox %{{.*}}(%[[shape]]) typeparams %[[unbox]]#1 : (!fir.ref<!fir.array<?x?x!fir.char<1,?>>>, !fir.shapeshift<2>, index) -> !fir.box<!fir.ptr<!fir.array<?x?x!fir.char<1,?>>>>
140a1425019SValentin Clement  ! CHECK: fir.store %[[box]] to %[[p]]
141a1425019SValentin Clement  p(2:11, 3:12) => x
142a1425019SValentin Clementend subroutine
143a1425019SValentin Clement
144a1425019SValentin Clement! -----------------------------------------------------------------------------
145a1425019SValentin Clement!  Test simple pointer assignments to non contiguous right-hand side
146a1425019SValentin Clement! -----------------------------------------------------------------------------
147a1425019SValentin Clement
148a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_non_contig_rhs(
149a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>{{.*}}, %[[x:.*]]: !fir.box<!fir.array<?xf32>> {{{.*}}, fir.target})
150a1425019SValentin Clementsubroutine test_array_non_contig_rhs(p, x)
151a1425019SValentin Clement  real, target :: x(:)
152a1425019SValentin Clement  real, pointer :: p(:)
153a1425019SValentin Clement  ! CHECK: %[[rebox:.*]] = fir.rebox %[[x]] : (!fir.box<!fir.array<?xf32>>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
154a1425019SValentin Clement  ! CHECK: fir.store %[[rebox]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
155a1425019SValentin Clement  p => x
156a1425019SValentin Clementend subroutine
157a1425019SValentin Clement
158a1425019SValentin Clement! Test 10.2.2.3 point 10: lower bounds requirements:
159a1425019SValentin Clement! pointer takes lbounds from rhs if no bounds spec.
160a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_non_contig_rhs_lbs(
161a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>{{.*}}, %[[x:.*]]: !fir.box<!fir.array<?xf32>> {{{.*}}, fir.target})
162a1425019SValentin Clementsubroutine test_array_non_contig_rhs_lbs(p, x)
163a1425019SValentin Clement  real, target :: x(7:)
164a1425019SValentin Clement  real, pointer :: p(:)
165a1425019SValentin Clement  ! CHECK: %[[c7_idx:.*]] = fir.convert %c7{{.*}} : (i64) -> index
166a1425019SValentin Clement  ! CHECK: %[[shift:.*]] = fir.shift %[[c7_idx]] : (index) -> !fir.shift<1>
167a1425019SValentin Clement  ! CHECK: %[[rebox:.*]] = fir.rebox %[[x]](%[[shift]]) : (!fir.box<!fir.array<?xf32>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
168a1425019SValentin Clement  ! CHECK: fir.store %[[rebox]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
169a1425019SValentin Clement  p => x
170a1425019SValentin Clementend subroutine
171a1425019SValentin Clement
172a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_non_contig_rhs2(
173a1425019SValentin Clement! CHECK-SAME:                                      %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<!fir.array<200xf32>> {{{.*}}, fir.target}) {
174a1425019SValentin Clement! CHECK:         %[[VAL_2:.*]] = arith.constant 200 : index
175a1425019SValentin Clement! CHECK:         %[[VAL_3:.*]] = arith.constant 10 : i64
176a1425019SValentin Clement! CHECK:         %[[VAL_4:.*]] = fir.convert %[[VAL_3]] : (i64) -> index
177a1425019SValentin Clement! CHECK:         %[[VAL_5:.*]] = arith.constant 3 : i64
178a1425019SValentin Clement! CHECK:         %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i64) -> index
179a1425019SValentin Clement! CHECK:         %[[VAL_7:.*]] = arith.constant 160 : i64
180a1425019SValentin Clement! CHECK:         %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i64) -> index
181a1425019SValentin Clement! CHECK:         %[[VAL_9:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
182a1425019SValentin Clement! CHECK:         %[[VAL_10:.*]] = fir.slice %[[VAL_4]], %[[VAL_8]], %[[VAL_6]] : (index, index, index) -> !fir.slice<1>
18313f9089aSPeixin Qiao! CHECK:         %[[VAL_11:.*]] = fir.embox %[[VAL_1]](%[[VAL_9]]) {{\[}}%[[VAL_10]]] : (!fir.ref<!fir.array<200xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<51xf32>>
18413f9089aSPeixin Qiao! CHECK:         %[[VAL_12:.*]] = fir.rebox %[[VAL_11]] : (!fir.box<!fir.array<51xf32>>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
185a1425019SValentin Clement! CHECK:         fir.store %[[VAL_12]] to %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
186a1425019SValentin Clement! CHECK:         return
187a1425019SValentin Clement! CHECK:       }
188a1425019SValentin Clement
189a1425019SValentin Clementsubroutine test_array_non_contig_rhs2(p, x)
190a1425019SValentin Clement  real, target :: x(200)
191a1425019SValentin Clement  real, pointer :: p(:)
192a1425019SValentin Clement  p => x(10:160:3)
193a1425019SValentin Clementend subroutine
194a1425019SValentin Clement
195a1425019SValentin Clement! -----------------------------------------------------------------------------
196a1425019SValentin Clement!  Test pointer assignments with bound specs to non contiguous right-hand side
197a1425019SValentin Clement! -----------------------------------------------------------------------------
198a1425019SValentin Clement
199a1425019SValentin Clement
200a1425019SValentin Clement! Test 10.2.2.3 point 10: lower bounds requirements:
201a1425019SValentin Clement! pointer takes lbounds from bound spec if specified
202a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_non_contig_rhs_new_lbs(
203a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>{{.*}}, %[[x:.*]]: !fir.box<!fir.array<?xf32>> {{{.*}}, fir.target})
204a1425019SValentin Clementsubroutine test_array_non_contig_rhs_new_lbs(p, x)
205a1425019SValentin Clement  real, target :: x(7:)
206a1425019SValentin Clement  real, pointer :: p(:)
207a1425019SValentin Clement  ! CHECK: %[[shift:.*]] = fir.shift %c4{{.*}}
208a1425019SValentin Clement  ! CHECK: %[[rebox:.*]] = fir.rebox %[[x]](%[[shift]]) : (!fir.box<!fir.array<?xf32>>, !fir.shift<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
209a1425019SValentin Clement
210a1425019SValentin Clement  ! CHECK: fir.store %[[rebox]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
211a1425019SValentin Clement  p(4:) => x
212a1425019SValentin Clementend subroutine
213a1425019SValentin Clement
214a1425019SValentin Clement! Test F2018 10.2.2.3 point 9: bounds remapping
215a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_non_contig_remap(
216a1425019SValentin Clement! CHECK-SAME: %[[p:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>>{{.*}}, %[[x:.*]]: !fir.box<!fir.array<?xf32>> {{{.*}}, fir.target})
217a1425019SValentin Clementsubroutine test_array_non_contig_remap(p, x)
218a1425019SValentin Clement  real, target :: x(:)
219a1425019SValentin Clement  real, pointer :: p(:, :)
220a1425019SValentin Clement  ! CHECK: subi
221a1425019SValentin Clement  ! CHECK: %[[ext0:.*]] = arith.addi
222a1425019SValentin Clement  ! CHECK: subi
223a1425019SValentin Clement  ! CHECK: %[[ext1:.*]] = arith.addi
224a1425019SValentin Clement  ! CHECK: %[[shape:.*]] = fir.shape_shift %{{.*}}, %[[ext0]], %{{.*}}, %[[ext1]]
225a1425019SValentin Clement  ! CHECK: %[[rebox:.*]] = fir.rebox %[[x]](%[[shape]]) : (!fir.box<!fir.array<?xf32>>, !fir.shapeshift<2>) -> !fir.box<!fir.ptr<!fir.array<?x?xf32>>>
226a1425019SValentin Clement  ! CHECK: fir.store %[[rebox]] to %[[p]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>>
227a1425019SValentin Clement  p(2:11, 3:12) => x
228a1425019SValentin Clementend subroutine
229a1425019SValentin Clement
230a1425019SValentin Clement! Test remapping a slice
231a1425019SValentin Clement
232a1425019SValentin Clement! CHECK-LABEL: func @_QPtest_array_non_contig_remap_slice(
233a1425019SValentin Clement! CHECK-SAME:                                             %[[VAL_0:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>>{{.*}}, %[[VAL_1:.*]]: !fir.ref<!fir.array<400xf32>> {{{.*}}, fir.target}) {
234a1425019SValentin Clement! CHECK:         %[[VAL_2:.*]] = arith.constant 400 : index
235a1425019SValentin Clement! CHECK:         %[[VAL_3:.*]] = arith.constant 2 : i64
236a1425019SValentin Clement! CHECK:         %[[VAL_4:.*]] = arith.constant 11 : i64
237a1425019SValentin Clement! CHECK:         %[[VAL_5:.*]] = arith.constant 3 : i64
238a1425019SValentin Clement! CHECK:         %[[VAL_6:.*]] = arith.constant 12 : i64
239a1425019SValentin Clement! CHECK:         %[[VAL_7:.*]] = arith.constant 51 : i64
240a1425019SValentin Clement! CHECK:         %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i64) -> index
241a1425019SValentin Clement! CHECK:         %[[VAL_9:.*]] = arith.constant 3 : i64
242a1425019SValentin Clement! CHECK:         %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i64) -> index
243a1425019SValentin Clement! CHECK:         %[[VAL_11:.*]] = arith.constant 350 : i64
244a1425019SValentin Clement! CHECK:         %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i64) -> index
245a1425019SValentin Clement! CHECK:         %[[VAL_13:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1>
246a1425019SValentin Clement! CHECK:         %[[VAL_14:.*]] = fir.slice %[[VAL_8]], %[[VAL_12]], %[[VAL_10]] : (index, index, index) -> !fir.slice<1>
24713f9089aSPeixin Qiao! CHECK:         %[[VAL_15:.*]] = fir.embox %[[VAL_1]](%[[VAL_13]]) {{\[}}%[[VAL_14]]] : (!fir.ref<!fir.array<400xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<100xf32>>
248a1425019SValentin Clement! CHECK:         %[[VAL_16:.*]] = arith.constant 1 : index
249a1425019SValentin Clement! CHECK:         %[[VAL_17:.*]] = fir.convert %[[VAL_3]] : (i64) -> index
250a1425019SValentin Clement! CHECK:         %[[VAL_18:.*]] = fir.convert %[[VAL_4]] : (i64) -> index
251a1425019SValentin Clement! CHECK:         %[[VAL_19:.*]] = arith.subi %[[VAL_18]], %[[VAL_17]] : index
252a1425019SValentin Clement! CHECK:         %[[VAL_20:.*]] = arith.addi %[[VAL_19]], %[[VAL_16]] : index
253a1425019SValentin Clement! CHECK:         %[[VAL_21:.*]] = fir.convert %[[VAL_5]] : (i64) -> index
254a1425019SValentin Clement! CHECK:         %[[VAL_22:.*]] = fir.convert %[[VAL_6]] : (i64) -> index
255a1425019SValentin Clement! CHECK:         %[[VAL_23:.*]] = arith.subi %[[VAL_22]], %[[VAL_21]] : index
256a1425019SValentin Clement! CHECK:         %[[VAL_24:.*]] = arith.addi %[[VAL_23]], %[[VAL_16]] : index
257a1425019SValentin Clement! CHECK:         %[[VAL_25:.*]] = fir.convert %[[VAL_3]] : (i64) -> index
258a1425019SValentin Clement! CHECK:         %[[VAL_26:.*]] = fir.convert %[[VAL_5]] : (i64) -> index
259a1425019SValentin Clement! CHECK:         %[[VAL_27:.*]] = fir.shape_shift %[[VAL_25]], %[[VAL_20]], %[[VAL_26]], %[[VAL_24]] : (index, index, index, index) -> !fir.shapeshift<2>
26013f9089aSPeixin Qiao! CHECK:         %[[VAL_28:.*]] = fir.rebox %[[VAL_15]](%[[VAL_27]]) : (!fir.box<!fir.array<100xf32>>, !fir.shapeshift<2>) -> !fir.box<!fir.ptr<!fir.array<?x?xf32>>>
261a1425019SValentin Clement! CHECK:         fir.store %[[VAL_28]] to %[[VAL_0]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x?xf32>>>>
262a1425019SValentin Clement! CHECK:         return
263a1425019SValentin Clement! CHECK:       }
264a1425019SValentin Clementsubroutine test_array_non_contig_remap_slice(p, x)
265a1425019SValentin Clement  real, target :: x(400)
266a1425019SValentin Clement  real, pointer :: p(:, :)
267a1425019SValentin Clement  p(2:11, 3:12) => x(51:350:3)
268a1425019SValentin Clementend subroutine
269a1425019SValentin Clement
270a1425019SValentin Clement! -----------------------------------------------------------------------------
271a1425019SValentin Clement!  Test pointer assignments that involves LHS pointers lowered to local variables
272a1425019SValentin Clement!  instead of a fir.ref<fir.box>, and RHS that are fir.box
273a1425019SValentin Clement! -----------------------------------------------------------------------------
274a1425019SValentin Clement
275a1425019SValentin Clement! CHECK-LABEL: func @_QPissue857(
276a1425019SValentin Clement! CHECK-SAME: %[[rhs:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.type<_QFissue857Tt{i:i32}>>>>
277a1425019SValentin Clementsubroutine issue857(rhs)
278a1425019SValentin Clement  type t
279a1425019SValentin Clement    integer :: i
280a1425019SValentin Clement  end type
281a1425019SValentin Clement  type(t), pointer :: rhs, lhs
282a1425019SValentin Clement  ! CHECK: %[[lhs:.*]] = fir.alloca !fir.ptr<!fir.type<_QFissue857Tt{i:i32}>>
283a1425019SValentin Clement  ! CHECK: %[[box_load:.*]] = fir.load %[[rhs]] : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QFissue857Tt{i:i32}>>>>
284a1425019SValentin Clement  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box_load]] : (!fir.box<!fir.ptr<!fir.type<_QFissue857Tt{i:i32}>>>) -> !fir.ptr<!fir.type<_QFissue857Tt{i:i32}>>
285a1425019SValentin Clement  ! CHECK: fir.store %[[addr]] to %[[lhs]] : !fir.ref<!fir.ptr<!fir.type<_QFissue857Tt{i:i32}>>>
286a1425019SValentin Clement  lhs => rhs
287a1425019SValentin Clementend subroutine
288a1425019SValentin Clement
289a1425019SValentin Clement! CHECK-LABEL: func @_QPissue857_array(
290a1425019SValentin Clement! CHECK-SAME: %[[rhs:.*]]: !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFissue857_arrayTt{i:i32}>>>>>
291a1425019SValentin Clementsubroutine issue857_array(rhs)
292a1425019SValentin Clement  type t
293a1425019SValentin Clement    integer :: i
294a1425019SValentin Clement  end type
295a1425019SValentin Clement  type(t), contiguous,  pointer :: rhs(:), lhs(:)
296a1425019SValentin Clement  ! CHECK-DAG: %[[lhs_addr:.*]] = fir.alloca !fir.ptr<!fir.array<?x!fir.type<_QFissue857_arrayTt{i:i32}>>> {uniq_name = "_QFissue857_arrayElhs.addr"}
297a1425019SValentin Clement  ! CHECK-DAG: %[[lhs_lb:.*]] = fir.alloca index {uniq_name = "_QFissue857_arrayElhs.lb0"}
298a1425019SValentin Clement  ! CHECK-DAG: %[[lhs_ext:.*]] = fir.alloca index {uniq_name = "_QFissue857_arrayElhs.ext0"}
299a1425019SValentin Clement  ! CHECK: %[[box:.*]] = fir.load %[[rhs]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFissue857_arrayTt{i:i32}>>>>>
300a1425019SValentin Clement  ! CHECK: %[[lb:.*]]:3 = fir.box_dims %[[box]], %c{{.*}} : (!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFissue857_arrayTt{i:i32}>>>>, index) -> (index, index, index)
301a1425019SValentin Clement  ! CHECK: %[[addr:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFissue857_arrayTt{i:i32}>>>>) -> !fir.ptr<!fir.array<?x!fir.type<_QFissue857_arrayTt{i:i32}>>>
302a1425019SValentin Clement  ! CHECK: %[[ext:.*]]:3 = fir.box_dims %[[box]], %c0{{.*}} : (!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QFissue857_arrayTt{i:i32}>>>>, index) -> (index, index, index)
303a1425019SValentin Clement  ! CHECK-DAG: fir.store %[[addr]] to %[[lhs_addr]] : !fir.ref<!fir.ptr<!fir.array<?x!fir.type<_QFissue857_arrayTt{i:i32}>>>>
304a1425019SValentin Clement  ! CHECK-DAG: fir.store %[[ext]]#1 to %[[lhs_ext]] : !fir.ref<index>
305a1425019SValentin Clement  ! CHECK-DAG: fir.store %[[lb]]#0 to %[[lhs_lb]] : !fir.ref<index>
306a1425019SValentin Clement  lhs => rhs
307a1425019SValentin Clementend subroutine
308a1425019SValentin Clement
309a1425019SValentin Clement! CHECK-LABEL: func @_QPissue857_array_shift(
310a1425019SValentin Clementsubroutine issue857_array_shift(rhs)
311a1425019SValentin Clement  ! Test lower bounds is the one from the shift
312a1425019SValentin Clement  type t
313a1425019SValentin Clement    integer :: i
314a1425019SValentin Clement  end type
315a1425019SValentin Clement  type(t), contiguous,  pointer :: rhs(:), lhs(:)
316a1425019SValentin Clement  ! CHECK: %[[lhs_lb:.*]] = fir.alloca index {uniq_name = "_QFissue857_array_shiftElhs.lb0"}
317a1425019SValentin Clement  ! CHECK: %[[c42:.*]] = fir.convert %c42{{.*}} : (i64) -> index
318a1425019SValentin Clement  ! CHECK: fir.store %[[c42]] to %[[lhs_lb]] : !fir.ref<index>
319a1425019SValentin Clement  lhs(42:) => rhs
320a1425019SValentin Clementend subroutine
321a1425019SValentin Clement
322a1425019SValentin Clement! CHECK-LABEL: func @_QPissue857_array_remap
323a1425019SValentin Clementsubroutine issue857_array_remap(rhs)
324a1425019SValentin Clement  ! Test lower bounds is the one from the shift
325a1425019SValentin Clement  type t
326a1425019SValentin Clement    integer :: i
327a1425019SValentin Clement  end type
328a1425019SValentin Clement  type(t), contiguous,  pointer :: rhs(:, :), lhs(:)
329a1425019SValentin Clement  ! CHECK-DAG: %[[lhs_addr:.*]] = fir.alloca !fir.ptr<!fir.array<?x!fir.type<_QFissue857_array_remapTt{i:i32}>>> {uniq_name = "_QFissue857_array_remapElhs.addr"}
330a1425019SValentin Clement  ! CHECK-DAG: %[[lhs_lb:.*]] = fir.alloca index {uniq_name = "_QFissue857_array_remapElhs.lb0"}
331a1425019SValentin Clement  ! CHECK-DAG: %[[lhs_ext:.*]] = fir.alloca index {uniq_name = "_QFissue857_array_remapElhs.ext0"}
332a1425019SValentin Clement
333a1425019SValentin Clement  ! CHECK: %[[c101:.*]] = fir.convert %c101_i64 : (i64) -> index
334a1425019SValentin Clement  ! CHECK: %[[c200:.*]] = fir.convert %c200_i64 : (i64) -> index
335a1425019SValentin Clement  ! CHECK: %[[sub:.*]] = arith.subi %[[c200]], %[[c101]] : index
336a1425019SValentin Clement  ! CHECK: %[[extent:.*]] = arith.addi %[[sub]], %c1{{.*}} : index
337a1425019SValentin Clement  ! CHECK: %[[addr:.*]] = fir.box_addr %{{.*}} : (!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QFissue857_array_remapTt{i:i32}>>>>) -> !fir.ptr<!fir.array<?x?x!fir.type<_QFissue857_array_remapTt{i:i32}>>>
338a1425019SValentin Clement  ! CHECK: %[[addr_cast:.*]] = fir.convert %[[addr]] : (!fir.ptr<!fir.array<?x?x!fir.type<_QFissue857_array_remapTt{i:i32}>>>) -> !fir.ptr<!fir.array<?x!fir.type<_QFissue857_array_remapTt{i:i32}>>>
339a1425019SValentin Clement  ! CHECK: fir.store %[[addr_cast]] to %[[lhs_addr]] : !fir.ref<!fir.ptr<!fir.array<?x!fir.type<_QFissue857_array_remapTt{i:i32}>>>>
340a1425019SValentin Clement  ! CHECK: fir.store %[[extent]] to %[[lhs_ext]] : !fir.ref<index>
341a1425019SValentin Clement  ! CHECK: %[[c101_2:.*]] = fir.convert %c101{{.*}} : (i64) -> index
342a1425019SValentin Clement  ! CHECK: fir.store %[[c101_2]] to %[[lhs_lb]] : !fir.ref<index>
343a1425019SValentin Clement  lhs(101:200) => rhs
344a1425019SValentin Clementend subroutine
345a1425019SValentin Clement
346a1425019SValentin Clement! CHECK-LABEL: func @_QPissue857_char
347a1425019SValentin Clementsubroutine issue857_char(rhs)
348a1425019SValentin Clement  ! Only check that the length is taken from the fir.box created for the slice.
349a1425019SValentin Clement  ! CHECK-DAG: %[[lhs1_len:.*]] = fir.alloca index {uniq_name = "_QFissue857_charElhs1.len"}
350a1425019SValentin Clement  ! CHECK-DAG: %[[lhs2_len:.*]] = fir.alloca index {uniq_name = "_QFissue857_charElhs2.len"}
351a1425019SValentin Clement  character(:), contiguous,  pointer ::  lhs1(:), lhs2(:, :)
352a1425019SValentin Clement  character(*), target ::  rhs(100)
35313f9089aSPeixin Qiao  ! CHECK: %[[len:.*]] = fir.box_elesize %{{.*}} : (!fir.box<!fir.array<50x!fir.char<1,?>>>) -> index
354a1425019SValentin Clement  ! CHECK: fir.store %[[len]] to %[[lhs1_len]] : !fir.ref<index>
355a1425019SValentin Clement  lhs1 => rhs(1:50:1)
35613f9089aSPeixin Qiao  ! CHECK: %[[len2:.*]] = fir.box_elesize %{{.*}} : (!fir.box<!fir.array<50x!fir.char<1,?>>>) -> index
357a1425019SValentin Clement  ! CHECK: fir.store %[[len2]] to %[[lhs2_len]] : !fir.ref<index>
358a1425019SValentin Clement  lhs2(1:2, 1:25) => rhs(1:50:1)
359a1425019SValentin Clementend subroutine
360a1425019SValentin Clement
361a1425019SValentin Clement! CHECK-LABEL: func @_QPissue1180(
362a1425019SValentin Clement! CHECK-SAME:  %[[VAL_0:.*]]: !fir.ref<i32> {{{.*}}, fir.target}) {
363a1425019SValentin Clementsubroutine issue1180(x)
364a1425019SValentin Clement  integer, target :: x
365a1425019SValentin Clement  integer, pointer :: p
366a1425019SValentin Clement  common /some_common/ p
3676ffea74fSjeanPerier  ! CHECK: %[[VAL_1:.*]] = fir.address_of(@some_common_) : !fir.ref<!fir.array<24xi8>>
368a1425019SValentin Clement  ! CHECK: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (!fir.ref<!fir.array<24xi8>>) -> !fir.ref<!fir.array<?xi8>>
369a1425019SValentin Clement  ! CHECK: %[[VAL_3:.*]] = arith.constant 0 : index
370a1425019SValentin Clement  ! CHECK: %[[VAL_4:.*]] = fir.coordinate_of %[[VAL_2]], %[[VAL_3]] : (!fir.ref<!fir.array<?xi8>>, index) -> !fir.ref<i8>
371a1425019SValentin Clement  ! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (!fir.ref<i8>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>
372a1425019SValentin Clement  ! CHECK: %[[VAL_6:.*]] = fir.embox %[[VAL_0]] : (!fir.ref<i32>) -> !fir.box<!fir.ptr<i32>>
373a1425019SValentin Clement  ! CHECK: fir.store %[[VAL_6]] to %[[VAL_5]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
374a1425019SValentin Clement  p => x
375a1425019SValentin Clementend subroutine
376