Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 7 additions & 9 deletions flang/lib/Lower/ConvertCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,13 +497,12 @@ Fortran::lower::genCallOpAndResult(

// Special handling for %VAL arguments: internal procedures expect
// reference parameters. When %VAL is used, the argument should be
// passed by value. So we need to create a temporary variable and
// pass its address to avoid a type conversion error.
// passed by value. Pass the originally loaded value.
if (fir::isa_ref_type(snd) && !fir::isa_ref_type(fst.getType()) &&
fir::dyn_cast_ptrEleTy(snd) == fst.getType()) {
mlir::Value temp = builder.createTemporary(loc, fst.getType());
builder.create<fir::StoreOp>(loc, fst, temp);
cast = temp;
auto loadOp = mlir::cast<fir::LoadOp>(fst.getDefiningOp());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. Please could you keep the old code creating the temporary as a fallback. I'm not 100% certain that there will always be a load here. If the cast failed that would be a compiler crash. I'd rather have 2 lines of dead code than a compiler crash for some obscure untested case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's the case because hlfir::loadTrivialScalar always creates fir::LoadOp for scalar trivial variables coming from hlfir.declare.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checking I understand the reasoning here: do you mean it will have always taken this path, and that means it must be a load op?

hlfir::Entity value = hlfir::loadTrivialScalar(loc, builder, actual);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, correct.

mlir::Value originalStorage = loadOp.getMemref();
cast = originalStorage;
} else if (mlir::isa<fir::BoxProcType>(snd) &&
mlir::isa<mlir::FunctionType>(fst.getType())) {
mlir::FunctionType funcTy = mlir::FunctionType::get(context, {}, {});
Expand Down Expand Up @@ -1654,10 +1653,9 @@ void prepareUserCallArguments(
caller.placeInput(arg, value);
else if (fir::isa_ref_type(argTy) &&
fir::dyn_cast_ptrEleTy(argTy) == value.getType()) {
// We're trying to convert value to reference - create temporary
mlir::Value temp = builder.createTemporary(loc, value.getType());
builder.create<fir::StoreOp>(loc, value, temp);
caller.placeInput(arg, temp);
auto loadOp = mlir::cast<fir::LoadOp>(value.getDefiningOp());
mlir::Value originalStorage = loadOp.getMemref();
caller.placeInput(arg, originalStorage);
} else
caller.placeInput(arg, builder.createConvert(loc, argTy, value));

Expand Down