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