@@ -515,10 +515,19 @@ Fortran::lower::genCallOpAndResult(
515515 // arguments of any type and vice versa.
516516 mlir::Value cast;
517517 auto *context = builder.getContext ();
518- if (mlir::isa<fir::BoxProcType>(snd) &&
519- mlir::isa<mlir::FunctionType>(fst.getType ())) {
520- auto funcTy = mlir::FunctionType::get (context, {}, {});
521- auto boxProcTy = builder.getBoxProcType (funcTy);
518+
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 ())) {
529+ mlir::FunctionType funcTy = mlir::FunctionType::get (context, {}, {});
530+ fir::BoxProcType boxProcTy = builder.getBoxProcType (funcTy);
522531 if (mlir::Value host = argumentHostAssocs (converter, fst)) {
523532 cast = fir::EmboxProcOp::create (builder, loc, boxProcTy,
524533 llvm::ArrayRef<mlir::Value>{fst, host});
@@ -1658,7 +1667,19 @@ void prepareUserCallArguments(
16581667 (*cleanup)();
16591668 break ;
16601669 }
1661- caller.placeInput (arg, builder.createConvert (loc, argTy, value));
1670+ // 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));
1682+
16621683 } break ;
16631684 case PassBy::BaseAddressValueAttribute:
16641685 case PassBy::CharBoxValueAttribute:
0 commit comments