195 lines · plain
1! RUN: bbc -o - -emit-fir -hlfir=false %s | FileCheck %s2 3! Test lowering of operations sub-expression inside elemental call arguments.4! This tests array contexts where an address is needed for each element (for5! the argument), but part of the array sub-expression must be lowered by value6! (for the operation)7 8module test_ops9 interface10 integer elemental function elem_func(i)11 integer, intent(in) :: i12 end function13 integer elemental function elem_func_logical(l)14 logical(8), intent(in) :: l15 end function16 integer elemental function elem_func_logical4(l)17 logical, intent(in) :: l18 end function19 integer elemental function elem_func_real(x)20 real(8), value :: x21 end function22 end interface23 integer :: i(10), j(10), iscalar24 logical(8) :: a(10), b(10)25 real(8) :: x(10), y(10)26 complex(8) :: z1(10), z227 28contains29! CHECK-LABEL: func @_QMtest_opsPcheck_binary_ops() {30subroutine check_binary_ops()31 print *, elem_func(i+j)32! CHECK: %[[VAL_0:.*]] = fir.alloca i3233! CHECK: fir.do_loop34! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i3235! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i3236! CHECK: %[[VAL_27:.*]] = arith.addi %[[VAL_25]], %[[VAL_26]] : i3237! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref<i32>38! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i3239end subroutine40 41! CHECK-LABEL: func @_QMtest_opsPcheck_binary_ops_2() {42subroutine check_binary_ops_2()43 print *, elem_func(i*iscalar)44! CHECK: %[[VAL_0:.*]] = fir.alloca i3245! CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref<i32>46! CHECK: fir.do_loop47! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i3248! CHECK: %[[VAL_27:.*]] = arith.muli %[[VAL_25]], %[[VAL_13]] : i3249! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref<i32>50! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i3251end subroutine52 53! CHECK-LABEL: func @_QMtest_opsPcheck_negate() {54subroutine check_negate()55 print *, elem_func(-i)56! CHECK: %[[VAL_0:.*]] = fir.alloca i3257! CHECK: fir.do_loop58! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i3259! CHECK: %[[VAL_22:.*]] = arith.constant 0 : i3260! CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_22]], %[[VAL_21]] : i3261! CHECK: fir.store %[[VAL_23]] to %[[VAL_0]] : !fir.ref<i32>62! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i3263end subroutine64 65! CHECK-LABEL: func @_QMtest_opsPcheck_convert() {66subroutine check_convert()67 print *, elem_func(int(x))68! CHECK: %[[VAL_0:.*]] = fir.alloca i3269! CHECK: fir.do_loop70! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f6471! CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (f64) -> i3272! CHECK: fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref<i32>73! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i3274end subroutine75 76! CHECK-LABEL: func @_QMtest_opsPcheck_exteremum() {77subroutine check_exteremum()78 print *, elem_func(min(i, j))79! CHECK: %[[VAL_0:.*]] = fir.alloca i3280! CHECK: fir.do_loop81! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i3282! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xi32>, index) -> i3283! CHECK: %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_25]], %[[VAL_26]] : i3284! CHECK: %[[VAL_28:.*]] = arith.select %[[VAL_27]], %[[VAL_25]], %[[VAL_26]] : i3285! CHECK: fir.store %[[VAL_28]] to %[[VAL_0]] : !fir.ref<i32>86! CHECK: fir.call @_QPelem_func(%[[VAL_0]]) {{.*}}: (!fir.ref<i32>) -> i3287end subroutine88 89! CHECK-LABEL: func @_QMtest_opsPcheck_logical_unary_ops() {90subroutine 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 true94! CHECK: fir.do_loop95! 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>) -> i197! CHECK: %[[VAL_24:.*]] = arith.xori %[[VAL_23]], %[[VAL_12]] : i198! 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>>) -> i32101end subroutine102 103! CHECK-LABEL: func @_QMtest_opsPcheck_logical_binary_ops() {104subroutine 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_loop108! 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>) -> i1111! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_26]] : (!fir.logical<8>) -> i1112! CHECK: %[[VAL_29:.*]] = arith.cmpi eq, %[[VAL_27]], %[[VAL_28]] : i1113! 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>>) -> i32116end subroutine117 118! CHECK-LABEL: func @_QMtest_opsPcheck_compare() {119subroutine check_compare()120 print *, elem_func_logical4(x.lt.y)121! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<4>122! CHECK: fir.do_loop123! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64124! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64125! CHECK: %[[VAL_27:.*]] = arith.cmpf olt, %[[VAL_25]], %[[VAL_26]] {{.*}} : f64126! 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>>) -> i32129end subroutine130 131! CHECK-LABEL: func @_QMtest_opsPcheck_pow() {132subroutine check_pow()133 print *, elem_func_real(x**y)134! CHECK: fir.do_loop135! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64136! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64137! CHECK: %[[VAL_27:.*]] = math.powf %[[VAL_25]], %[[VAL_26]] {{.*}}: f64138! CHECK: %[[VAL_28:.*]] = fir.call @_QPelem_func_real(%[[VAL_27]]) {{.*}}: (f64) -> i32139end subroutine140 141! CHECK-LABEL: func @_QMtest_opsPcheck_cmplx_part() {142subroutine check_cmplx_part()143 print *, elem_func_real(AIMAG(z1 + z2))144! CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref<complex<f64>>145! CHECK: fir.do_loop146! CHECK: %[[VAL_23:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xcomplex<f64>>, index) -> complex<f64>147! CHECK: %[[VAL_24:.*]] = fir.addc %[[VAL_23]], %[[VAL_13]] {fastmath = #arith.fastmath<contract>} : complex<f64>148! CHECK: %[[VAL_25:.*]] = fir.extract_value %[[VAL_24]], [1 : index] : (complex<f64>) -> f64149! CHECK: fir.call @_QPelem_func_real(%[[VAL_25]]) {{.*}}: (f64) -> i32150end subroutine151 152! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses() {153subroutine check_parentheses()154 print *, elem_func_real((x))155! CHECK: fir.do_loop156! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64157! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : f64158! CHECK: fir.call @_QPelem_func_real(%[[VAL_22]]) {{.*}}: (f64) -> i32159end subroutine160 161! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses_logical() {162subroutine check_parentheses_logical()163 print *, elem_func_logical((a))164! CHECK: %[[VAL_0:.*]] = fir.alloca !fir.logical<8>165! CHECK: fir.do_loop166! 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>>) -> i32170end subroutine171 172subroutine check_parentheses_derived(a)173 type t174 integer :: i175 end type176 interface177 integer elemental function elem_func_derived(x)178 import :: t179 type(t), intent(in) :: x180 end function181 end interface182 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_loop186! 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: %[[FROM:.*]] = fir.coordinate_of %[[VAL_22]], i : (!fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>) -> !fir.ref<i32>189! CHECK: %[[TO:.*]] = fir.coordinate_of %[[VAL_0]], i : (!fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>) -> !fir.ref<i32>190! CHECK: %[[VAL:.*]] = fir.load %[[FROM]] : !fir.ref<i32>191! CHECK: fir.store %[[VAL]] to %[[TO]] : !fir.ref<i32>192! CHECK: %{{.*}} = fir.call @_QPelem_func_derived(%[[VAL_0]]) {{.*}}: (!fir.ref<!fir.type<_QMtest_opsFcheck_parentheses_derivedTt{i:i32}>>) -> i32193end subroutine194end module195