xref: /llvm-project/flang/test/Lower/array-elemental-calls-2.f90 (revision c4204c0b29a6721267b1bcbaeedd7b1118e42396)
1f35f863aSjeanPerier! RUN: bbc -o - -emit-fir -hlfir=false %s | FileCheck %s
27b917fd2SValentin Clement
37b917fd2SValentin Clement! Test lowering of operations sub-expression inside elemental call arguments.
47b917fd2SValentin Clement! This tests array contexts where an address is needed for each element (for
57b917fd2SValentin Clement! the argument), but part of the array sub-expression must be lowered by value
67b917fd2SValentin Clement! (for the operation)
77b917fd2SValentin Clement
87b917fd2SValentin Clementmodule test_ops
97b917fd2SValentin Clement  interface
107b917fd2SValentin Clement    integer elemental function elem_func(i)
117b917fd2SValentin Clement      integer, intent(in) :: i
127b917fd2SValentin Clement    end function
137b917fd2SValentin Clement    integer elemental function elem_func_logical(l)
147b917fd2SValentin Clement      logical(8), intent(in) :: l
157b917fd2SValentin Clement    end function
167b917fd2SValentin Clement    integer elemental function elem_func_logical4(l)
177b917fd2SValentin Clement      logical, intent(in) :: l
187b917fd2SValentin Clement    end function
197b917fd2SValentin Clement    integer elemental function elem_func_real(x)
207b917fd2SValentin Clement      real(8), value :: x
217b917fd2SValentin Clement    end function
227b917fd2SValentin Clement  end interface
237b917fd2SValentin Clement  integer :: i(10), j(10), iscalar
247b917fd2SValentin Clement  logical(8) :: a(10), b(10)
257b917fd2SValentin Clement  real(8) :: x(10), y(10)
267b917fd2SValentin Clement  complex(8) :: z1(10), z2
277b917fd2SValentin Clement
287b917fd2SValentin Clementcontains
297b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_binary_ops() {
307b917fd2SValentin Clementsubroutine check_binary_ops()
317b917fd2SValentin Clement  print *,  elem_func(i+j)
327b917fd2SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.alloca i32
337b917fd2SValentin Clement! CHECK:  fir.do_loop
347b917fd2SValentin Clement! CHECK:  %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
357b917fd2SValentin Clement! CHECK:  %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
367b917fd2SValentin Clement! CHECK:  %[[VAL_27:.*]] = arith.addi %[[VAL_25]], %[[VAL_26]] : i32
377b917fd2SValentin Clement! CHECK:  fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref<i32>
384cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i32
397b917fd2SValentin Clementend subroutine
407b917fd2SValentin Clement
417b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_binary_ops_2() {
427b917fd2SValentin Clementsubroutine check_binary_ops_2()
437b917fd2SValentin Clement  print *,  elem_func(i*iscalar)
447b917fd2SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.alloca i32
457b917fd2SValentin Clement! CHECK:  %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref<i32>
467b917fd2SValentin Clement! CHECK:  fir.do_loop
477b917fd2SValentin Clement! CHECK:  %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
487b917fd2SValentin Clement! CHECK:  %[[VAL_27:.*]] = arith.muli %[[VAL_25]], %[[VAL_13]] : i32
497b917fd2SValentin Clement! CHECK:  fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref<i32>
504cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i32
517b917fd2SValentin Clementend subroutine
527b917fd2SValentin Clement
537b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_negate() {
547b917fd2SValentin Clementsubroutine check_negate()
557b917fd2SValentin Clement  print *,  elem_func(-i)
567b917fd2SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.alloca i32
577b917fd2SValentin Clement! CHECK:  fir.do_loop
587b917fd2SValentin Clement! CHECK:  %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
597b917fd2SValentin Clement! CHECK:  %[[VAL_22:.*]] = arith.constant 0 : i32
607b917fd2SValentin Clement! CHECK:  %[[VAL_23:.*]] = arith.subi %[[VAL_22]], %[[VAL_21]] : i32
617b917fd2SValentin Clement! CHECK:  fir.store %[[VAL_23]] to %[[VAL_0]] : !fir.ref<i32>
624cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i32
637b917fd2SValentin Clementend subroutine
647b917fd2SValentin Clement
657b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_convert() {
667b917fd2SValentin Clementsubroutine check_convert()
677b917fd2SValentin Clement  print *,  elem_func(int(x))
687b917fd2SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.alloca i32
697b917fd2SValentin Clement! CHECK:  fir.do_loop
707b917fd2SValentin Clement! CHECK:  %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
717b917fd2SValentin Clement! CHECK:  %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (f64) -> i32
727b917fd2SValentin Clement! CHECK:  fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref<i32>
734cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i32
747b917fd2SValentin Clementend subroutine
757b917fd2SValentin Clement
767b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_exteremum() {
777b917fd2SValentin Clementsubroutine check_exteremum()
787b917fd2SValentin Clement  print *,  elem_func(min(i, j))
797b917fd2SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.alloca i32
807b917fd2SValentin Clement! CHECK:  fir.do_loop
817b917fd2SValentin Clement! CHECK:  %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
827b917fd2SValentin Clement! CHECK:  %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i32
837b917fd2SValentin Clement! CHECK:  %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_25]], %[[VAL_26]] : i32
847b917fd2SValentin Clement! CHECK:  %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : i32
857b917fd2SValentin Clement! CHECK:  fir.store %[[VAL_28]] to %[[VAL_0]] : !fir.ref<i32>
864cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i32
877b917fd2SValentin Clementend subroutine
887b917fd2SValentin Clement
897b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_logical_unary_ops() {
907b917fd2SValentin Clementsubroutine check_logical_unary_ops()
917b917fd2SValentin Clement  print *,  elem_func_logical(.not.b)
927b917fd2SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.alloca !fir.logical<8>
937b917fd2SValentin Clement! CHECK:  %[[VAL_12:.*]] = arith.constant true
947b917fd2SValentin Clement! CHECK:  fir.do_loop
957b917fd2SValentin Clement! CHECK:  %[[VAL_22:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8>
967b917fd2SValentin Clement! CHECK:  %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (!fir.logical<8>) -> i1
977b917fd2SValentin Clement! CHECK:  %[[VAL_24:.*]] = arith.xori %[[VAL_23]], %[[VAL_12]] : i1
987b917fd2SValentin Clement! CHECK:  %[[VAL_25:.*]] = fir.convert %[[VAL_24]] : (i1) -> !fir.logical<8>
997b917fd2SValentin Clement! CHECK:  fir.store %[[VAL_25]] to %[[VAL_0]] : !fir.ref<!fir.logical<8>>
1004cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func_logical(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.logical<8>>) -> i32
1017b917fd2SValentin Clementend subroutine
1027b917fd2SValentin Clement
1037b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_logical_binary_ops() {
1047b917fd2SValentin Clementsubroutine check_logical_binary_ops()
1057b917fd2SValentin Clement  print *,  elem_func_logical(a.eqv.b)
1067b917fd2SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.alloca !fir.logical<8>
1077b917fd2SValentin Clement! CHECK:  fir.do_loop
1087b917fd2SValentin Clement! CHECK:  %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8>
1097b917fd2SValentin Clement! CHECK:  %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8>
1107b917fd2SValentin Clement! CHECK:  %[[VAL_27:.*]] = fir.convert %[[VAL_25]] : (!fir.logical<8>) -> i1
1117b917fd2SValentin Clement! CHECK:  %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.logical<8>) -> i1
1127b917fd2SValentin Clement! CHECK:  %[[VAL_29:.*]] = arith.cmpi eq, %[[VAL_27]], %[[VAL_28]] : i1
1137b917fd2SValentin Clement! CHECK:  %[[VAL_30:.*]] = fir.convert %[[VAL_29]] : (i1) -> !fir.logical<8>
1147b917fd2SValentin Clement! CHECK:  fir.store %[[VAL_30]] to %[[VAL_0]] : !fir.ref<!fir.logical<8>>
1154cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func_logical(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.logical<8>>) -> i32
1167b917fd2SValentin Clementend subroutine
1177b917fd2SValentin Clement
1187b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_compare() {
1197b917fd2SValentin Clementsubroutine check_compare()
1207b917fd2SValentin Clement  print *,  elem_func_logical4(x.lt.y)
1217b917fd2SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.alloca !fir.logical<4>
1227b917fd2SValentin Clement! CHECK:  fir.do_loop
1237b917fd2SValentin Clement! CHECK:  %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
1247b917fd2SValentin Clement! CHECK:  %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
125fcd06d77STom Eccles! CHECK:  %[[VAL_27:.*]] = arith.cmpf olt, %[[VAL_25]], %[[VAL_26]] {{.*}} : f64
1267b917fd2SValentin Clement! CHECK:  %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i1) -> !fir.logical<4>
1277b917fd2SValentin Clement! CHECK:  fir.store %[[VAL_28]] to %[[VAL_0]] : !fir.ref<!fir.logical<4>>
1284cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func_logical4(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.logical<4>>) -> i32
1297b917fd2SValentin Clementend subroutine
1307b917fd2SValentin Clement
1317b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_pow() {
1327b917fd2SValentin Clementsubroutine check_pow()
1337b917fd2SValentin Clement  print *,  elem_func_real(x**y)
1347b917fd2SValentin Clement! CHECK:  fir.do_loop
1357b917fd2SValentin Clement! CHECK:  %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
1367b917fd2SValentin Clement! CHECK:  %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
1374cc9437aSTom Eccles! CHECK:  %[[VAL_27:.*]] = math.powf %[[VAL_25]], %[[VAL_26]] {{.*}}: f64
1384cc9437aSTom Eccles! CHECK:  %[[VAL_28:.*]] = fir.call @_QPelem_func_real(%[[VAL_27]]) {{.*}}: (f64) -> i32
1397b917fd2SValentin Clementend subroutine
1407b917fd2SValentin Clement
1417b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_cmplx_part() {
1427b917fd2SValentin Clementsubroutine check_cmplx_part()
1437b917fd2SValentin Clement  print *,  elem_func_real(AIMAG(z1 + z2))
144*c4204c0bSjeanPerier! CHECK:  %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref<complex<f64>>
1457b917fd2SValentin Clement! CHECK:  fir.do_loop
146*c4204c0bSjeanPerier! CHECK:  %[[VAL_23:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xcomplex<f64>>, index) -> complex<f64>
147*c4204c0bSjeanPerier! CHECK:  %[[VAL_24:.*]] = fir.addc %[[VAL_23]], %[[VAL_13]] {fastmath = #arith.fastmath<contract>} : complex<f64>
148*c4204c0bSjeanPerier! CHECK:  %[[VAL_25:.*]] = fir.extract_value %[[VAL_24]], [1 : index] : (complex<f64>) -> f64
1494cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func_real(%[[VAL_25]]) {{.*}}: (f64) -> i32
1507b917fd2SValentin Clementend subroutine
1517b917fd2SValentin Clement
1527b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses() {
1537b917fd2SValentin Clementsubroutine check_parentheses()
1547b917fd2SValentin Clement  print *,  elem_func_real((x))
1557b917fd2SValentin Clement! CHECK:  fir.do_loop
1567b917fd2SValentin Clement! CHECK:  %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64
1577b917fd2SValentin Clement! CHECK:  %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : f64
1584cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func_real(%[[VAL_22]]) {{.*}}: (f64) -> i32
1597b917fd2SValentin Clementend subroutine
1607b917fd2SValentin Clement
1617b917fd2SValentin Clement! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses_logical() {
1627b917fd2SValentin Clementsubroutine check_parentheses_logical()
1637b917fd2SValentin Clement  print *,  elem_func_logical((a))
1647b917fd2SValentin Clement! CHECK:  %[[VAL_0:.*]] = fir.alloca !fir.logical<8>
1657b917fd2SValentin Clement! CHECK:  fir.do_loop
1667b917fd2SValentin Clement! CHECK:  %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.logical<8>>, index) -> !fir.logical<8>
1677b917fd2SValentin Clement! CHECK:  %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : !fir.logical<8>
1687b917fd2SValentin Clement! CHECK:  fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref<!fir.logical<8>>
1694cc9437aSTom Eccles! CHECK:  fir.call @_QPelem_func_logical(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.logical<8>>) -> i32
1707b917fd2SValentin Clementend subroutine
1717b917fd2SValentin Clement
1727b917fd2SValentin Clementsubroutine check_parentheses_derived(a)
1737b917fd2SValentin Clement  type t
1747b917fd2SValentin Clement    integer :: i
1757b917fd2SValentin Clement  end type
1767b917fd2SValentin Clement  interface
1777b917fd2SValentin Clement    integer elemental function elem_func_derived(x)
1787b917fd2SValentin Clement      import :: t
1797b917fd2SValentin Clement      type(t), intent(in) :: x
1807b917fd2SValentin Clement    end function
1817b917fd2SValentin Clement  end interface
1827b917fd2SValentin Clement  type(t), pointer :: a(:)
1837b917fd2SValentin Clement  print *,  elem_func_derived((a))
1847b917fd2SValentin Clement! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>
1857b917fd2SValentin Clement! CHECK: fir.do_loop
1867b917fd2SValentin Clement! CHECK: %[[VAL_21:.*]] = fir.array_access %{{.}}, %{{.*}}
1877b917fd2SValentin Clement! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : !fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>
1887b917fd2SValentin Clement! CHECK: %[[FIELD:.*]] = fir.field_index i, !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>
1897b917fd2SValentin Clement! CHECK: %[[FROM:.*]] = fir.coordinate_of %[[VAL_22]], %[[FIELD]] : (!fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>, !fir.field) -> !fir.ref<i32>
19068cfb6a8SEric Schweitz! CHECK: %[[FIELD2:.*]] = fir.field_index i, !fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>
19168cfb6a8SEric Schweitz! CHECK: %[[TO:.*]] = fir.coordinate_of %[[VAL_0]], %[[FIELD2]] : (!fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>, !fir.field) -> !fir.ref<i32>
1927b917fd2SValentin Clement! CHECK: %[[VAL:.*]] = fir.load %[[FROM]] : !fir.ref<i32>
1937b917fd2SValentin Clement! CHECK: fir.store %[[VAL]] to %[[TO]] : !fir.ref<i32>
1944cc9437aSTom Eccles! CHECK: %{{.*}} = fir.call @_QPelem_func_derived(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>) -> i32
1957b917fd2SValentin Clementend subroutine
1967b917fd2SValentin Clementend module
197