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
10 integer elemental
function elem_func(i
)
11 integer, intent(in
) :: i
13 integer elemental
function elem_func_logical(l
)
14 logical(8), intent(in
) :: l
16 integer elemental
function elem_func_logical4(l
)
17 logical, intent(in
) :: l
19 integer elemental
function elem_func_real(x
)
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
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
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
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>
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
53 ! CHECK-LABEL: func @_QMtest_opsPcheck_negate() {
54 subroutine check_negate()
55 print *, elem_func(-i
)
56 ! CHECK: %[[VAL_0:.*]] = fir.alloca i32
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
65 ! CHECK-LABEL: func @_QMtest_opsPcheck_convert() {
66 subroutine check_convert()
67 print *, elem_func(int(x
))
68 ! CHECK: %[[VAL_0:.*]] = fir.alloca i32
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
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
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
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
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
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>
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
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>
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
131 ! CHECK-LABEL: func @_QMtest_opsPcheck_pow() {
132 subroutine check_pow()
133 print *, elem_func_real(x
**y
)
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
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>>
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
152 ! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses() {
153 subroutine check_parentheses()
154 print *, elem_func_real((x
))
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
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>
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
172 subroutine check_parentheses_derived(a
)
177 integer elemental
function elem_func_derived(x
)
179 type(t
), intent(in
) :: x
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}>
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