Index: flang/lib/Lower/CallInterface.cpp =================================================================== --- flang/lib/Lower/CallInterface.cpp +++ flang/lib/Lower/CallInterface.cpp @@ -921,12 +921,18 @@ : PassEntityBy::BoxChar, entity, characteristics); } else { - // Pass as fir.ref unless it's by VALUE and BIND(C) + // Pass as fir.ref unless it's by VALUE and BIND(C). Also pass-by-value + // for numerical/logical scalar without OPTIONAL so that the behavior is + // consistent with gfortran/nvfortran. + // TODO: pass-by-value for derived type is not supported yet mlir::Type passType = fir::ReferenceType::get(type); PassEntityBy passBy = PassEntityBy::BaseAddress; Property prop = Property::BaseAddress; if (isValueAttr) { - if (isBindC) { + if (isBindC || (!type.isa() && + !obj.attrs.test(Attrs::Optional) && + dynamicType.category() != + Fortran::common::TypeCategory::Derived)) { passBy = PassEntityBy::Value; prop = Property::Value; if (type.isa()) Index: flang/test/Lower/array-elemental-calls-2.f90 =================================================================== --- flang/test/Lower/array-elemental-calls-2.f90 +++ flang/test/Lower/array-elemental-calls-2.f90 @@ -131,37 +131,31 @@ ! CHECK-LABEL: func @_QMtest_opsPcheck_pow() { subroutine check_pow() print *, elem_func_real(x**y) -! CHECK: %[[VAL_0:.*]] = fir.alloca f64 ! CHECK: fir.do_loop ! CHECK: %[[VAL_25:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 ! CHECK: %[[VAL_26:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 ! CHECK: %[[VAL_27:.*]] = math.powf %[[VAL_25]], %[[VAL_26]] : f64 -! CHECK: fir.store %[[VAL_27]] to %[[VAL_0]] : !fir.ref -! CHECK: %[[VAL_28:.*]] = fir.call @_QPelem_func_real(%[[VAL_0]]) : (!fir.ref) -> i32 +! CHECK: %[[VAL_28:.*]] = fir.call @_QPelem_func_real(%[[VAL_27]]) : (f64) -> i32 end subroutine ! CHECK-LABEL: func @_QMtest_opsPcheck_cmplx_part() { subroutine check_cmplx_part() print *, elem_func_real(AIMAG(z1 + z2)) -! CHECK: %[[VAL_0:.*]] = fir.alloca f64 ! CHECK: %[[VAL_13:.*]] = fir.load %{{.*}} : !fir.ref> ! CHECK: fir.do_loop ! CHECK: %[[VAL_23:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10x!fir.complex<8>>, index) -> !fir.complex<8> ! CHECK: %[[VAL_24:.*]] = fir.addc %[[VAL_23]], %[[VAL_13]] : !fir.complex<8> ! CHECK: %[[VAL_25:.*]] = fir.extract_value %[[VAL_24]], [1 : index] : (!fir.complex<8>) -> f64 -! CHECK: fir.store %[[VAL_25]] to %[[VAL_0]] : !fir.ref -! CHECK: fir.call @_QPelem_func_real(%[[VAL_0]]) : (!fir.ref) -> i32 +! CHECK: fir.call @_QPelem_func_real(%[[VAL_25]]) : (f64) -> i32 end subroutine ! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses() { subroutine check_parentheses() print *, elem_func_real((x)) -! CHECK: %[[VAL_0:.*]] = fir.alloca f64 ! CHECK: fir.do_loop ! CHECK: %[[VAL_21:.*]] = fir.array_fetch %{{.*}}, %{{.*}} : (!fir.array<10xf64>, index) -> f64 ! CHECK: %[[VAL_22:.*]] = fir.no_reassoc %[[VAL_21]] : f64 -! CHECK: fir.store %[[VAL_22]] to %[[VAL_0]] : !fir.ref -! CHECK: fir.call @_QPelem_func_real(%[[VAL_0]]) : (!fir.ref) -> i32 +! CHECK: fir.call @_QPelem_func_real(%[[VAL_22]]) : (f64) -> i32 end subroutine ! CHECK-LABEL: func @_QMtest_opsPcheck_parentheses_logical() { Index: flang/test/Lower/array-elemental-calls.f90 =================================================================== --- flang/test/Lower/array-elemental-calls.f90 +++ flang/test/Lower/array-elemental-calls.f90 @@ -34,16 +34,12 @@ ! CHECK-SAME: %[[arg0:.*]]: !fir.ref>{{.*}}, %[[arg1:.*]]: !fir.ref>{{.*}}) { subroutine test_elem_by_valueref(i, j) integer :: i(100), j(100) - ! CHECK-DAG: %[[tmpA:.*]] = fir.alloca i32 {adapt.valuebyref} - ! CHECK-DAG: %[[tmpB:.*]] = fir.alloca f32 {adapt.valuebyref} ! CHECK: %[[jload:.*]] = fir.array_load %[[arg1]] ! CHECK: %[[cst:.*]] = arith.constant 4.200000e+01 : f32 - ! CHECK: fir.store %[[cst]] to %[[tmpB]] : !fir.ref ! CHECK: fir.do_loop ! CHECK: %[[j:.*]] = fir.array_fetch %[[jload]], %{{.*}} : (!fir.array<100xi32>, index) -> i32 - ! CHECK: fir.store %[[j]] to %[[tmpA]] : !fir.ref - ! CHECK: fir.call @_QMscalar_in_elemPelem_by_valueref(%[[tmpA]], %[[tmpB]]) : (!fir.ref, !fir.ref) -> i32 + ! CHECK: fir.call @_QMscalar_in_elemPelem_by_valueref(%[[j]], %[[cst]]) : (i32, f32) -> i32 ! CHECK: fir.result i = elem_by_valueref(j, 42.) end Index: flang/test/Lower/array-elemental-subroutines.f90 =================================================================== --- flang/test/Lower/array-elemental-subroutines.f90 +++ flang/test/Lower/array-elemental-subroutines.f90 @@ -3,7 +3,6 @@ ! CHECK-LABEL: func @_QPtest_elem_sub( ! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>{{.*}}, %[[VAL_1:.*]]: !fir.box>>{{.*}}, %[[VAL_2:.*]]: !fir.ref{{.*}}, %[[VAL_3:.*]]: !fir.ref>{{.*}}) { -! CHECK: %[[VAL_4:.*]] = fir.alloca !fir.complex<4> {adapt.valuebyref} ! CHECK: %[[VAL_5:.*]] = arith.constant 0 : index ! CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) ! CHECK: %[[VAL_7:.*]] = arith.constant 10 : i64 @@ -14,7 +13,6 @@ ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i64) -> index ! CHECK: %[[VAL_13:.*]] = fir.slice %[[VAL_8]], %[[VAL_12]], %[[VAL_10]] : (index, index, index) -> !fir.slice<1> ! CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_3]] : !fir.ref> -! CHECK: fir.store %[[VAL_14]] to %[[VAL_4]] : !fir.ref> ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : index ! CHECK: %[[VAL_16:.*]] = arith.constant 0 : index ! CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_6]]#1, %[[VAL_15]] : index @@ -27,7 +25,7 @@ ! CHECK: %[[VAL_24:.*]] = fir.array_coor %[[VAL_1]] {{\[}}%[[VAL_13]]] %[[VAL_23]] : (!fir.box>>, !fir.slice<1>, index) -> !fir.ref> ! CHECK: %[[VAL_25:.*]] = fir.box_elesize %[[VAL_1]] : (!fir.box>>) -> index ! CHECK: %[[VAL_26:.*]] = fir.emboxchar %[[VAL_24]], %[[VAL_25]] : (!fir.ref>, index) -> !fir.boxchar<1> -! CHECK: fir.call @_QPfoo(%[[VAL_21]], %[[VAL_26]], %[[VAL_2]], %[[VAL_4]]) : (!fir.ref, !fir.boxchar<1>, !fir.ref, !fir.ref>) -> () +! CHECK: fir.call @_QPfoo(%[[VAL_21]], %[[VAL_26]], %[[VAL_2]], %[[VAL_14]]) : (!fir.ref, !fir.boxchar<1>, !fir.ref, !fir.complex<4>) -> () ! CHECK: } ! CHECK: return ! CHECK: } Index: flang/test/Lower/array-expression.f90 =================================================================== --- flang/test/Lower/array-expression.f90 +++ flang/test/Lower/array-expression.f90 @@ -482,7 +482,6 @@ ! CHECK-LABEL: func @_QPtest16( ! CHECK-SAME: %[[a:.*]]: !fir.ref>{{.*}}, %[[b:.*]]: !fir.ref>{{.*}}) subroutine test16(a,b) - ! CHECK: %[[tmp:.*]] = fir.alloca f32 {adapt.valuebyref ! CHECK-DAG: %[[aarr:.*]] = fir.array_load %[[a]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> ! CHECK-DAG: %[[barr:.*]] = fir.array_load %[[b]](%{{.*}}) : (!fir.ref>, !fir.shape<1>) -> !fir.array<100xf32> interface @@ -493,8 +492,7 @@ real :: a(100), b(100) ! CHECK: %[[loop:.*]] = fir.do_loop %[[i:.*]] = %{{.*}} to %{{.*}} step %{{.*}} iter_args(%[[bth:.*]] = %[[barr]]) -> (!fir.array<100xf32>) { ! CHECK: %[[val:.*]] = fir.array_fetch %[[aarr]], %[[i]] : (!fir.array<100xf32>, index) -> f32 - ! CHECK: fir.store %[[val]] to %[[tmp]] - ! CHECK: %[[fres:.*]] = fir.call @_QPf2(%[[tmp]]) : (!fir.ref) -> f32 + ! CHECK: %[[fres:.*]] = fir.call @_QPf2(%[[val]]) : (f32) -> f32 ! CHECK: %[[res:.*]] = fir.array_update %[[bth]], %[[fres]], %[[i]] : (!fir.array<100xf32>, f32, index) -> !fir.array<100xf32> ! CHECK: fir.result %[[res]] : !fir.array<100xf32> ! CHECK: fir.array_merge_store %[[barr]], %[[loop]] to %[[b]] Index: flang/test/Lower/call-by-value-attr.f90 =================================================================== --- flang/test/Lower/call-by-value-attr.f90 +++ flang/test/Lower/call-by-value-attr.f90 @@ -16,7 +16,6 @@ integer, dimension(15) :: b v = 17 call subri(v) - !CHECK: %[[COPY:.*]] = fir.alloca i32 !CHECK: %[[ARRAY_A:.*]] = fir.address_of(@_QFEa) !CHECK: %[[CONST_10_1:.*]] = arith.constant 10 : index !CHECK: %[[ARRAY_B:.*]] = fir.address_of(@_QFEb) @@ -25,8 +24,7 @@ !CHECK: %[[CONST:.*]] = arith.constant 17 !CHECK: fir.store %[[CONST]] to %[[VALUE]] !CHECK: %[[LOAD:.*]] = fir.load %[[VALUE]] - !CHECK: fir.store %[[LOAD]] to %[[COPY]] - !CHECK: fir.call @_QPsubri(%[[COPY]]) : {{.*}} + !CHECK: fir.call @_QPsubri(%[[LOAD]]) : {{.*}} a = (/ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 /) !CHECK: %[[SHAPE_1:.*]] = fir.shape %[[CONST_10_1]] !CHECK: %[[ARRAY_LOAD_1:.*]] = fir.array_load %[[ARRAY_A]](%[[SHAPE_1]]) : {{.*}} @@ -87,6 +85,18 @@ call subra(b(5:15)) end program call_by_value_attr +! CHECK-LABEL: func.func @_QPsubri( +! CHECK-SAME: %[[VAL_0:.*]]: i32 {fir.bindc_name = "val"}) { +! CHECK: %[[VAL_1:.*]] = fir.alloca i32 +! CHECK: fir.store %[[VAL_0]] to %[[VAL_1]] : !fir.ref +! CHECK: fir.call @_QPtest_numeric_scalar_value(%[[VAL_1]]) : (!fir.ref) -> () +! CHECK: return +! CHECK: } + +subroutine subri(val) + integer, value :: val + call test_numeric_scalar_value(val) +end subroutine subri ! CHECK-LABEL: func @_QPtest_litteral_copies_1 subroutine test_litteral_copies_1