[flang] Accept polymorphic component element in storage_size
[llvm-project.git] / flang / test / Lower / character-assignment.f90
blobdc5bf6852de76a3b6419002a260bfa44ebd38a09
1 ! RUN: bbc %s -o - -emit-fir | FileCheck %s
3 ! Simple character assignment tests
4 ! CHECK-LABEL: _QPassign1
5 subroutine assign1(lhs, rhs)
6 character(*, 1) :: lhs, rhs
7 ! CHECK: %[[lhs:.*]]:2 = fir.unboxchar %arg0
8 ! CHECK: %[[rhs:.*]]:2 = fir.unboxchar %arg1
9 lhs = rhs
10 ! Compute minimum length
11 ! CHECK: %[[cmp_len:[0-9]+]] = arith.cmpi slt, %[[lhs:.*]]#1, %[[rhs:.*]]#1
12 ! CHECK-NEXT: %[[min_len:[0-9]+]] = arith.select %[[cmp_len]], %[[lhs]]#1, %[[rhs]]#1
14 ! Copy of rhs into lhs
15 ! CHECK: %[[count:.*]] = arith.muli %{{.*}}, %{{.*}} : i64
16 ! CHECK-DAG: %[[bug:.*]] = fir.convert %[[lhs]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
17 ! CHECK-DAG: %[[src:.*]] = fir.convert %[[rhs]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
18 ! CHECK: fir.call @llvm.memmove.p0.p0.i64(%{{.*}}, %[[src]], %[[count]], %false) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
20 ! Padding
21 ! CHECK-DAG: %[[blank:.*]] = fir.insert_value %{{.*}}, %c32{{.*}}, [0 : index] : (!fir.char<1>, i8) -> !fir.char<1>
22 ! CHECK: fir.do_loop %[[ij:.*]] =
23 ! CHECK-DAG: %[[lhs_cast:.*]] = fir.convert %[[lhs]]#0
24 ! CHECK: %[[lhs_addr:.*]] = fir.coordinate_of %[[lhs_cast]], %[[ij]]
25 ! CHECK: fir.store %[[blank]] to %[[lhs_addr]]
26 ! CHECK-NEXT: }
27 end subroutine
29 ! Test substring assignment
30 ! CHECK-LABEL: _QPassign_substring1
31 subroutine assign_substring1(str, rhs, lb, ub)
32 character(*, 1) :: rhs, str
33 integer(8) :: lb, ub
34 str(lb:ub) = rhs
35 ! CHECK-DAG: %[[lb:.*]] = fir.load %arg2
36 ! CHECK-DAG: %[[ub:.*]] = fir.load %arg3
37 ! CHECK-DAG: %[[str:.*]]:2 = fir.unboxchar %arg0
39 ! Compute substring offset
40 ! CHECK-DAG: %[[lbi:.*]] = fir.convert %[[lb]] : (i64) -> index
41 ! CHECK-DAG: %[[c1:.*]] = arith.constant 1
42 ! CHECK-DAG: %[[offset:.*]] = arith.subi %[[lbi]], %[[c1]]
43 ! CHECK-DAG: %[[str_cast:.*]] = fir.convert %[[str]]#0
44 ! CHECK-DAG: %[[str_addr:.*]] = fir.coordinate_of %[[str_cast]], %[[offset]]
45 ! CHECK-DAG: %[[lhs_addr:.*]] = fir.convert %[[str_addr]]
47 ! Compute substring length
48 ! CHECK-DAG: %[[ubi:.*]] = fir.convert %[[ub]] : (i64) -> index
49 ! CHECK-DAG: %[[diff:.*]] = arith.subi %[[ubi]], %[[lbi]]
50 ! CHECK-DAG: %[[pre_lhs_len:.*]] = arith.addi %[[diff]], %[[c1]]
51 ! CHECK-DAG: %[[c0:.*]] = arith.constant 0
52 ! CHECK-DAG: %[[cmp_len:.*]] = arith.cmpi slt, %[[pre_lhs_len]], %[[c0]]
54 ! CHECK-DAG: %[[lhs_len:.*]] = arith.select %[[cmp_len]], %[[c0]], %[[pre_lhs_len]]
56 ! The rest of the assignment is just as the one above, only test that the
57 ! substring is the one used as lhs.
58 ! ...
59 ! CHECK: fir.do_loop %arg4 =
60 ! CHECK: %[[lhs_addr3:.*]] = fir.convert %[[lhs_addr]]
61 ! CHECK: fir.coordinate_of %[[lhs_addr3]], %arg4
62 ! ...
63 end subroutine
65 ! CHECK-LABEL: _QPassign_constant
66 ! CHECK-SAME: (%[[ARG:.*]]:
67 subroutine assign_constant(lhs)
68 character(*, 1) :: lhs
69 ! CHECK: %[[lhs:.*]]:2 = fir.unboxchar %arg0
70 ! CHECK: %[[cst:.*]] = fir.address_of(@{{.*}}) :
71 lhs = "Hello World"
72 ! CHECK-DAG: %[[dst:.*]] = fir.convert %[[lhs]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<i8>
73 ! CHECK-DAG: %[[src:.*]] = fir.convert %[[cst]] : (!fir.ref<!fir.char<1,11>>) -> !fir.ref<i8>
74 ! CHECK-DAG: %[[count:.*]] = arith.muli %{{.*}}, %{{.*}} : i64
75 ! CHECK: fir.call @llvm.memmove.p0.p0.i64(%[[dst]], %[[src]], %[[count]], %false) {{.*}}: (!fir.ref<i8>, !fir.ref<i8>, i64, i1) -> ()
77 ! Padding
78 ! CHECK-DAG: %[[blank:.*]] = fir.insert_value %{{.*}}, %c32{{.*}}, [0 : index] : (!fir.char<1>, i8) -> !fir.char<1>
79 ! CHECK: fir.do_loop %[[j:.*]] = %{{.*}} to %{{.*}} {
80 ! CHECK-DAG: %[[jhs_cast:.*]] = fir.convert %[[lhs]]#0 : (!fir.ref<!fir.char<1,?>>) -> !fir.ref<!fir.array<?x!fir.char<1>>>
81 ! CHECK: %[[jhs_addr:.*]] = fir.coordinate_of %[[jhs_cast]], %[[j]]
82 ! CHECK: fir.store %[[blank]] to %[[jhs_addr]]
83 ! CHECK: }
84 end subroutine
86 ! CHECK: func @_QPassign_zero_size_array
87 subroutine assign_zero_size_array(n)
88 ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.heap<!fir.array<?x!fir.char<1,?>>> {uniq_name = "_QFassign_zero_size_arrayEa.addr"}
89 character(n), allocatable :: a(:)
90 ! CHECK: fir.store %{{.*}} to %[[VAL_0]] : !fir.ref<!fir.heap<!fir.array<?x!fir.char<1,?>>>>
91 ! CHECK: %{{.*}} = fir.load %[[VAL_0]] : !fir.ref<!fir.heap<!fir.array<?x!fir.char<1,?>>>>
92 ! CHECK: %[[VAL_1:.*]] = arith.cmpi ne, %{{.*}}, %c0{{.*}} : i64
93 ! CHECK: %[[VAL_2:.*]]:2 = fir.if %[[VAL_1]] -> (i1, !fir.heap<!fir.array<?x!fir.char<1,?>>>) {
94 ! CHECK: %{{.*}} = fir.if %{{.*}} -> (!fir.heap<!fir.array<?x!fir.char<1,?>>>) {
95 ! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %c0{{.*}} to %{{.*}} step %c1{{.*}} unordered iter_args(%{{.*}} = %{{.*}}) -> (!fir.array<?x!fir.char<1,?>>) {
96 ! CHECK: fir.do_loop %[[ARG_0:.*]] = %{{.*}} to {{.*}} step %c1{{.*}} {
97 ! CHECK: %{{.*}} = fir.coordinate_of %{{.*}}, %[[ARG_0]] : (!fir.ref<!fir.array<?x!fir.char<1>>>, index) -> !fir.ref<!fir.char<1>>
98 ! CHECK: fir.if %[[VAL_2]]#0 {
99 ! CHECK: fir.if %[[VAL_1]] {
100 ! CHECK: fir.store %[[VAL_2]]#1 to %[[VAL_0]] : !fir.ref<!fir.heap<!fir.array<?x!fir.char<1,?>>>>
101 a = [character(n)::]
102 ! CHECK: return
103 end subroutine
105 ! CHECK-LABEL: fir.global linkonce @_QQcl.48656C6C6F20576F726C64
106 ! CHECK: %[[lit:.*]] = fir.string_lit "Hello World"(11) : !fir.char<1,11>
107 ! CHECK: fir.has_value %[[lit]] : !fir.char<1,11>
108 ! CHECK: }