xref: /llvm-project/flang/test/Lower/array-derived.f90 (revision a88677edc0792534ba3157bf7d7a1b98e470f2fb)
1! RUN: bbc -hlfir=false -fwrapv %s -o - | FileCheck %s
2
3module cs
4  type r
5     integer n, d
6  end type r
7
8  type t2
9     integer :: f1(5)
10     type(r) :: f2
11  end type t2
12
13  type t3
14     type(t2) :: f(3,3)
15  end type t3
16
17contains
18
19  ! CHECK: func @_QMcsPc1(
20  ! CHECK-SAME:   %[[arg0:[^:]+]]: !fir.box<!fir.array<?x!fir.type<_QMcsTr{n:i32,d:i32}>>>{{.*}}, %[[arg1:[^:]+]]: !fir.box<!fir.array<?x!fir.type<_QMcsTr{n:i32,d:i32}>>>{{.*}})
21  function c1(e, c)
22    type(r), intent(in) :: e(:), c(:)
23    ! CHECK-DAG: fir.alloca !fir.logical<1> {bindc_name = "c1", uniq_name = "_QMcsFc1Ec1"}
24    logical*1 :: c1
25    ! CHECK-DAG: %[[fldn:.*]] = fir.field_index n, !fir.type<_QMcsTr{n:i32,d:i32}>
26    ! CHECK: %[[ext1:.*]]:3 = fir.box_dims %[[arg1]], %c0{{.*}} : (!fir.box<!fir.array<?x!fir.type<_QMcsTr{n:i32,d:i32}>>>, index) -> (index, index, index)
27    ! CHECK-DAG: %[[slice1:.*]] = fir.slice %c1{{.*}}, %[[ext1]]#1, %c1{{.*}} path %[[fldn]] : (index, index, index, !fir.field) -> !fir.slice<1>
28    ! CHECK-DAG: %[[ext0:.*]]:3 = fir.box_dims %[[arg0]], %c0{{.*}} : (!fir.box<!fir.array<?x!fir.type<_QMcsTr{n:i32,d:i32}>>>, index) -> (index, index, index)
29    ! CHECK: %[[slice0:.*]] = fir.slice %c1{{.*}}, %[[ext0]]#1, %c1{{.*}} path %[[fldn]] : (index, index, index, !fir.field) -> !fir.slice<1>
30    ! CHECK-DAG: = fir.array_coor %[[arg1]] [%[[slice1]]] %[[index:.*]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTr{n:i32,d:i32}>>>, !fir.slice<1>, index) -> !fir.ref<i32>
31    ! CHECK-DAG: = fir.array_coor %[[arg0]] [%[[slice0]]] %[[index]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTr{n:i32,d:i32}>>>, !fir.slice<1>, index) -> !fir.ref<i32>
32    ! CHECK: = fir.call @_FortranAAllLogical4x1_simplified(
33    c1 = all(c%n == e%n)
34  end function c1
35
36! CHECK-LABEL: func @_QMcsPtest2(
37! CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>>{{.*}}, %[[VAL_1:.*]]: !fir.box<!fir.array<?x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>>{{.*}}) {
38! CHECK-DAG:     %[[VAL_2:.*]] = arith.constant 2 : index
39! CHECK-DAG:     %[[VAL_3:.*]] = arith.constant 4 : index
40! CHECK-DAG:     %[[VAL_4:.*]] = arith.constant 0 : index
41! CHECK-DAG:     %[[VAL_5:.*]] = arith.constant 1 : index
42! CHECK:         %[[VAL_6:.*]] = fir.field_index f2, !fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>
43! CHECK:         %[[VAL_7:.*]] = fir.field_index d, !fir.type<_QMcsTr{n:i32,d:i32}>
44! CHECK:         %[[VAL_8:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_4]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>>, index) -> (index, index, index)
45! CHECK:         %[[VAL_9:.*]] = fir.slice %[[VAL_5]], %[[VAL_8]]#1, %[[VAL_5]] path %[[VAL_6]], %[[VAL_7]] : (index, index, index, !fir.field, !fir.field) -> !fir.slice<1>
46! CHECK:         %[[VAL_8_2:.*]] = arith.cmpi sgt, %[[VAL_8]]#1, %[[VAL_4]] : index
47! CHECK:         %[[VAL_8_3:.*]] = arith.select %[[VAL_8_2]], %[[VAL_8]]#1, %[[VAL_4]] : index
48! CHECK:         %[[VAL_10:.*]] = fir.field_index f1, !fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>
49! CHECK:         %[[VAL_11:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_4]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>>, index) -> (index, index, index)
50! CHECK:         %[[VAL_12:.*]] = fir.slice %[[VAL_5]], %[[VAL_11]]#1, %[[VAL_5]] path %[[VAL_10]], %[[VAL_4]] : (index, index, index, !fir.field, index) -> !fir.slice<1>
51! CHECK:         %[[VAL_13:.*]] = fir.slice %[[VAL_5]], %[[VAL_11]]#1, %[[VAL_5]] path %[[VAL_10]], %[[VAL_3]] : (index, index, index, !fir.field, index) -> !fir.slice<1>
52! CHECK:         %[[VAL_14:.*]] = fir.slice %[[VAL_5]], %[[VAL_11]]#1, %[[VAL_5]] path %[[VAL_10]], %[[VAL_2]] : (index, index, index, !fir.field, index) -> !fir.slice<1>
53! CHECK:         br ^bb1(%[[VAL_4]], %[[VAL_8_3]] : index, index)
54! CHECK:       ^bb1(%[[VAL_15:.*]]: index, %[[VAL_16:.*]]: index):
55! CHECK:         %[[VAL_17:.*]] = arith.cmpi sgt, %[[VAL_16]], %[[VAL_4]] : index
56! CHECK:         cond_br %[[VAL_17]], ^bb2, ^bb3
57! CHECK:       ^bb2:
58! CHECK:         %[[VAL_18:.*]] = arith.addi %[[VAL_15]], %[[VAL_5]] : index
59! CHECK:         %[[VAL_19:.*]] = fir.array_coor %[[VAL_1]] {{\[}}%[[VAL_12]]] %[[VAL_18]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>>, !fir.slice<1>, index) -> !fir.ref<i32>
60! CHECK:         %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<i32>
61! CHECK:         %[[VAL_21:.*]] = fir.array_coor %[[VAL_1]] {{\[}}%[[VAL_13]]] %[[VAL_18]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>>, !fir.slice<1>, index) -> !fir.ref<i32>
62! CHECK:         %[[VAL_22:.*]] = fir.load %[[VAL_21]] : !fir.ref<i32>
63! CHECK:         %[[VAL_23:.*]] = fir.array_coor %[[VAL_1]] {{\[}}%[[VAL_14]]] %[[VAL_18]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>>, !fir.slice<1>, index) -> !fir.ref<i32>
64! CHECK:         %[[VAL_24:.*]] = fir.load %[[VAL_23]] : !fir.ref<i32>
65! CHECK:         %[[VAL_25:.*]] = arith.divsi %[[VAL_22]], %[[VAL_24]] : i32
66! CHECK:         %[[VAL_26:.*]] = arith.addi %[[VAL_20]], %[[VAL_25]] : i32
67! CHECK:         %[[VAL_27:.*]] = fir.array_coor %[[VAL_0]] {{\[}}%[[VAL_9]]] %[[VAL_18]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>>, !fir.slice<1>, index) -> !fir.ref<i32>
68! CHECK:         fir.store %[[VAL_26]] to %[[VAL_27]] : !fir.ref<i32>
69! CHECK:         %[[VAL_28:.*]] = arith.subi %[[VAL_16]], %[[VAL_5]] : index
70! CHECK:         br ^bb1(%[[VAL_18]], %[[VAL_28]] : index, index)
71! CHECK:       ^bb3:
72! CHECK:         return
73! CHECK:       }
74
75
76  subroutine test2(a1, a2)
77    type(t2) :: a1(:), a2(:)
78    a1%f2%d = a2%f1(1) + a2%f1(5) / a2%f1(3)
79  end subroutine test2
80
81! CHECK-LABEL: func @_QMcsPtest3(
82! CHECK-SAME:    %[[VAL_0:.*]]: !fir.box<!fir.array<?x!fir.type<_QMcsTt3{f:!fir.array<3x3x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>}>>>{{.*}}, %[[VAL_1:.*]]: !fir.box<!fir.array<?x!fir.type<_QMcsTt3{f:!fir.array<3x3x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>}>>>{{.*}}) {
83! CHECK-DAG:     %[[VAL_2:.*]] = arith.constant 2 : index
84! CHECK-DAG:     %[[VAL_3:.*]] = arith.constant 3 : index
85! CHECK-DAG:     %[[VAL_4:.*]] = arith.constant 4 : i32
86! CHECK-DAG:     %[[VAL_5:.*]] = arith.constant 1 : index
87! CHECK-DAG:     %[[VAL_6:.*]] = arith.constant 0 : index
88! CHECK:         %[[VAL_7:.*]] = fir.field_index f, !fir.type<_QMcsTt3{f:!fir.array<3x3x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>}>
89! CHECK:         %[[VAL_8:.*]] = fir.field_index f2, !fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>
90! CHECK:         %[[VAL_9:.*]] = fir.field_index n, !fir.type<_QMcsTr{n:i32,d:i32}>
91! CHECK:         %[[VAL_10:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_6]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt3{f:!fir.array<3x3x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>}>>>, index) -> (index, index, index)
92! CHECK:         %[[VAL_11:.*]] = fir.slice %[[VAL_5]], %[[VAL_10]]#1, %[[VAL_5]] path %[[VAL_7]], %[[VAL_6]], %[[VAL_6]], %[[VAL_8]], %[[VAL_9]] : (index, index, index, !fir.field, index, index, !fir.field, !fir.field) -> !fir.slice<1>
93! CHECK:         %[[VAL_10_2:.*]] = arith.cmpi sgt, %[[VAL_10]]#1, %[[VAL_6]] : index
94! CHECK:         %[[VAL_10_3:.*]] = arith.select %[[VAL_10_2]], %[[VAL_10]]#1, %[[VAL_6]] : index
95! CHECK:         %[[VAL_12:.*]] = fir.field_index f1, !fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>
96! CHECK:         %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_6]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt3{f:!fir.array<3x3x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>}>>>, index) -> (index, index, index)
97! CHECK:         %[[VAL_14:.*]] = fir.slice %[[VAL_5]], %[[VAL_13]]#1, %[[VAL_5]] path %[[VAL_7]], %[[VAL_5]], %[[VAL_5]], %[[VAL_12]], %[[VAL_3]] : (index, index, index, !fir.field, index, index, !fir.field, index) -> !fir.slice<1>
98! CHECK:         br ^bb1(%[[VAL_6]], %[[VAL_10_3]] : index, index)
99! CHECK:       ^bb1(%[[VAL_15:.*]]: index, %[[VAL_16:.*]]: index):
100! CHECK:         %[[VAL_17:.*]] = arith.cmpi sgt, %[[VAL_16]], %[[VAL_6]] : index
101! CHECK:         cond_br %[[VAL_17]], ^bb2, ^bb3
102! CHECK:       ^bb2:
103! CHECK:         %[[VAL_18:.*]] = arith.addi %[[VAL_15]], %[[VAL_5]] : index
104! CHECK:         %[[VAL_19:.*]] = fir.array_coor %[[VAL_1]] {{\[}}%[[VAL_14]]] %[[VAL_18]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt3{f:!fir.array<3x3x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>}>>>, !fir.slice<1>, index) -> !fir.ref<i32>
105! CHECK:         %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<i32>
106! CHECK:         %[[VAL_21:.*]] = arith.subi %[[VAL_20]], %[[VAL_4]] : i32
107! CHECK:         %[[VAL_22:.*]] = fir.array_coor %[[VAL_0]] {{\[}}%[[VAL_11]]] %[[VAL_18]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt3{f:!fir.array<3x3x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>}>>>, !fir.slice<1>, index) -> !fir.ref<i32>
108! CHECK:         fir.store %[[VAL_21]] to %[[VAL_22]] : !fir.ref<i32>
109! CHECK:         %[[VAL_23:.*]] = arith.subi %[[VAL_16]], %[[VAL_5]] : index
110! CHECK:         br ^bb1(%[[VAL_18]], %[[VAL_23]] : index, index)
111! CHECK:       ^bb3:
112! CHECK:         %[[VAL_24:.*]] = fir.slice %[[VAL_5]], %[[VAL_13]]#1, %[[VAL_5]] path %[[VAL_7]], %[[VAL_2]], %[[VAL_2]], %[[VAL_12]], %[[VAL_5]] : (index, index, index, !fir.field, index, index, !fir.field, index) -> !fir.slice<1>
113! CHECK:         %[[VAL_13_2:.*]] = arith.cmpi sgt, %[[VAL_13]]#1, %[[VAL_6]] : index
114! CHECK:         %[[VAL_13_3:.*]] = arith.select %[[VAL_13_2]], %[[VAL_13]]#1, %[[VAL_6]] : index
115! CHECK:         %[[VAL_25:.*]] = fir.field_index d, !fir.type<_QMcsTr{n:i32,d:i32}>
116! CHECK:         %[[VAL_26:.*]] = fir.slice %[[VAL_5]], %[[VAL_10]]#1, %[[VAL_5]] path %[[VAL_7]], %[[VAL_6]], %[[VAL_5]], %[[VAL_8]], %[[VAL_25]] : (index, index, index, !fir.field, index, index, !fir.field, !fir.field) -> !fir.slice<1>
117! CHECK:         br ^bb4(%[[VAL_6]], %[[VAL_13_3]] : index, index)
118! CHECK:       ^bb4(%[[VAL_27:.*]]: index, %[[VAL_28:.*]]: index):
119! CHECK:         %[[VAL_29:.*]] = arith.cmpi sgt, %[[VAL_28]], %[[VAL_6]] : index
120! CHECK:         cond_br %[[VAL_29]], ^bb5, ^bb6
121! CHECK:       ^bb5:
122! CHECK:         %[[VAL_30:.*]] = arith.addi %[[VAL_27]], %[[VAL_5]] : index
123! CHECK:         %[[VAL_31:.*]] = fir.array_coor %[[VAL_0]] {{\[}}%[[VAL_26]]] %[[VAL_30]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt3{f:!fir.array<3x3x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>}>>>, !fir.slice<1>, index) -> !fir.ref<i32>
124! CHECK:         %[[VAL_32:.*]] = fir.load %[[VAL_31]] : !fir.ref<i32>
125! CHECK:         %[[VAL_33:.*]] = arith.addi %[[VAL_32]], %[[VAL_4]] : i32
126! CHECK:         %[[VAL_34:.*]] = fir.array_coor %[[VAL_1]] {{\[}}%[[VAL_24]]] %[[VAL_30]] : (!fir.box<!fir.array<?x!fir.type<_QMcsTt3{f:!fir.array<3x3x!fir.type<_QMcsTt2{f1:!fir.array<5xi32>,f2:!fir.type<_QMcsTr{n:i32,d:i32}>}>>}>>>, !fir.slice<1>, index) -> !fir.ref<i32>
127! CHECK:         fir.store %[[VAL_33]] to %[[VAL_34]] : !fir.ref<i32>
128! CHECK:         %[[VAL_35:.*]] = arith.subi %[[VAL_28]], %[[VAL_5]] : index
129! CHECK:         br ^bb4(%[[VAL_30]], %[[VAL_35]] : index, index)
130! CHECK:       ^bb6:
131! CHECK:         return
132! CHECK:       }
133
134  subroutine test3(a3, a4)
135    type(t3) :: a3(:), a4(:)
136    a3%f(1,1)%f2%n = a4%f(2,2)%f1(4) - 4
137    a4%f(3,3)%f1(2) = a3%f(1,2)%f2%d + 4
138  end subroutine test3
139end module cs
140
141! CHECK: func private @_FortranAAll(!fir.box<none>, !fir.ref<i8>, i32, i32) -> i1 attributes {fir.runtime}
142