Index: flang/lib/Lower/CallInterface.cpp =================================================================== --- flang/lib/Lower/CallInterface.cpp +++ flang/lib/Lower/CallInterface.cpp @@ -639,7 +639,7 @@ handleImplicitDummy(&argCharacteristics, dummy, entity); else handleExplicitDummy(&argCharacteristics, dummy, entity, - isBindC); + isBindC, procedure.IsElemental()); }, [&](const Fortran::evaluate::characteristics::DummyProcedure &dummy) { @@ -849,7 +849,7 @@ void handleExplicitDummy( const DummyCharacteristics *characteristics, const Fortran::evaluate::characteristics::DummyDataObject &obj, - const FortranEntity &entity, bool isBindC) { + const FortranEntity &entity, bool isBindC, bool isElemental) { using Attrs = Fortran::evaluate::characteristics::DummyDataObject::Attr; bool isValueAttr = false; @@ -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 ELEMENTAL/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() && !isElemental && + !obj.attrs.test(Attrs::Optional) && + dynamicType.category() != + Fortran::common::TypeCategory::Derived)) { passBy = PassEntityBy::Value; prop = Property::Value; if (type.isa()) 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