xref: /llvm-project/flang/test/Lower/Intrinsics/associated-proc-pointers.f90 (revision 1710c8cf0f8def4984893e9dd646579de5528d95)
1f3fa603dSjeanPerier! Test ASSOCIATED() with procedure pointers.
2f3fa603dSjeanPerier! RUN: bbc -emit-hlfir -o - %s | FileCheck %s
3f3fa603dSjeanPerier
4f3fa603dSjeanPeriersubroutine test_proc_pointer_1(p, dummy_proc)
5f3fa603dSjeanPerier  procedure(), pointer :: p
6f3fa603dSjeanPerier  procedure() :: dummy_proc
7f3fa603dSjeanPerier  call takes_log(associated(p, dummy_proc))
8f3fa603dSjeanPerierend subroutine
9f3fa603dSjeanPerier! CHECK-LABEL:   func.func @_QPtest_proc_pointer_1(
10f3fa603dSjeanPerier! CHECK-SAME:                                      %[[VAL_0:.*]]: !fir.ref<!fir.boxproc<() -> ()>>,
11f3fa603dSjeanPerier! CHECK-SAME:                                      %[[VAL_1:.*]]: !fir.boxproc<() -> ()>) {
12*1710c8cfSSlava Zakharin! CHECK:           %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_proc_pointer_1Ep"} : (!fir.ref<!fir.boxproc<() -> ()>>, !fir.dscope) -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
13f3fa603dSjeanPerier! CHECK:           %[[VAL_3:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.boxproc<() -> ()>>
14f3fa603dSjeanPerier! CHECK:           %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> (() -> ())
15f3fa603dSjeanPerier! CHECK:           %[[VAL_5:.*]] = fir.box_addr %[[VAL_1]] : (!fir.boxproc<() -> ()>) -> (() -> ())
16f3fa603dSjeanPerier! CHECK:           %[[VAL_6:.*]] = fir.convert %[[VAL_4]] : (() -> ()) -> i64
17f3fa603dSjeanPerier! CHECK:           %[[VAL_7:.*]] = fir.convert %[[VAL_5]] : (() -> ()) -> i64
18f3fa603dSjeanPerier! CHECK:           %[[VAL_8:.*]] = arith.cmpi eq, %[[VAL_6]], %[[VAL_7]] : i64
19f3fa603dSjeanPerier! CHECK:           %[[VAL_9:.*]] = arith.constant 0 : i64
20f3fa603dSjeanPerier! CHECK:           %[[VAL_10:.*]] = arith.cmpi ne, %[[VAL_9]], %[[VAL_6]] : i64
21f3fa603dSjeanPerier! CHECK:           %[[VAL_11:.*]] = arith.andi %[[VAL_8]], %[[VAL_10]] : i1
22f3fa603dSjeanPerier! CHECK:           %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i1) -> !fir.logical<4>
23f3fa603dSjeanPerier
24f3fa603dSjeanPeriersubroutine test_proc_pointer_2(p, p_target)
25f3fa603dSjeanPerier  procedure(), pointer :: p, p_target
26f3fa603dSjeanPerier  call takes_log(associated(p, p_target))
27f3fa603dSjeanPerierend subroutine
28f3fa603dSjeanPerier! CHECK-LABEL:   func.func @_QPtest_proc_pointer_2(
29f3fa603dSjeanPerier! CHECK-SAME:                                      %[[VAL_0:.*]]: !fir.ref<!fir.boxproc<() -> ()>>,
30f3fa603dSjeanPerier! CHECK-SAME:                                      %[[VAL_1:.*]]: !fir.ref<!fir.boxproc<() -> ()>>) {
31*1710c8cfSSlava Zakharin! CHECK:           %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_proc_pointer_2Ep"} : (!fir.ref<!fir.boxproc<() -> ()>>, !fir.dscope) -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
32*1710c8cfSSlava Zakharin! CHECK:           %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_proc_pointer_2Ep_target"} : (!fir.ref<!fir.boxproc<() -> ()>>, !fir.dscope) -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
33f3fa603dSjeanPerier! CHECK:           %[[VAL_4:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.boxproc<() -> ()>>
34f3fa603dSjeanPerier! CHECK:           %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]] : (!fir.boxproc<() -> ()>) -> (() -> ())
35f3fa603dSjeanPerier! CHECK:           %[[VAL_6:.*]] = fir.load %[[VAL_3]]#1 : !fir.ref<!fir.boxproc<() -> ()>>
36f3fa603dSjeanPerier! CHECK:           %[[VAL_7:.*]] = fir.box_addr %[[VAL_6]] : (!fir.boxproc<() -> ()>) -> (() -> ())
37f3fa603dSjeanPerier! CHECK:           %[[VAL_8:.*]] = fir.convert %[[VAL_5]] : (() -> ()) -> i64
38f3fa603dSjeanPerier! CHECK:           %[[VAL_9:.*]] = fir.convert %[[VAL_7]] : (() -> ()) -> i64
39f3fa603dSjeanPerier! CHECK:           %[[VAL_10:.*]] = arith.cmpi eq, %[[VAL_8]], %[[VAL_9]] : i64
40f3fa603dSjeanPerier! CHECK:           %[[VAL_11:.*]] = arith.constant 0 : i64
41f3fa603dSjeanPerier! CHECK:           %[[VAL_12:.*]] = arith.cmpi ne, %[[VAL_11]], %[[VAL_8]] : i64
42f3fa603dSjeanPerier! CHECK:           %[[VAL_13:.*]] = arith.andi %[[VAL_10]], %[[VAL_12]] : i1
43f3fa603dSjeanPerier! CHECK:           %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (i1) -> !fir.logical<4>
44f3fa603dSjeanPerier
45f3fa603dSjeanPeriersubroutine test_proc_pointer_3(p, dummy_proc)
46f3fa603dSjeanPerier  procedure(), pointer :: p
47f3fa603dSjeanPerier  procedure(), optional :: dummy_proc
48f3fa603dSjeanPerier  call takes_log(associated(p, dummy_proc))
49f3fa603dSjeanPerierend subroutine
50f3fa603dSjeanPerier! CHECK-LABEL:   func.func @_QPtest_proc_pointer_3(
51f3fa603dSjeanPerier! CHECK-SAME:                                      %[[VAL_0:.*]]: !fir.ref<!fir.boxproc<() -> ()>>,
52f3fa603dSjeanPerier! CHECK-SAME:                                      %[[VAL_1:.*]]: !fir.boxproc<() -> ()>) {
53*1710c8cfSSlava Zakharin! CHECK:           %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_proc_pointer_3Ep"} : (!fir.ref<!fir.boxproc<() -> ()>>, !fir.dscope) -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
54f3fa603dSjeanPerier! CHECK:           %[[VAL_3:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.boxproc<() -> ()>>
55f3fa603dSjeanPerier! CHECK:           %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> (() -> ())
56f3fa603dSjeanPerier! CHECK:           %[[VAL_5:.*]] = fir.box_addr %[[VAL_1]] : (!fir.boxproc<() -> ()>) -> (() -> ())
57f3fa603dSjeanPerier! CHECK:           %[[VAL_6:.*]] = fir.convert %[[VAL_4]] : (() -> ()) -> i64
58f3fa603dSjeanPerier! CHECK:           %[[VAL_7:.*]] = fir.convert %[[VAL_5]] : (() -> ()) -> i64
59f3fa603dSjeanPerier! CHECK:           %[[VAL_8:.*]] = arith.cmpi eq, %[[VAL_6]], %[[VAL_7]] : i64
60f3fa603dSjeanPerier! CHECK:           %[[VAL_9:.*]] = arith.constant 0 : i64
61f3fa603dSjeanPerier! CHECK:           %[[VAL_10:.*]] = arith.cmpi ne, %[[VAL_9]], %[[VAL_6]] : i64
62f3fa603dSjeanPerier! CHECK:           %[[VAL_11:.*]] = arith.andi %[[VAL_8]], %[[VAL_10]] : i1
63f3fa603dSjeanPerier! CHECK:           %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i1) -> !fir.logical<4>
64f3fa603dSjeanPerier
65f3fa603dSjeanPeriersubroutine test_proc_pointer_4(p)
66f3fa603dSjeanPerier  procedure(), pointer :: p
67f3fa603dSjeanPerier  external :: some_external
68f3fa603dSjeanPerier  call takes_log(associated(p, some_external))
69f3fa603dSjeanPerierend subroutine
70f3fa603dSjeanPerier! CHECK-LABEL:   func.func @_QPtest_proc_pointer_4(
71f3fa603dSjeanPerier! CHECK-SAME:                                      %[[VAL_0:.*]]: !fir.ref<!fir.boxproc<() -> ()>>) {
72*1710c8cfSSlava Zakharin! CHECK:           %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_proc_pointer_4Ep"} : (!fir.ref<!fir.boxproc<() -> ()>>, !fir.dscope) -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
73f3fa603dSjeanPerier! CHECK:           %[[VAL_2:.*]] = fir.address_of(@_QPsome_external) : () -> ()
74f3fa603dSjeanPerier! CHECK:           %[[VAL_3:.*]] = fir.emboxproc %[[VAL_2]] : (() -> ()) -> !fir.boxproc<() -> ()>
75f3fa603dSjeanPerier! CHECK:           %[[VAL_4:.*]] = fir.load %[[VAL_1]]#1 : !fir.ref<!fir.boxproc<() -> ()>>
76f3fa603dSjeanPerier! CHECK:           %[[VAL_5:.*]] = fir.box_addr %[[VAL_4]] : (!fir.boxproc<() -> ()>) -> (() -> ())
77f3fa603dSjeanPerier! CHECK:           %[[VAL_6:.*]] = fir.box_addr %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> (() -> ())
78f3fa603dSjeanPerier! CHECK:           %[[VAL_7:.*]] = fir.convert %[[VAL_5]] : (() -> ()) -> i64
79f3fa603dSjeanPerier! CHECK:           %[[VAL_8:.*]] = fir.convert %[[VAL_6]] : (() -> ()) -> i64
80f3fa603dSjeanPerier! CHECK:           %[[VAL_9:.*]] = arith.cmpi eq, %[[VAL_7]], %[[VAL_8]] : i64
81f3fa603dSjeanPerier! CHECK:           %[[VAL_10:.*]] = arith.constant 0 : i64
82f3fa603dSjeanPerier! CHECK:           %[[VAL_11:.*]] = arith.cmpi ne, %[[VAL_10]], %[[VAL_7]] : i64
83f3fa603dSjeanPerier! CHECK:           %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_11]] : i1
84f3fa603dSjeanPerier! CHECK:           %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i1) -> !fir.logical<4>
85f3fa603dSjeanPerier
86f3fa603dSjeanPeriersubroutine test_proc_pointer_5(p, dummy_proc)
87f3fa603dSjeanPerier  interface
88f3fa603dSjeanPerier    character(10) function char_func()
89f3fa603dSjeanPerier    end function
90f3fa603dSjeanPerier  end interface
91f3fa603dSjeanPerier  procedure(char_func), pointer :: p
92f3fa603dSjeanPerier  procedure(char_func) :: dummy_proc
93f3fa603dSjeanPerier  call takes_log(associated(p, dummy_proc))
94f3fa603dSjeanPerierend subroutine
95f3fa603dSjeanPerier! CHECK-LABEL:   func.func @_QPtest_proc_pointer_5(
96f3fa603dSjeanPerier! CHECK-SAME:                                      %[[VAL_0:.*]]: !fir.ref<!fir.boxproc<() -> ()>>,
97f3fa603dSjeanPerier! CHECK-SAME:                                      %[[VAL_1:.*]]: tuple<!fir.boxproc<() -> ()>, i64> {fir.char_proc}) {
98*1710c8cfSSlava Zakharin! CHECK:           %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %{{[0-9]+}} {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtest_proc_pointer_5Ep"} : (!fir.ref<!fir.boxproc<() -> ()>>, !fir.dscope) -> (!fir.ref<!fir.boxproc<() -> ()>>, !fir.ref<!fir.boxproc<() -> ()>>)
99f3fa603dSjeanPerier! CHECK:           %[[VAL_3:.*]] = fir.extract_value %[[VAL_1]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>) -> !fir.boxproc<() -> ()>
100f3fa603dSjeanPerier! CHECK:           %[[VAL_4:.*]] = fir.box_addr %[[VAL_3]] : (!fir.boxproc<() -> ()>) -> (() -> ())
101f3fa603dSjeanPerier! CHECK:           %[[VAL_5:.*]] = arith.constant 10 : i64
102f3fa603dSjeanPerier! CHECK:           %[[VAL_6:.*]] = fir.emboxproc %[[VAL_4]] : (() -> ()) -> !fir.boxproc<() -> ()>
103f3fa603dSjeanPerier! CHECK:           %[[VAL_7:.*]] = fir.undefined tuple<!fir.boxproc<() -> ()>, i64>
104f3fa603dSjeanPerier! CHECK:           %[[VAL_8:.*]] = fir.insert_value %[[VAL_7]], %[[VAL_6]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, !fir.boxproc<() -> ()>) -> tuple<!fir.boxproc<() -> ()>, i64>
105f3fa603dSjeanPerier! CHECK:           %[[VAL_9:.*]] = fir.insert_value %[[VAL_8]], %[[VAL_5]], [1 : index] : (tuple<!fir.boxproc<() -> ()>, i64>, i64) -> tuple<!fir.boxproc<() -> ()>, i64>
106f3fa603dSjeanPerier! CHECK:           %[[VAL_10:.*]] = fir.extract_value %[[VAL_9]], [0 : index] : (tuple<!fir.boxproc<() -> ()>, i64>) -> !fir.boxproc<() -> ()>
107f3fa603dSjeanPerier! CHECK:           %[[VAL_11:.*]] = fir.load %[[VAL_2]]#1 : !fir.ref<!fir.boxproc<() -> ()>>
108f3fa603dSjeanPerier! CHECK:           %[[VAL_12:.*]] = fir.box_addr %[[VAL_11]] : (!fir.boxproc<() -> ()>) -> (() -> ())
109f3fa603dSjeanPerier! CHECK:           %[[VAL_13:.*]] = fir.box_addr %[[VAL_10]] : (!fir.boxproc<() -> ()>) -> (() -> ())
110f3fa603dSjeanPerier! CHECK:           %[[VAL_14:.*]] = fir.convert %[[VAL_12]] : (() -> ()) -> i64
111f3fa603dSjeanPerier! CHECK:           %[[VAL_15:.*]] = fir.convert %[[VAL_13]] : (() -> ()) -> i64
112f3fa603dSjeanPerier! CHECK:           %[[VAL_16:.*]] = arith.cmpi eq, %[[VAL_14]], %[[VAL_15]] : i64
113f3fa603dSjeanPerier! CHECK:           %[[VAL_17:.*]] = arith.constant 0 : i64
114f3fa603dSjeanPerier! CHECK:           %[[VAL_18:.*]] = arith.cmpi ne, %[[VAL_17]], %[[VAL_14]] : i64
115f3fa603dSjeanPerier! CHECK:           %[[VAL_19:.*]] = arith.andi %[[VAL_16]], %[[VAL_18]] : i1
116f3fa603dSjeanPerier! CHECK:           %[[VAL_20:.*]] = fir.convert %[[VAL_19]] : (i1) -> !fir.logical<4>
117cdb320b4SDaniel Chen
118cdb320b4SDaniel Chensubroutine test_proc_pointer_6()
119cdb320b4SDaniel Chen  interface
120cdb320b4SDaniel Chen    real function func()
121cdb320b4SDaniel Chen    end
122cdb320b4SDaniel Chen  end interface
123cdb320b4SDaniel Chen  logical :: ll
124cdb320b4SDaniel Chen  ll = associated(reffunc(), func)
125cdb320b4SDaniel Chencontains
126cdb320b4SDaniel Chen  function reffunc() result(pp)
127cdb320b4SDaniel Chen    procedure(func), pointer :: pp
128cdb320b4SDaniel Chen  end
129cdb320b4SDaniel Chenend
130cdb320b4SDaniel Chen! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<4> {bindc_name = "ll", uniq_name = "_QFtest_proc_pointer_6Ell"}
131cdb320b4SDaniel Chen! CHECK: %[[VAL_1:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtest_proc_pointer_6Ell"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
132cdb320b4SDaniel Chen! CHECK: %[[VAL_2:.*]] = fir.call @_QFtest_proc_pointer_6Preffunc() fastmath<contract> : () -> !fir.boxproc<() -> f32>
133cdb320b4SDaniel Chen! CHECK: %[[VAL_3:.*]] = fir.address_of(@_QPfunc) : () -> f32
134cdb320b4SDaniel Chen! CHECK: %[[VAL_4:.*]] = fir.emboxproc %[[VAL_3]] : (() -> f32) -> !fir.boxproc<() -> ()>
135cdb320b4SDaniel Chen! CHECK: %[[VAL_5:.*]] = fir.box_addr %[[VAL_2]] : (!fir.boxproc<() -> f32>) -> (() -> f32)
136cdb320b4SDaniel Chen! CHECK: %[[VAL_6:.*]] = fir.box_addr %[[VAL_4]] : (!fir.boxproc<() -> ()>) -> (() -> ())
137cdb320b4SDaniel Chen! CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_5]] : (() -> f32) -> i64
138cdb320b4SDaniel Chen! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_6]] : (() -> ()) -> i64
139cdb320b4SDaniel Chen! CHECK: %[[VAL_9:.*]] = arith.cmpi eq, %[[VAL_7]], %[[VAL_8]] : i64
140cdb320b4SDaniel Chen! CHECK: %c0_i64 = arith.constant 0 : i64
141cdb320b4SDaniel Chen! CHECK: %[[VAL_10:.*]] = arith.cmpi ne, %c0_i64, %[[VAL_7]] : i64
142cdb320b4SDaniel Chen! CHECK: %[[VAL_11:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1
143cdb320b4SDaniel Chen! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i1) -> !fir.logical<4>
144cdb320b4SDaniel Chen! CHECK: hlfir.assign %[[VAL_12]] to %[[VAL_1]]#0 : !fir.logical<4>, !fir.ref<!fir.logical<4>>
145