413 lines · plain
1// Test rewrite of functions that return fir.array<>, fir.type<>, fir.box<> to2// functions that take an additional argument for the result.3 4// RUN: fir-opt %s --abstract-result | FileCheck %s --check-prefix=FUNC-REF5// RUN: fir-opt %s --abstract-result=abstract-result-as-box | FileCheck %s --check-prefix=FUNC-BOX6// RUN: fir-opt %s --abstract-result | FileCheck %s --check-prefix=GLOBAL-REF7// RUN: fir-opt %s --abstract-result=abstract-result-as-box | FileCheck %s --check-prefix=GLOBAL-BOX8 9// ----------------------- Test declaration rewrite ----------------------------10 11// FUNC-REF-LABEL: func private @arrayfunc(!fir.ref<!fir.array<?xf32>>, i32)12// FUNC-BOX-LABEL: func private @arrayfunc(!fir.box<!fir.array<?xf32>>, i32)13func.func private @arrayfunc(i32) -> !fir.array<?xf32>14 15// FUNC-REF-LABEL: func private @derivedfunc(!fir.ref<!fir.type<t{x:f32}>>, f32)16// FUNC-BOX-LABEL: func private @derivedfunc(!fir.box<!fir.type<t{x:f32}>>, f32)17func.func private @derivedfunc(f32) -> !fir.type<t{x:f32}>18 19// FUNC-REF-LABEL: func private @boxfunc(!fir.ref<!fir.box<!fir.heap<f64>>>, i64)20// FUNC-BOX-LABEL: func private @boxfunc(!fir.ref<!fir.box<!fir.heap<f64>>>, i64)21func.func private @boxfunc(i64) -> !fir.box<!fir.heap<f64>>22 23 24// ------------------------ Test callee rewrite --------------------------------25 26// FUNC-REF-LABEL: func private @arrayfunc_callee(27// FUNC-REF-SAME: %[[buffer:.*]]: !fir.ref<!fir.array<?xf32>>, %[[n:.*]]: index) {28// FUNC-BOX-LABEL: func private @arrayfunc_callee(29// FUNC-BOX-SAME: %[[box:.*]]: !fir.box<!fir.array<?xf32>>, %[[n:.*]]: index) {30func.func private @arrayfunc_callee(%n : index) -> !fir.array<?xf32> {31 %buffer = fir.alloca !fir.array<?xf32>, %n32 // Do something with result (res(4) = 42.)33 %c4 = arith.constant 4 : i6434 %coor = fir.coordinate_of %buffer, %c4 : (!fir.ref<!fir.array<?xf32>>, i64) -> !fir.ref<f32>35 %cst = arith.constant 4.200000e+01 : f3236 fir.store %cst to %coor : !fir.ref<f32>37 %res = fir.load %buffer : !fir.ref<!fir.array<?xf32>>38 return %res : !fir.array<?xf32>39 40 // FUNC-REF-DAG: %[[coor:.*]] = fir.coordinate_of %[[buffer]], %{{.*}} : (!fir.ref<!fir.array<?xf32>>, i64) -> !fir.ref<f32>41 // FUNC-REF-DAG: fir.store %{{.*}} to %[[coor]] : !fir.ref<f32>42 // FUNC-REF: return43 44 // FUNC-BOX: %[[buffer:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>45 // FUNC-BOX-DAG: %[[coor:.*]] = fir.coordinate_of %[[buffer]], %{{.*}} : (!fir.ref<!fir.array<?xf32>>, i64) -> !fir.ref<f32>46 // FUNC-BOX-DAG: fir.store %{{.*}} to %[[coor]] : !fir.ref<f32>47 // FUNC-BOX: return48}49 50 51// FUNC-REF-LABEL: func @derivedfunc_callee(52// FUNC-REF-SAME: %[[buffer:.*]]: !fir.ref<!fir.type<t{x:f32}>>, %[[v:.*]]: f32) {53// FUNC-BOX-LABEL: func @derivedfunc_callee(54// FUNC-BOX-SAME: %[[box:.*]]: !fir.box<!fir.type<t{x:f32}>>, %[[v:.*]]: f32) {55func.func @derivedfunc_callee(%v: f32) -> !fir.type<t{x:f32}> {56 %buffer = fir.alloca !fir.type<t{x:f32}>57 %1 = fir.coordinate_of %buffer, x : (!fir.ref<!fir.type<t{x:f32}>>) -> !fir.ref<f32>58 fir.store %v to %1 : !fir.ref<f32>59 %res = fir.load %buffer : !fir.ref<!fir.type<t{x:f32}>>60 return %res : !fir.type<t{x:f32}>61 62 // FUNC-REF: %[[coor:.*]] = fir.coordinate_of %[[buffer]], x : (!fir.ref<!fir.type<t{x:f32}>>) -> !fir.ref<f32>63 // FUNC-REF: fir.store %[[v]] to %[[coor]] : !fir.ref<f32>64 // FUNC-REF: return65 66 // FUNC-BOX: %[[buffer:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.type<t{x:f32}>>) -> !fir.ref<!fir.type<t{x:f32}>>67 // FUNC-BOX: %[[coor:.*]] = fir.coordinate_of %[[buffer]], x : (!fir.ref<!fir.type<t{x:f32}>>) -> !fir.ref<f32>68 // FUNC-BOX: fir.store %[[v]] to %[[coor]] : !fir.ref<f32>69 // FUNC-BOX: return70}71 72// FUNC-REF-LABEL: func @boxfunc_callee(73// FUNC-REF-SAME: %[[buffer:.*]]: !fir.ref<!fir.box<!fir.heap<f64>>>) {74// FUNC-BOX-LABEL: func @boxfunc_callee(75// FUNC-BOX-SAME: %[[buffer:.*]]: !fir.ref<!fir.box<!fir.heap<f64>>>) {76func.func @boxfunc_callee() -> !fir.box<!fir.heap<f64>> {77 %alloc = fir.allocmem f6478 %res = fir.embox %alloc : (!fir.heap<f64>) -> !fir.box<!fir.heap<f64>>79 return %res : !fir.box<!fir.heap<f64>>80 // FUNC-REF: %[[box:.*]] = fir.embox %{{.*}} : (!fir.heap<f64>) -> !fir.box<!fir.heap<f64>>81 // FUNC-REF: fir.store %[[box]] to %[[buffer]] : !fir.ref<!fir.box<!fir.heap<f64>>>82 // FUNC-REF: return83 84 // FUNC-BOX: %[[box:.*]] = fir.embox %{{.*}} : (!fir.heap<f64>) -> !fir.box<!fir.heap<f64>>85 // FUNC-BOX: fir.store %[[box]] to %[[buffer]] : !fir.ref<!fir.box<!fir.heap<f64>>>86 // FUNC-BOX: return87}88 89// FUNC-REF-LABEL: func @retcptr() -> !fir.ref<none>90// FUNC-BOX-LABEL: func @retcptr() -> !fir.ref<none>91func.func @retcptr() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {92 %0 = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = "rec", uniq_name = "_QFrecErec"}93 %1 = fir.load %0 : !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>94 return %1 : !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>95 96 // FUNC-REF: %[[ALLOC:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = "rec", uniq_name = "_QFrecErec"}97 // FUNC-REF: %[[ADDR:.*]] = fir.coordinate_of %[[ALLOC]], __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>98 // FUNC-REF: %[[VAL:.*]] = fir.load %[[ADDR]] : !fir.ref<i64>99 // FUNC-REF: %[[CAST:.*]] = fir.convert %[[VAL]] : (i64) -> !fir.ref<none>100 // FUNC-REF: return %[[CAST]] : !fir.ref<none>101 // FUNC-BOX: %[[ALLOC:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = "rec", uniq_name = "_QFrecErec"}102 // FUNC-BOX: %[[ADDR:.*]] = fir.coordinate_of %[[ALLOC]], __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>103 // FUNC-BOX: %[[VAL:.*]] = fir.load %[[ADDR]] : !fir.ref<i64>104 // FUNC-BOX: %[[CAST:.*]] = fir.convert %[[VAL]] : (i64) -> !fir.ref<none>105 // FUNC-BOX: return %[[CAST]] : !fir.ref<none>106}107 108// FUNC-REF-LABEL: func private @arrayfunc_callee_declare(109// FUNC-REF-SAME: %[[buffer:.*]]: !fir.ref<!fir.array<?xf32>>, %[[n:.*]]: index) {110// FUNC-BOX-LABEL: func private @arrayfunc_callee_declare(111// FUNC-BOX-SAME: %[[box:.*]]: !fir.box<!fir.array<?xf32>>, %[[n:.*]]: index) {112func.func private @arrayfunc_callee_declare(%n : index) -> !fir.array<?xf32> {113 %buffer_alloc = fir.alloca !fir.array<?xf32>, %n114 %shape = fir.shape %n : (index) -> !fir.shape<1>115 %buffer = fir.declare %buffer_alloc(%shape) {uniq_name = "x"}: (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<?xf32>>116 // Do something with result (res(4) = 42.)117 %c4 = arith.constant 4 : i64118 %coor = fir.coordinate_of %buffer, %c4 : (!fir.ref<!fir.array<?xf32>>, i64) -> !fir.ref<f32>119 %cst = arith.constant 4.200000e+01 : f32120 fir.store %cst to %coor : !fir.ref<f32>121 %res = fir.load %buffer : !fir.ref<!fir.array<?xf32>>122 return %res : !fir.array<?xf32>123 124 // FUNC-REF-DAG: %[[buffer_declare:.*]] = fir.declare %[[buffer]](%{{.*}}) {uniq_name = "x"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<?xf32>>125 // FUNC-REF-DAG: %[[coor:.*]] = fir.coordinate_of %[[buffer_declare]], %{{.*}} : (!fir.ref<!fir.array<?xf32>>, i64) -> !fir.ref<f32>126 // FUNC-REF-DAG: fir.store %{{.*}} to %[[coor]] : !fir.ref<f32>127 // FUNC-REF: return128 129 // FUNC-BOX: %[[buffer:.*]] = fir.box_addr %[[box]] : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<!fir.array<?xf32>>130 // FUNC-BOX-DAG: %[[buffer_declare:.*]] = fir.declare %[[buffer]](%{{.*}}) {uniq_name = "x"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<?xf32>>131 // FUNC-BOX-DAG: %[[coor:.*]] = fir.coordinate_of %[[buffer_declare]], %{{.*}} : (!fir.ref<!fir.array<?xf32>>, i64) -> !fir.ref<f32>132 // FUNC-BOX-DAG: fir.store %{{.*}} to %[[coor]] : !fir.ref<f32>133 // FUNC-BOX: return134}135 136// ------------------------ Test caller rewrite --------------------------------137 138// FUNC-REF-LABEL: func @call_arrayfunc() {139// FUNC-BOX-LABEL: func @call_arrayfunc() {140func.func @call_arrayfunc() {141 %c100 = arith.constant 100 : index142 %buffer = fir.alloca !fir.array<?xf32>, %c100143 %shape = fir.shape %c100 : (index) -> !fir.shape<1>144 %res = fir.call @arrayfunc_callee(%c100) : (index) -> !fir.array<?xf32>145 fir.save_result %res to %buffer(%shape) : !fir.array<?xf32>, !fir.ref<!fir.array<?xf32>>, !fir.shape<1>146 return147 148 // FUNC-REF: %[[c100:.*]] = arith.constant 100 : index149 // FUNC-REF: %[[buffer:.*]] = fir.alloca !fir.array<?xf32>, %[[c100]]150 // FUNC-REF: fir.call @arrayfunc_callee(%[[buffer]], %[[c100]]) : (!fir.ref<!fir.array<?xf32>>, index) -> ()151 // FUNC-REF-NOT: fir.save_result152 153 // FUNC-BOX: %[[c100:.*]] = arith.constant 100 : index154 // FUNC-BOX: %[[buffer:.*]] = fir.alloca !fir.array<?xf32>, %[[c100]]155 // FUNC-BOX: %[[shape:.*]] = fir.shape %[[c100]] : (index) -> !fir.shape<1>156 // FUNC-BOX: %[[box:.*]] = fir.embox %[[buffer]](%[[shape]]) : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>157 // FUNC-BOX: fir.call @arrayfunc_callee(%[[box]], %[[c100]]) : (!fir.box<!fir.array<?xf32>>, index) -> ()158 // FUNC-BOX-NOT: fir.save_result159}160 161// FUNC-REF-LABEL: func @call_derivedfunc() {162// FUNC-BOX-LABEL: func @call_derivedfunc() {163func.func @call_derivedfunc() {164 %buffer = fir.alloca !fir.type<t{x:f32}>165 %cst = arith.constant 4.200000e+01 : f32166 %res = fir.call @derivedfunc_callee(%cst) : (f32) -> !fir.type<t{x:f32}>167 fir.save_result %res to %buffer : !fir.type<t{x:f32}>, !fir.ref<!fir.type<t{x:f32}>>168 return169 // FUNC-REF: %[[buffer:.*]] = fir.alloca !fir.type<t{x:f32}>170 // FUNC-REF: %[[cst:.*]] = arith.constant {{.*}} : f32171 // FUNC-REF: fir.call @derivedfunc_callee(%[[buffer]], %[[cst]]) : (!fir.ref<!fir.type<t{x:f32}>>, f32) -> ()172 // FUNC-REF-NOT: fir.save_result173 174 // FUNC-BOX: %[[buffer:.*]] = fir.alloca !fir.type<t{x:f32}>175 // FUNC-BOX: %[[cst:.*]] = arith.constant {{.*}} : f32176 // FUNC-BOX: %[[box:.*]] = fir.embox %[[buffer]] : (!fir.ref<!fir.type<t{x:f32}>>) -> !fir.box<!fir.type<t{x:f32}>>177 // FUNC-BOX: fir.call @derivedfunc_callee(%[[box]], %[[cst]]) : (!fir.box<!fir.type<t{x:f32}>>, f32) -> ()178 // FUNC-BOX-NOT: fir.save_result179}180 181func.func private @derived_lparams_func() -> !fir.type<t2(l1:i32,l2:i32){x:f32}>182 183// FUNC-REF-LABEL: func @call_derived_lparams_func(184// FUNC-REF-SAME: %[[buffer:.*]]: !fir.ref<!fir.type<t2(l1:i32,l2:i32){x:f32}>>185// FUNC-BOX-LABEL: func @call_derived_lparams_func(186// FUNC-BOX-SAME: %[[buffer:.*]]: !fir.ref<!fir.type<t2(l1:i32,l2:i32){x:f32}>>187func.func @call_derived_lparams_func(%buffer: !fir.ref<!fir.type<t2(l1:i32,l2:i32){x:f32}>>) {188 %l1 = arith.constant 3 : i32189 %l2 = arith.constant 5 : i32190 %res = fir.call @derived_lparams_func() : () -> !fir.type<t2(l1:i32,l2:i32){x:f32}>191 fir.save_result %res to %buffer typeparams %l1, %l2 : !fir.type<t2(l1:i32,l2:i32){x:f32}>, !fir.ref<!fir.type<t2(l1:i32,l2:i32){x:f32}>>, i32, i32192 return193 194 // FUNC-REF: %[[l1:.*]] = arith.constant 3 : i32195 // FUNC-REF: %[[l2:.*]] = arith.constant 5 : i32196 // FUNC-REF: fir.call @derived_lparams_func(%[[buffer]]) : (!fir.ref<!fir.type<t2(l1:i32,l2:i32){x:f32}>>) -> ()197 // FUNC-REF-NOT: fir.save_result198 199 // FUNC-BOX: %[[l1:.*]] = arith.constant 3 : i32200 // FUNC-BOX: %[[l2:.*]] = arith.constant 5 : i32201 // FUNC-BOX: %[[box:.*]] = fir.embox %[[buffer]] typeparams %[[l1]], %[[l2]] : (!fir.ref<!fir.type<t2(l1:i32,l2:i32){x:f32}>>, i32, i32) -> !fir.box<!fir.type<t2(l1:i32,l2:i32){x:f32}>>202 // FUNC-BOX: fir.call @derived_lparams_func(%[[box]]) : (!fir.box<!fir.type<t2(l1:i32,l2:i32){x:f32}>>) -> ()203 // FUNC-BOX-NOT: fir.save_result204}205 206// FUNC-REF-LABEL: func @call_boxfunc() {207// FUNC-BOX-LABEL: func @call_boxfunc() {208func.func @call_boxfunc() {209 %buffer = fir.alloca !fir.box<!fir.heap<f64>>210 %res = fir.call @boxfunc_callee() : () -> !fir.box<!fir.heap<f64>>211 fir.save_result %res to %buffer: !fir.box<!fir.heap<f64>>, !fir.ref<!fir.box<!fir.heap<f64>>>212 return213 214 // FUNC-REF: %[[buffer:.*]] = fir.alloca !fir.box<!fir.heap<f64>>215 // FUNC-REF: fir.call @boxfunc_callee(%[[buffer]]) : (!fir.ref<!fir.box<!fir.heap<f64>>>) -> ()216 // FUNC-REF-NOT: fir.save_result217 218 // FUNC-BOX: %[[buffer:.*]] = fir.alloca !fir.box<!fir.heap<f64>>219 // FUNC-BOX: fir.call @boxfunc_callee(%[[buffer]]) : (!fir.ref<!fir.box<!fir.heap<f64>>>) -> ()220 // FUNC-BOX-NOT: fir.save_result221}222 223func.func private @chararrayfunc(index, index) -> !fir.array<?x!fir.char<1,?>>224 225// FUNC-REF-LABEL: func @call_chararrayfunc() {226// FUNC-BOX-LABEL: func @call_chararrayfunc() {227func.func @call_chararrayfunc() {228 %c100 = arith.constant 100 : index229 %c50 = arith.constant 50 : index230 %buffer = fir.alloca !fir.array<?x!fir.char<1,?>>(%c100 : index), %c50231 %shape = fir.shape %c100 : (index) -> !fir.shape<1>232 %res = fir.call @chararrayfunc(%c100, %c50) : (index, index) -> !fir.array<?x!fir.char<1,?>>233 fir.save_result %res to %buffer(%shape) typeparams %c50 : !fir.array<?x!fir.char<1,?>>, !fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index234 return235 236 // FUNC-REF: %[[c100:.*]] = arith.constant 100 : index237 // FUNC-REF: %[[c50:.*]] = arith.constant 50 : index238 // FUNC-REF: %[[buffer:.*]] = fir.alloca !fir.array<?x!fir.char<1,?>>(%[[c100]] : index), %[[c50]]239 // FUNC-REF: fir.call @chararrayfunc(%[[buffer]], %[[c100]], %[[c50]]) : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, index, index) -> ()240 // FUNC-REF-NOT: fir.save_result241 242 // FUNC-BOX: %[[c100:.*]] = arith.constant 100 : index243 // FUNC-BOX: %[[c50:.*]] = arith.constant 50 : index244 // FUNC-BOX: %[[buffer:.*]] = fir.alloca !fir.array<?x!fir.char<1,?>>(%[[c100]] : index), %[[c50]]245 // FUNC-BOX: %[[shape:.*]] = fir.shape %[[c100]] : (index) -> !fir.shape<1>246 // FUNC-BOX: %[[box:.*]] = fir.embox %[[buffer]](%[[shape]]) typeparams %[[c50]] : (!fir.ref<!fir.array<?x!fir.char<1,?>>>, !fir.shape<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,?>>>247 // FUNC-BOX: fir.call @chararrayfunc(%[[box]], %[[c100]], %[[c50]]) : (!fir.box<!fir.array<?x!fir.char<1,?>>>, index, index) -> ()248 // FUNC-BOX-NOT: fir.save_result249}250 251// FUNC-REF-LABEL: func @_QPtest_return_cptr252// FUNC-BOX-LABEL: func @_QPtest_return_cptr253func.func @_QPtest_return_cptr() {254 %0 = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = ".result"}255 %1 = fir.call @retcptr() : () -> i64256 %3 = fir.coordinate_of %0, __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>257 fir.store %1 to %3 : !fir.ref<i64>258 return259 260 // FUNC-REF: %[[ALLOC:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = ".result"}261 // FUNC-REF: %[[VAL:.*]] = fir.call @retcptr() : () -> i64262 // FUNC-REF: %[[ADDR:.*]] = fir.coordinate_of %[[ALLOC]], __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>263 // FUNC-REF: fir.store %[[VAL]] to %[[ADDR]] : !fir.ref<i64>264 // FUNC-BOX: %[[ALLOC:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = ".result"}265 // FUNC-BOX: %[[VAL:.*]] = fir.call @retcptr() : () -> i64266 // FUNC-BOX: %[[ADDR:.*]] = fir.coordinate_of %[[ALLOC]], __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>267 // FUNC-BOX: fir.store %[[VAL]] to %[[ADDR]] : !fir.ref<i64>268}269 270// FUNC-REF-LABEL: func @dispatch(271// FUNC-REF-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"}272// FUNC-BOX-LABEL: func @dispatch(273// FUNC-BOX-SAME: %[[ARG0:.*]]: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"}274func.func @dispatch(%arg0: !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>> {fir.bindc_name = "a"}) {275 %buffer = fir.alloca !fir.type<t{x:f32}>276 %res = fir.dispatch "ret_array"(%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%arg0 : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) -> !fir.type<t{x:f32}> {pass_arg_pos = 0 : i32}277 fir.save_result %res to %buffer : !fir.type<t{x:f32}>, !fir.ref<!fir.type<t{x:f32}>>278 return279 // FUNC-REF: %[[buffer:.*]] = fir.alloca !fir.type<t{x:f32}>280 // FUNC-REF: fir.dispatch "ret_array"(%[[ARG0]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%[[buffer]], %[[ARG0]] : !fir.ref<!fir.type<t{x:f32}>>, !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) {pass_arg_pos = 1 : i32}281 // FUNC-REF-NOT: fir.save_result282 283 // FUNC-BOX: %[[buffer:.*]] = fir.alloca !fir.type<t{x:f32}>284 // FUNC-BOX: %[[box:.*]] = fir.embox %[[buffer]] : (!fir.ref<!fir.type<t{x:f32}>>) -> !fir.box<!fir.type<t{x:f32}>>285 // FUNC-BOX: fir.dispatch "ret_array"(%[[ARG0]] : !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) (%[[box]], %[[ARG0]] : !fir.box<!fir.type<t{x:f32}>>, !fir.class<!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>>) {pass_arg_pos = 1 : i32}286 // FUNC-BOX-NOT: fir.save_result287}288 289// ------------------------ Test fir.address_of rewrite ------------------------290 291func.func private @takesfuncarray((i32) -> !fir.array<?xf32>)292 293// FUNC-REF-LABEL: func @test_address_of() {294// FUNC-BOX-LABEL: func @test_address_of() {295func.func @test_address_of() {296 %0 = fir.address_of(@arrayfunc) : (i32) -> !fir.array<?xf32>297 fir.call @takesfuncarray(%0) : ((i32) -> !fir.array<?xf32>) -> ()298 return299 300 // FUNC-REF: %[[addrOf:.*]] = fir.address_of(@arrayfunc) : (!fir.ref<!fir.array<?xf32>>, i32) -> ()301 // FUNC-REF: %[[conv:.*]] = fir.convert %[[addrOf]] : ((!fir.ref<!fir.array<?xf32>>, i32) -> ()) -> ((i32) -> !fir.array<?xf32>)302 // FUNC-REF: fir.call @takesfuncarray(%[[conv]]) : ((i32) -> !fir.array<?xf32>) -> ()303 304 // FUNC-BOX: %[[addrOf:.*]] = fir.address_of(@arrayfunc) : (!fir.box<!fir.array<?xf32>>, i32) -> ()305 // FUNC-BOX: %[[conv:.*]] = fir.convert %[[addrOf]] : ((!fir.box<!fir.array<?xf32>>, i32) -> ()) -> ((i32) -> !fir.array<?xf32>)306 // FUNC-BOX: fir.call @takesfuncarray(%[[conv]]) : ((i32) -> !fir.array<?xf32>) -> ()307 308}309 310// FUNC-REF-LABEL: func.func private @returns_null() -> !fir.ref<none>311// FUNC-BOX-LABEL: func.func private @returns_null() -> !fir.ref<none>312func.func private @returns_null() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>313 314// FUNC-REF-LABEL: func @test_address_of_cptr315// FUNC-BOX-LABEL: func @test_address_of_cptr316func.func @test_address_of_cptr() {317 %0 = fir.address_of(@returns_null) : () -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>318 %1 = fir.convert %0 : (() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>) -> (() -> ())319 fir.call @_QMtest_c_func_modPsubr(%1) : (() -> ()) -> ()320 return321 322 // FUNC-REF: %[[VAL_0:.*]] = fir.address_of(@returns_null) : () -> !fir.ref<none>323 // FUNC-REF: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (() -> !fir.ref<none>) -> (() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>)324 // FUNC-REF: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>) -> (() -> ())325 // FUNC-REF: fir.call @_QMtest_c_func_modPsubr(%[[VAL_2]]) : (() -> ()) -> ()326 // FUNC-BOX: %[[VAL_0:.*]] = fir.address_of(@returns_null) : () -> !fir.ref<none>327 // FUNC-BOX: %[[VAL_1:.*]] = fir.convert %[[VAL_0]] : (() -> !fir.ref<none>) -> (() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>)328 // FUNC-BOX: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>) -> (() -> ())329 // FUNC-BOX: fir.call @_QMtest_c_func_modPsubr(%[[VAL_2]]) : (() -> ()) -> ()330}331 332 333// ----------------------- Test indirect calls rewrite ------------------------334 335// FUNC-REF-LABEL: func @test_indirect_calls(336// FUNC-REF-SAME: %[[arg0:.*]]: () -> ()) {337// FUNC-BOX-LABEL: func @test_indirect_calls(338// FUNC-BOX-SAME: %[[arg0:.*]]: () -> ()) {339func.func @test_indirect_calls(%arg0: () -> ()) {340 %c100 = arith.constant 100 : index341 %buffer = fir.alloca !fir.array<?xf32>, %c100342 %shape = fir.shape %c100 : (index) -> !fir.shape<1>343 %0 = fir.convert %arg0 : (() -> ()) -> ((index) -> !fir.array<?xf32>)344 %res = fir.call %0(%c100) : (index) -> !fir.array<?xf32>345 fir.save_result %res to %buffer(%shape) : !fir.array<?xf32>, !fir.ref<!fir.array<?xf32>>, !fir.shape<1>346 return347 348 // FUNC-REF: %[[c100:.*]] = arith.constant 100 : index349 // FUNC-REF: %[[buffer:.*]] = fir.alloca !fir.array<?xf32>, %[[c100]]350 // FUNC-REF: %[[shape:.*]] = fir.shape %[[c100]] : (index) -> !fir.shape<1>351 // FUNC-REF: %[[original_conv:.*]] = fir.convert %[[arg0]] : (() -> ()) -> ((index) -> !fir.array<?xf32>)352 // FUNC-REF: %[[conv:.*]] = fir.convert %[[original_conv]] : ((index) -> !fir.array<?xf32>) -> ((!fir.ref<!fir.array<?xf32>>, index) -> ())353 // FUNC-REF: fir.call %[[conv]](%[[buffer]], %c100) : (!fir.ref<!fir.array<?xf32>>, index) -> ()354 // FUNC-REF-NOT: fir.save_result355 356 // FUNC-BOX: %[[c100:.*]] = arith.constant 100 : index357 // FUNC-BOX: %[[buffer:.*]] = fir.alloca !fir.array<?xf32>, %[[c100]]358 // FUNC-BOX: %[[shape:.*]] = fir.shape %[[c100]] : (index) -> !fir.shape<1>359 // FUNC-BOX: %[[original_conv:.*]] = fir.convert %[[arg0]] : (() -> ()) -> ((index) -> !fir.array<?xf32>)360 // FUNC-BOX: %[[box:.*]] = fir.embox %[[buffer]](%[[shape]]) : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>361 // FUNC-BOX: %[[conv:.*]] = fir.convert %[[original_conv]] : ((index) -> !fir.array<?xf32>) -> ((!fir.box<!fir.array<?xf32>>, index) -> ())362 // FUNC-BOX: fir.call %[[conv]](%[[box]], %c100) : (!fir.box<!fir.array<?xf32>>, index) -> ()363 // FUNC-BOX-NOT: fir.save_result364}365 366// FUNC-REF-LABEL: func @test_indirect_calls_return_cptr(367// FUNC-REF-SAME: %[[ARG0:.*]]: () -> ())368// FUNC-BOX-LABEL: func @test_indirect_calls_return_cptr(369// FUNC-BOX-SAME: %[[ARG0:.*]]: () -> ())370func.func @test_indirect_calls_return_cptr(%arg0: () -> ()) {371 %0 = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = ".result"}372 %1 = fir.convert %arg0 : (() -> ()) -> (() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>)373 %2 = fir.call %1() : () -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>374 fir.save_result %2 to %0 : !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>, !fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>375 return376 377 // FUNC-REF: %[[VAL_0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = ".result"}378 // FUNC-REF: %[[VAL_1:.*]] = fir.convert %[[ARG0]] : (() -> ()) -> (() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>)379 // FUNC-REF: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>) -> (() -> !fir.ref<none>)380 // FUNC-REF: %[[VAL_3:.*]] = fir.call %[[VAL_2]]() : () -> !fir.ref<none>381 // FUNC-REF: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_0]], __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>382 // FUNC-REF: %[[CAST:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<none>) -> i64383 // FUNC-REF: fir.store %[[CAST]] to %[[VAL_5]] : !fir.ref<i64>384 // FUNC-BOX: %[[VAL_0:.*]] = fir.alloca !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> {bindc_name = ".result"}385 // FUNC-BOX: %[[VAL_1:.*]] = fir.convert %[[ARG0]] : (() -> ()) -> (() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>)386 // FUNC-BOX: %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (() -> !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>) -> (() -> !fir.ref<none>)387 // FUNC-BOX: %[[VAL_3:.*]] = fir.call %[[VAL_2]]() : () -> !fir.ref<none>388 // FUNC-BOX: %[[VAL_5:.*]] = fir.coordinate_of %[[VAL_0]], __address : (!fir.ref<!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>>) -> !fir.ref<i64>389 // FUNC-BOX: %[[CAST:.*]] = fir.convert %[[VAL_3]] : (!fir.ref<none>) -> i64390 // FUNC-BOX: fir.store %[[CAST]] to %[[VAL_5]] : !fir.ref<i64>391}392 393// ----------------------- Test GlobalOp rewrite ------------------------394 395// This is needed to separate GlobalOp tests from FuncOp tests for FileCheck396// FUNC-REF-LABEL: fir.global {{.*}} : {{.*}} {397// FUNC-BOX-LABEL: fir.global {{.*}} : {{.*}} {398 399// GLOBAL-REF-LABEL: fir.global @global_test_address_of : i32 {400// GLOBAL-BOX-LABEL: fir.global @global_test_address_of : i32 {401fir.global @global_test_address_of : i32 {402 %0 = fir.address_of(@arrayfunc) : (i32) -> !fir.array<?xf32>403 404 // GLOBAL-REF: %[[addrOf:.*]] = fir.address_of(@arrayfunc) : (!fir.ref<!fir.array<?xf32>>, i32) -> ()405 // GLOBAL-REF: %[[conv:.*]] = fir.convert %[[addrOf]] : ((!fir.ref<!fir.array<?xf32>>, i32) -> ()) -> ((i32) -> !fir.array<?xf32>)406 407 // GLOBAL-BOX: %[[addrOf:.*]] = fir.address_of(@arrayfunc) : (!fir.box<!fir.array<?xf32>>, i32) -> ()408 // GLOBAL-BOX: %[[conv:.*]] = fir.convert %[[addrOf]] : ((!fir.box<!fir.array<?xf32>>, i32) -> ()) -> ((i32) -> !fir.array<?xf32>)409 410 %c42 = arith.constant 42 : i32411 fir.has_value %c42 : i32412}413