Break circular dependency between FIR dialect and utilities
[llvm-project.git] / flang / test / Lower / array-elemental-calls-2.f90
blob94e24a9910bc2677dc2a29096b87e02e067fab7e
1 ! RUN: bbc -o - -emit-fir %s | FileCheck %s
3 ! Test lowering of operations sub-expression inside elemental call arguments.
4 ! This tests array contexts where an address is needed for each element (for
5 ! the argument), but part of the array sub-expression must be lowered by value
6 ! (for the operation)
8 module test_ops
9 interface
10 integer elemental function elem_func(i)
11 integer, intent(in) :: i
12 end function
13 integer elemental function elem_func_logical(l)
14 logical(8), intent(in) :: l
15 end function
16 integer elemental function elem_func_logical4(l)
17 logical, intent(in) :: l
18 end function
19 integer elemental function elem_func_real(x)
20 real(8), value :: x
21 end function
22 end interface
23 integer :: i(10), j(10), iscalar
24 logical(8) :: a(10), b(10)
25 real(8) :: x(10), y(10)
26 complex(8) :: z1(10), z2
28 contains
29 ! CHECK-LABEL: func @_QMtest_opsPcheck_binary_ops() {
30 subroutine check_binary_ops()
31 print *, elem_func(i+j)
32 ! CHECK: %[[VAL_0:.*]] = fir.alloca i32
33 ! CHECK: fir.do_loop
34 ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
35 ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
36 ! CHECK: %[[VAL_27:.*]] = arith.addi %[[VAL_25]], %[[VAL_26]] : i32
37 ! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref<i32>
38 ! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i32
39 end subroutine
41 ! CHECK-LABEL: func @_QMtest_opsPcheck_binary_ops_2() {
42 subroutine check_binary_ops_2()
43 print *, elem_func(i*iscalar)
44 ! CHECK: %[[VAL_0:.*]] = fir.alloca i32
45 ! CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref<i32>
46 ! CHECK: fir.do_loop
47 ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
48 ! CHECK: %[[VAL_27:.*]] = arith.muli %[[VAL_25]], %[[VAL_13]] : i32
49 ! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref<i32>
50 ! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i32
51 end subroutine
53 ! CHECK-LABEL: func @_QMtest_opsPcheck_negate() {
54 subroutine check_negate()
55 print *, elem_func(-i)
56 ! CHECK: %[[VAL_0:.*]] = fir.alloca i32
57 ! CHECK: fir.do_loop
58 ! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
59 ! CHECK: %[[VAL_22:.*]] = arith.constant 0 : i32
60 ! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_22]], %[[VAL_21]] : i32
61 ! CHECK: fir.store %[[VAL_23]] to %[[VAL_0]] : !fir.ref<i32>
62 ! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i32
63 end subroutine
65 ! CHECK-LABEL: func @_QMtest_opsPcheck_convert() {
66 subroutine check_convert()
67 print *, elem_func(int(x))
68 ! CHECK: %[[VAL_0:.*]] = fir.alloca i32
69 ! CHECK: fir.do_loop
70 ! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
71 ! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (f64) -> i32
72 ! CHECK: fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref<i32>
73 ! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i32
74 end subroutine
76 ! CHECK-LABEL: func @_QMtest_opsPcheck_exteremum() {
77 subroutine check_exteremum()
78 print *, elem_func(min(i, j))
79 ! CHECK: %[[VAL_0:.*]] = fir.alloca i32
80 ! CHECK: fir.do_loop
81 ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
82 ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
83 ! CHECK: %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_25]], %[[VAL_26]] : i32
84 ! CHECK: %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : i32
85 ! CHECK: fir.store %[[VAL_28]] to %[[VAL_0]] : !fir.ref<i32>
86 ! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i32
87 end subroutine
89 ! CHECK-LABEL: func @_QMtest_opsPcheck_logical_unary_ops() {
90 subroutine check_logical_unary_ops()
91 print *, elem_func_logical(.not.b)
92 ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<8>
93 ! CHECK: %[[VAL_12:.*]] = arith.constant true
94 ! CHECK: fir.do_loop
95 ! CHECK: %[[VAL_22:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8>
96 ! CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (!fir.logical<8>) -> i1
97 ! CHECK: %[[VAL_24:.*]] = arith.xori %[[VAL_23]], %[[VAL_12]] : i1
98 ! CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (i1) -> !fir.logical<8>
99 ! CHECK: fir.store %[[VAL_25]] to %[[VAL_0]] : !fir.ref<!fir.logical<8>>
100 ! CHECK: fir.call @_QPelem_func_logical(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.logical<8>>) -> i32
101 end subroutine
103 ! CHECK-LABEL: func @_QMtest_opsPcheck_logical_binary_ops() {
104 subroutine check_logical_binary_ops()
105 print *, elem_func_logical(a.eqv.b)
106 ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<8>
107 ! CHECK: fir.do_loop
108 ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8>
109 ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8>
110 ! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_25]] : (!fir.logical<8>) -> i1
111 ! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.logical<8>) -> i1
112 ! CHECK: %[[VAL_29:.*]] = arith.cmpi eq, %[[VAL_27]], %[[VAL_28]] : i1
113 ! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i1) -> !fir.logical<8>
114 ! CHECK: fir.store %[[VAL_30]] to %[[VAL_0]] : !fir.ref<!fir.logical<8>>
115 ! CHECK: fir.call @_QPelem_func_logical(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.logical<8>>) -> i32
116 end subroutine
118 ! CHECK-LABEL: func @_QMtest_opsPcheck_compare() {
119 subroutine check_compare()
120 print *, elem_func_logical4(x.lt.y)
121 ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<4>
122 ! CHECK: fir.do_loop
123 ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
124 ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
125 ! CHECK: %[[VAL_27:.*]] = arith.cmpf olt, %[[VAL_25]], %[[VAL_26]] : f64
126 ! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i1) -> !fir.logical<4>
127 ! CHECK: fir.store %[[VAL_28]] to %[[VAL_0]] : !fir.ref<!fir.logical<4>>
128 ! CHECK: fir.call @_QPelem_func_logical4(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.logical<4>>) -> i32
129 end subroutine
131 ! CHECK-LABEL: func @_QMtest_opsPcheck_pow() {
132 subroutine check_pow()
133 print *, elem_func_real(x**y)
134 ! CHECK: fir.do_loop
135 ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
136 ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
137 ! CHECK: %[[VAL_27:.*]] = math.powf %[[VAL_25]], %[[VAL_26]] {{.*}}: f64
138 ! CHECK: %[[VAL_28:.*]] = fir.call @_QPelem_func_real(%[[VAL_27]]) {{.*}}: (f64) -> i32
139 end subroutine
141 ! CHECK-LABEL: func @_QMtest_opsPcheck_cmplx_part() {
142 subroutine check_cmplx_part()
143 print *, elem_func_real(AIMAG(z1 + z2))
144 ! CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref<!fir.complex<8>>
145 ! CHECK: fir.do_loop
146 ! CHECK: %[[VAL_23:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.complex<8>>, index) -> !fir.complex<8>
147 ! CHECK: %[[VAL_24:.*]] = fir.addc %[[VAL_23]], %[[VAL_13]] : !fir.complex<8>
148 ! CHECK: %[[VAL_25:.*]] = fir.extract_value %[[VAL_24]], [1 : index] : (!fir.complex<8>) -> f64
149 ! CHECK: fir.call @_QPelem_func_real(%[[VAL_25]]) {{.*}}: (f64) -> i32
150 end subroutine
152 ! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses() {
153 subroutine check_parentheses()
154 print *, elem_func_real((x))
155 ! CHECK: fir.do_loop
156 ! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
157 ! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : f64
158 ! CHECK: fir.call @_QPelem_func_real(%[[VAL_22]]) {{.*}}: (f64) -> i32
159 end subroutine
161 ! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses_logical() {
162 subroutine check_parentheses_logical()
163 print *, elem_func_logical((a))
164 ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<8>
165 ! CHECK: fir.do_loop
166 ! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8>
167 ! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : !fir.logical<8>
168 ! CHECK: fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref<!fir.logical<8>>
169 ! CHECK: fir.call @_QPelem_func_logical(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.logical<8>>) -> i32
170 end subroutine
172 subroutine check_parentheses_derived(a)
173 type t
174 integer :: i
175 end type
176 interface
177 integer elemental function elem_func_derived(x)
178 import :: t
179 type(t), intent(in) :: x
180 end function
181 end interface
182 type(t), pointer :: a(:)
183 print *, elem_func_derived((a))
184 ! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>
185 ! CHECK: fir.do_loop
186 ! CHECK: %[[VAL_21:.*]] = fir.array_access %{{.}}, %{{.*}}
187 ! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : !fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>
188 ! CHECK: %[[FIELD:.*]] = fir.field_index i, !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>
189 ! CHECK: %[[FROM:.*]] = fir.coordinate_of %[[VAL_22]], %[[FIELD]] : (!fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>, !fir.field) -> !fir.ref<i32>
190 ! CHECK: %[[FIELD2:.*]] = fir.field_index i, !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>
191 ! CHECK: %[[TO:.*]] = fir.coordinate_of %[[VAL_0]], %[[FIELD2]] : (!fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>, !fir.field) -> !fir.ref<i32>
192 ! CHECK: %[[VAL:.*]] = fir.load %[[FROM]] : !fir.ref<i32>
193 ! CHECK: fir.store %[[VAL]] to %[[TO]] : !fir.ref<i32>
194 ! CHECK: %{{.*}} = fir.call @_QPelem_func_derived(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>) -> i32
195 end subroutine
196 end module