1*460f828fSValentin Clement! RUN: bbc -emit-fir -outline-intrinsics %s -o - | FileCheck %s 2*460f828fSValentin Clement 3*460f828fSValentin Clement! Test statement function lowering 4*460f828fSValentin Clement 5*460f828fSValentin Clement! Simple case 6*460f828fSValentin Clement ! CHECK-LABEL: func @_QPtest_stmt_0( 7*460f828fSValentin Clement ! CHECK-SAME: %{{.*}}: !fir.ref<f32>{{.*}}) -> f32 8*460f828fSValentin Clementreal function test_stmt_0(x) 9*460f828fSValentin Clement real :: x, func, arg 10*460f828fSValentin Clement func(arg) = arg + 0.123456 11*460f828fSValentin Clement 12*460f828fSValentin Clement ! CHECK-DAG: %[[x:.*]] = fir.load %arg0 13*460f828fSValentin Clement ! CHECK-DAG: %[[cst:.*]] = arith.constant 1.234560e-01 14*460f828fSValentin Clement ! CHECK: %[[eval:.*]] = arith.addf %[[x]], %[[cst]] 15*460f828fSValentin Clement ! CHECK: fir.store %[[eval]] to %[[resmem:.*]] : !fir.ref<f32> 16*460f828fSValentin Clement test_stmt_0 = func(x) 17*460f828fSValentin Clement 18*460f828fSValentin Clement ! CHECK: %[[res:.*]] = fir.load %[[resmem]] 19*460f828fSValentin Clement ! CHECK: return %[[res]] 20*460f828fSValentin Clementend function 21*460f828fSValentin Clement 22*460f828fSValentin Clement! Check this is not lowered as a simple macro: e.g. argument is only 23*460f828fSValentin Clement! evaluated once even if it appears in several placed inside the 24*460f828fSValentin Clement! statement function expression 25*460f828fSValentin Clement! CHECK-LABEL: func @_QPtest_stmt_only_eval_arg_once() -> f32 26*460f828fSValentin Clementreal(4) function test_stmt_only_eval_arg_once() 27*460f828fSValentin Clement real(4) :: only_once, x1 28*460f828fSValentin Clement func(x1) = x1 + x1 29*460f828fSValentin Clement ! CHECK: %[[x2:.*]] = fir.alloca f32 {adapt.valuebyref} 30*460f828fSValentin Clement ! CHECK: %[[x1:.*]] = fir.call @_QPonly_once() 31*460f828fSValentin Clement ! Note: using -emit-fir, so the faked pass-by-reference is exposed 32*460f828fSValentin Clement ! CHECK: fir.store %[[x1]] to %[[x2]] 33*460f828fSValentin Clement ! CHECK: addf %{{.*}}, %{{.*}} 34*460f828fSValentin Clement test_stmt_only_eval_arg_once = func(only_once()) 35*460f828fSValentin Clementend function 36*460f828fSValentin Clement 37*460f828fSValentin Clement! Test nested statement function (note that they cannot be recursively 38*460f828fSValentin Clement! nested as per F2018 C1577). 39*460f828fSValentin Clementreal function test_stmt_1(x, a) 40*460f828fSValentin Clement real :: y, a, b, foo 41*460f828fSValentin Clement real :: func1, arg1, func2, arg2 42*460f828fSValentin Clement real :: res1, res2 43*460f828fSValentin Clement func1(arg1) = a + foo(arg1) 44*460f828fSValentin Clement func2(arg2) = func1(arg2) + b 45*460f828fSValentin Clement ! CHECK-DAG: %[[bmem:.*]] = fir.alloca f32 {{{.*}}uniq_name = "{{.*}}Eb"} 46*460f828fSValentin Clement ! CHECK-DAG: %[[res1:.*]] = fir.alloca f32 {{{.*}}uniq_name = "{{.*}}Eres1"} 47*460f828fSValentin Clement ! CHECK-DAG: %[[res2:.*]] = fir.alloca f32 {{{.*}}uniq_name = "{{.*}}Eres2"} 48*460f828fSValentin Clement 49*460f828fSValentin Clement b = 5 50*460f828fSValentin Clement 51*460f828fSValentin Clement ! CHECK-DAG: %[[cst_8:.*]] = arith.constant 8.000000e+00 52*460f828fSValentin Clement ! CHECK-DAG: fir.store %[[cst_8]] to %[[tmp1:.*]] : !fir.ref<f32> 53*460f828fSValentin Clement ! CHECK-DAG: %[[foocall1:.*]] = fir.call @_QPfoo(%[[tmp1]]) 54*460f828fSValentin Clement ! CHECK-DAG: %[[aload1:.*]] = fir.load %arg1 55*460f828fSValentin Clement ! CHECK: %[[add1:.*]] = arith.addf %[[aload1]], %[[foocall1]] 56*460f828fSValentin Clement ! CHECK: fir.store %[[add1]] to %[[res1]] 57*460f828fSValentin Clement res1 = func1(8.) 58*460f828fSValentin Clement 59*460f828fSValentin Clement ! CHECK-DAG: %[[a2:.*]] = fir.load %arg1 60*460f828fSValentin Clement ! CHECK-DAG: %[[foocall2:.*]] = fir.call @_QPfoo(%arg0) 61*460f828fSValentin Clement ! CHECK-DAG: %[[add2:.*]] = arith.addf %[[a2]], %[[foocall2]] 62*460f828fSValentin Clement ! CHECK-DAG: %[[b:.*]] = fir.load %[[bmem]] 63*460f828fSValentin Clement ! CHECK: %[[add3:.*]] = arith.addf %[[add2]], %[[b]] 64*460f828fSValentin Clement ! CHECK: fir.store %[[add3]] to %[[res2]] 65*460f828fSValentin Clement res2 = func2(x) 66*460f828fSValentin Clement 67*460f828fSValentin Clement ! CHECK-DAG: %[[res12:.*]] = fir.load %[[res1]] 68*460f828fSValentin Clement ! CHECK-DAG: %[[res22:.*]] = fir.load %[[res2]] 69*460f828fSValentin Clement ! CHECK: = arith.addf %[[res12]], %[[res22]] : f32 70*460f828fSValentin Clement test_stmt_1 = res1 + res2 71*460f828fSValentin Clement ! CHECK: return %{{.*}} : f32 72*460f828fSValentin Clementend function 73*460f828fSValentin Clement 74*460f828fSValentin Clement 75*460f828fSValentin Clement! Test statement functions with no argument. 76*460f828fSValentin Clement! Test that they are not pre-evaluated. 77*460f828fSValentin Clement! CHECK-LABEL: func @_QPtest_stmt_no_args 78*460f828fSValentin Clementreal function test_stmt_no_args(x, y) 79*460f828fSValentin Clement func() = x + y 80*460f828fSValentin Clement ! CHECK: addf 81*460f828fSValentin Clement a = func() 82*460f828fSValentin Clement ! CHECK: fir.call @_QPfoo_may_modify_xy 83*460f828fSValentin Clement call foo_may_modify_xy(x, y) 84*460f828fSValentin Clement ! CHECK: addf 85*460f828fSValentin Clement ! CHECK: addf 86*460f828fSValentin Clement test_stmt_no_args = func() + a 87*460f828fSValentin Clementend function 88*460f828fSValentin Clement 89*460f828fSValentin Clement! Test statement function with character arguments 90*460f828fSValentin Clement! CHECK-LABEL: @_QPtest_stmt_character 91*460f828fSValentin Clementinteger function test_stmt_character(c, j) 92*460f828fSValentin Clement integer :: i, j, func, argj 93*460f828fSValentin Clement character(10) :: c, argc 94*460f828fSValentin Clement ! CHECK-DAG: %[[unboxed:.*]]:2 = fir.unboxchar %arg0 : 95*460f828fSValentin Clement ! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : 96*460f828fSValentin Clement ! CHECK: %[[c10_cast:.*]] = fir.convert %[[c10]] : (i32) -> index 97*460f828fSValentin Clement ! CHECK: %[[c:.*]] = fir.emboxchar %[[unboxed]]#0, %[[c10_cast]] 98*460f828fSValentin Clement 99*460f828fSValentin Clement func(argc, argj) = len_trim(argc, 4) + argj 100*460f828fSValentin Clement ! CHECK: addi %{{.*}}, %{{.*}} : i 101*460f828fSValentin Clement test_stmt_character = func(c, j) 102*460f828fSValentin Clementend function 103*460f828fSValentin Clement 104*460f828fSValentin Clement! Test statement function with a character actual argument whose 105*460f828fSValentin Clement! length may be different than the dummy length (the dummy length 106*460f828fSValentin Clement! must be used inside the statement function). 107*460f828fSValentin Clement! CHECK-LABEL: @_QPtest_stmt_character_with_different_length( 108*460f828fSValentin Clement! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1> 109*460f828fSValentin Clementinteger function test_stmt_character_with_different_length(c) 110*460f828fSValentin Clement integer :: func, ifoo 111*460f828fSValentin Clement character(10) :: argc 112*460f828fSValentin Clement character(*) :: c 113*460f828fSValentin Clement ! CHECK-DAG: %[[unboxed:.*]]:2 = fir.unboxchar %[[arg0]] : 114*460f828fSValentin Clement ! CHECK-DAG: %[[c10:.*]] = arith.constant 10 : 115*460f828fSValentin Clement ! CHECK: %[[c10_cast:.*]] = fir.convert %[[c10]] : (i32) -> index 116*460f828fSValentin Clement ! CHECK: %[[argc:.*]] = fir.emboxchar %[[unboxed]]#0, %[[c10_cast]] 117*460f828fSValentin Clement ! CHECK: fir.call @_QPifoo(%[[argc]]) : (!fir.boxchar<1>) -> i32 118*460f828fSValentin Clement func(argc) = ifoo(argc) 119*460f828fSValentin Clement test_stmt_character = func(c) 120*460f828fSValentin Clementend function 121*460f828fSValentin Clement 122*460f828fSValentin Clement! CHECK-LABEL: @_QPtest_stmt_character_with_different_length_2( 123*460f828fSValentin Clement! CHECK-SAME: %[[arg0:.*]]: !fir.boxchar<1>{{.*}}, %[[arg1:.*]]: !fir.ref<i32> 124*460f828fSValentin Clementinteger function test_stmt_character_with_different_length_2(c, n) 125*460f828fSValentin Clement integer :: func, ifoo 126*460f828fSValentin Clement character(n) :: argc 127*460f828fSValentin Clement character(*) :: c 128*460f828fSValentin Clement ! CHECK: %[[unboxed:.*]]:2 = fir.unboxchar %[[arg0]] : 129*460f828fSValentin Clement ! CHECK: fir.load %[[arg1]] : !fir.ref<i32> 130*460f828fSValentin Clement ! CHECK: %[[n:.*]] = fir.load %[[arg1]] : !fir.ref<i32> 131*460f828fSValentin Clement ! CHECK: %[[n_is_positive:.*]] = arith.cmpi sgt, %[[n]], %c0{{.*}} : i32 132*460f828fSValentin Clement ! CHECK: %[[len:.*]] = arith.select %[[n_is_positive]], %[[n]], %c0{{.*}} : i32 133*460f828fSValentin Clement ! CHECK: %[[lenCast:.*]] = fir.convert %[[len]] : (i32) -> index 134*460f828fSValentin Clement ! CHECK: %[[argc:.*]] = fir.emboxchar %[[unboxed]]#0, %[[lenCast]] : (!fir.ref<!fir.char<1,?>>, index) -> !fir.boxchar<1> 135*460f828fSValentin Clement ! CHECK: fir.call @_QPifoo(%[[argc]]) : (!fir.boxchar<1>) -> i32 136*460f828fSValentin Clement func(argc) = ifoo(argc) 137*460f828fSValentin Clement test_stmt_character = func(c) 138*460f828fSValentin Clementend function 139*460f828fSValentin Clement 140*460f828fSValentin Clement! issue #247 141*460f828fSValentin Clement! CHECK-LABEL: @_QPbug247 142*460f828fSValentin Clementsubroutine bug247(r) 143*460f828fSValentin Clement I(R) = R 144*460f828fSValentin Clement ! CHECK: fir.call {{.*}}OutputInteger 145*460f828fSValentin Clement PRINT *, I(2.5) 146*460f828fSValentin Clement ! CHECK: fir.call {{.*}}EndIo 147*460f828fSValentin ClementEND subroutine bug247 148