[flang] Accept polymorphic component element in storage_size
[llvm-project.git] / flang / test / HLFIR / associate-codegen.fir
bloba151e7ca5368c9a421223ac729474f3ff68483da
1 // Test hlfir.associate/hlfir.end_associate operation code generation to FIR.
3 // RUN: fir-opt %s -bufferize-hlfir | FileCheck %s
5 func.func @associate_int() {
6   %c42_i32 = arith.constant 42 : i32
7   %0:3 = hlfir.associate %c42_i32 {uniq_name = "x"} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)
8   fir.call @take_i4(%0#0) : (!fir.ref<i32>) -> ()
9   hlfir.end_associate %0#1, %0#2 : !fir.ref<i32>, i1
10   return
12 // CHECK-LABEL:   func.func @associate_int() {
13 // CHECK:  %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "x"}
14 // CHECK:  %[[VAL_1:.*]] = arith.constant 42 : i32
15 // CHECK:  fir.store %[[VAL_1]] to %[[VAL_0]] : !fir.ref<i32>
16 // CHECK:  %[[VAL_2:.*]] = arith.constant false
17 // CHECK:  fir.call @take_i4(%[[VAL_0]]) : (!fir.ref<i32>) -> ()
18 // CHECK-NOT: fir.freemem
21 func.func @associate_real() {
22   %cst = arith.constant 4.200000e-01 : f32
23   %0:3 = hlfir.associate %cst {uniq_name = "x"} : (f32) -> (!fir.ref<f32>, !fir.ref<f32>, i1)
24   fir.call @take_r4(%0#0) : (!fir.ref<f32>) -> ()
25   hlfir.end_associate %0#1, %0#2 : !fir.ref<f32>, i1
26   return
28 // CHECK-LABEL:   func.func @associate_real() {
29 // CHECK:  %[[VAL_0:.*]] = fir.alloca f32 {bindc_name = "x"}
30 // CHECK:  %[[VAL_1:.*]] = arith.constant 4.200000e-01 : f32
31 // CHECK:  fir.store %[[VAL_1]] to %[[VAL_0]] : !fir.ref<f32>
32 // CHECK:  %[[VAL_2:.*]] = arith.constant false
33 // CHECK:  fir.call @take_r4(%[[VAL_0]]) : (!fir.ref<f32>) -> ()
34 // CHECK-NOT: fir.freemem
37 func.func @associate_logical() {
38   %true = arith.constant true
39   %0 = fir.convert %true : (i1) -> !fir.logical<4>
40   %1:3 = hlfir.associate %0 {uniq_name = "x"} : (!fir.logical<4>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>, i1)
41   fir.call @take_l4(%1#0) : (!fir.ref<!fir.logical<4>>) -> ()
42   hlfir.end_associate %1#1, %1#2 : !fir.ref<!fir.logical<4>>, i1
43   return
45 // CHECK-LABEL:   func.func @associate_logical() {
46 // CHECK:  %[[VAL_0:.*]] = fir.alloca !fir.logical<4> {bindc_name = "x"}
47 // CHECK:  %[[VAL_1:.*]] = arith.constant true
48 // CHECK:  %[[VAL_2:.*]] = fir.convert %[[VAL_1]] : (i1) -> !fir.logical<4>
49 // CHECK:  fir.store %[[VAL_2]] to %[[VAL_0]] : !fir.ref<!fir.logical<4>>
50 // CHECK:  %[[VAL_3:.*]] = arith.constant false
51 // CHECK:  fir.call @take_l4(%[[VAL_0]]) : (!fir.ref<!fir.logical<4>>) -> ()
52 // CHECK-NOT: fir.freemem
55 func.func @associate_char(%arg0: !fir.boxchar<1> ) {
56   %0:2 = fir.unboxchar %arg0 : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
57   %1:2 = hlfir.declare %0#0 typeparams %0#1 {uniq_name = "x"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
58   %2 = arith.addi %0#1, %0#1 : index
59   %3 = hlfir.concat %1#0, %1#0 len %2 : (!fir.boxchar<1>, !fir.boxchar<1>, index) -> !hlfir.expr<!fir.char<1,?>>
60   %4:3 = hlfir.associate %3 typeparams %2 {uniq_name = "x"} : (!hlfir.expr<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>, i1)
61   fir.call @take_c(%4#0) : (!fir.boxchar<1>) -> ()
62   hlfir.end_associate %4#1, %4#2 : !fir.ref<!fir.char<1,?>>, i1
63   return
65 // CHECK-LABEL:   func.func @associate_char(
66 // CHECK-SAME:    %[[VAL_0:.*]]: !fir.boxchar<1>) {
67 // CHECK:  %[[VAL_1:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref<!fir.char<1,?>>, index)
68 // CHECK:  %[[VAL_2:.*]]:2 = hlfir.declare %[[VAL_1]]#0 typeparams %[[VAL_1]]#1 {uniq_name = "x"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
69 // CHECK:  %[[VAL_3:.*]] = arith.addi %[[VAL_1]]#1, %[[VAL_1]]#1 : index
70 // CHECK:  %[[VAL_4:.*]] = arith.addi %[[VAL_1]]#1, %[[VAL_1]]#1 : index
71 // CHECK:  %[[VAL_5:.*]] = fir.alloca !fir.char<1,?>(%[[VAL_4]] : index) {bindc_name = ".chrtmp"}
72 // CHECK:  fir.call @llvm.memmove.p0.p0.i64
73 // CHECK:  %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_5]] typeparams %[[VAL_4]] {uniq_name = "tmp"} : (!fir.ref<!fir.char<1,?>>, index) -> (!fir.boxchar<1>, !fir.ref<!fir.char<1,?>>)
74 // CHECK:  %[[VAL_22:.*]] = arith.constant false
75 // CHECK:  %[[VAL_23:.*]] = fir.undefined tuple<!fir.boxchar<1>, i1>
76 // CHECK:  %[[VAL_24:.*]] = fir.insert_value %[[VAL_23]], %[[VAL_22]], [1 : index] : (tuple<!fir.boxchar<1>, i1>, i1) -> tuple<!fir.boxchar<1>, i1>
77 // CHECK:  %[[VAL_25:.*]] = fir.insert_value %[[VAL_24]], %[[VAL_21]]#0, [0 : index] : (tuple<!fir.boxchar<1>, i1>, !fir.boxchar<1>) -> tuple<!fir.boxchar<1>, i1>
78 // CHECK:  fir.call @take_c(%[[VAL_21]]#0) : (!fir.boxchar<1>) -> ()
79 // CHECK-NOT: fir.freemem
82 func.func @test_end_associate_box(%var: !fir.box<!fir.array<?xf64>>) {
83   %true = arith.constant 1 : i1
84   hlfir.end_associate %var, %true : !fir.box<!fir.array<?xf64>>, i1
85   return
87 // CHECK-LABEL:   func.func @test_end_associate_box(
88 // CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>) {
89 // CHECK:  %[[VAL_1:.*]] = arith.constant true
90 // CHECK:  %[[VAL_2:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.heap<!fir.array<?xf64>>
91 // CHECK:  fir.freemem %[[VAL_2]] : !fir.heap<!fir.array<?xf64>>
94 func.func @test_end_associate_boxchar(%var: !fir.boxchar<2>) {
95   %true = arith.constant 1 : i1
96   hlfir.end_associate %var, %true : !fir.boxchar<2>, i1
97   return
99 // CHECK-LABEL:   func.func @test_end_associate_boxchar(
100 // CHECK-SAME:    %[[VAL_0:.*]]: !fir.boxchar<2>) {
101 // CHECK:  %[[VAL_1:.*]] = arith.constant true
102 // CHECK:  %[[VAL_2:.*]] = fir.box_addr %[[VAL_0]] : (!fir.boxchar<2>) -> !fir.heap<!fir.char<2,?>>
103 // CHECK:  fir.freemem %[[VAL_2]] : !fir.heap<!fir.char<2,?>>
106 func.func @test_end_associate_box_dynamic(%var: !fir.box<!fir.array<?xf64>>, %must_free: i1) {
107   hlfir.end_associate %var, %must_free : !fir.box<!fir.array<?xf64>>, i1
108   return
110 // CHECK-LABEL:   func.func @test_end_associate_box_dynamic(
111 // CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?xf64>>,
112 // CHECK-SAME:    %[[VAL_1:.*]]: i1) {
113 // CHECK:  fir.if %[[VAL_1]] {
114 // CHECK:    %[[VAL_2:.*]] = fir.box_addr %[[VAL_0]] : (!fir.box<!fir.array<?xf64>>) -> !fir.heap<!fir.array<?xf64>>
115 // CHECK:    fir.freemem %[[VAL_2]] : !fir.heap<!fir.array<?xf64>>
116 // CHECK:  }
118 func.func private @bar(!fir.ref<!fir.array<?xi32>>) -> ()
119 func.func @test_result_box_addr(%x : !fir.box<!fir.array<?xi32>>) {
120   %true = arith.constant 1 : i1
121   %expr = hlfir.as_expr %x move %true : (!fir.box<!fir.array<?xi32>>, i1) -> !hlfir.expr<?xi32>
122   %y:3 = hlfir.associate %expr {uniq_name = "y"}: (!hlfir.expr<?xi32>) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>, i1)
123   fir.call @bar(%y#1) : (!fir.ref<!fir.array<?xi32>>) -> ()
124   return
126 // CHECK-LABEL: func.func @test_result_box_addr(
127 // CHECK-SAME: %[[X:.*]]: !fir.box<!fir.array<?xi32>>) {
128 // CHECK:  %[[ADDR:.*]] = fir.box_addr %[[X]] : (!fir.box<!fir.array<?xi32>>) -> !fir.ref<!fir.array<?xi32>>
129 // CHECK: fir.call @bar(%[[ADDR]]) : (!fir.ref<!fir.array<?xi32>>) -> ()
131 func.func private @bar2(!fir.ref<!fir.array<10xi32>>) -> ()
132 func.func @test_result_convert(%x : !fir.heap<!fir.array<10xi32>>) {
133   %true = arith.constant 1 : i1
134   %expr = hlfir.as_expr %x move %true : (!fir.heap<!fir.array<10xi32>>, i1) -> !hlfir.expr<10xi32>
135   %y:3 = hlfir.associate %expr {uniq_name = "y"}: (!hlfir.expr<10xi32>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>, i1)
136   fir.call @bar2(%y#1) : (!fir.ref<!fir.array<10xi32>>) -> ()
137   return
139 // CHECK-LABEL: func.func @test_result_convert(
140 // CHECK-SAME: %[[X:.*]]: !fir.heap<!fir.array<10xi32>>) {
141 // CHECK: fir.convert
142 // CHECK:  %[[ADDR:.*]] = fir.convert %[[X]] : (!fir.heap<!fir.array<10xi32>>) -> !fir.ref<!fir.array<10xi32>>
143 // CHECK: fir.call @bar2(%[[ADDR]]) : (!fir.ref<!fir.array<10xi32>>) -> ()
146 func.func private @take_i4(!fir.ref<i32>)
147 func.func private @take_r4(!fir.ref<f32>)
148 func.func private @take_l4(!fir.ref<!fir.logical<4>>)
149 func.func private @take_c(!fir.boxchar<1>)