brintos

brintos / llvm-project-archived public Read only

0
0
Text · 24.5 KiB · d112ec6 Raw
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