@@ -151,6 +151,17 @@ static bool mustCastFuncOpToCopeWithImplicitInterfaceMismatch(
151151 if (actualType != dummyType &&
152152 !fir::ConvertOp::canBeConverted (actualType, dummyType))
153153 return true ;
154+
155+ // For %VAL arguments with implicit interfaces, we need to force an indirect
156+ // call to ensure consistent behavior regardless of whether the procedure
157+ // is defined in the same compilation unit or not. Check for mismatches
158+ // where a by-value call site expects a reference type in the actual
159+ // function definition.
160+ for (auto [actualType, dummyType] :
161+ llvm::zip (callSiteType.getInputs (), funcOpType.getInputs ()))
162+ if (!fir::isa_ref_type (actualType) && fir::isa_ref_type (dummyType) &&
163+ fir::dyn_cast_ptrEleTy (dummyType) == actualType)
164+ return true ;
154165 return false ;
155166}
156167
@@ -516,16 +527,8 @@ Fortran::lower::genCallOpAndResult(
516527 mlir::Value cast;
517528 auto *context = builder.getContext ();
518529
519- // Special handling for %VAL arguments: internal procedures expect
520- // reference parameters. When %VAL is used, the argument should be
521- // passed by value. Pass the originally loaded value.
522- if (fir::isa_ref_type (snd) && !fir::isa_ref_type (fst.getType ()) &&
523- fir::dyn_cast_ptrEleTy (snd) == fst.getType ()) {
524- auto loadOp = mlir::cast<fir::LoadOp>(fst.getDefiningOp ());
525- mlir::Value originalStorage = loadOp.getMemref ();
526- cast = originalStorage;
527- } else if (mlir::isa<fir::BoxProcType>(snd) &&
528- mlir::isa<mlir::FunctionType>(fst.getType ())) {
530+ if (mlir::isa<fir::BoxProcType>(snd) &&
531+ mlir::isa<mlir::FunctionType>(fst.getType ())) {
529532 mlir::FunctionType funcTy = mlir::FunctionType::get (context, {}, {});
530533 fir::BoxProcType boxProcTy = builder.getBoxProcType (funcTy);
531534 if (mlir::Value host = argumentHostAssocs (converter, fst)) {
@@ -1668,17 +1671,8 @@ void prepareUserCallArguments(
16681671 break ;
16691672 }
16701673 // For %VAL arguments, we should pass the value directly without
1671- // conversion to reference types. If argTy is different from value type,
1672- // it might be due to signature mismatch with internal procedures.
1673- if (argTy == value.getType ())
1674- caller.placeInput (arg, value);
1675- else if (fir::isa_ref_type (argTy) &&
1676- fir::dyn_cast_ptrEleTy (argTy) == value.getType ()) {
1677- auto loadOp = mlir::cast<fir::LoadOp>(value.getDefiningOp ());
1678- mlir::Value originalStorage = loadOp.getMemref ();
1679- caller.placeInput (arg, originalStorage);
1680- } else
1681- caller.placeInput (arg, builder.createConvert (loc, argTy, value));
1674+ // conversion to reference types.
1675+ caller.placeInput (arg, builder.createConvert (loc, argTy, value));
16821676
16831677 } break ;
16841678 case PassBy::BaseAddressValueAttribute:
0 commit comments