Skip to content

Commit 3cd3570

Browse files
committed
[Flang] Make handling of %VAL consistent with gfortran
Force an indirect call to the implicit signature in mustCastFuncOpToCopeWithImplicitInterfaceMismatch to make lowering consistent with gfortran.
1 parent 17abebe commit 3cd3570

File tree

2 files changed

+19
-22
lines changed

2 files changed

+19
-22
lines changed

flang/lib/Lower/ConvertCall.cpp

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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:

flang/test/Lower/percent-val-actual-argument.f90

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ program main
66
call sa(%val(a1))
77
! CHECK: %[[A1_ADDR:.*]] = fir.address_of(@_QFEa1) : !fir.ref<!fir.logical<4>>
88
! CHECK: %[[A1_DECL:.*]]:2 = hlfir.declare %[[A1_ADDR]] {uniq_name = "_QFEa1"} : (!fir.ref<!fir.logical<4>>) -> (!fir.ref<!fir.logical<4>>, !fir.ref<!fir.logical<4>>)
9-
! CHECK: fir.call @_QPsa(%[[A1_DECL]]#0) fastmath<contract> : (!fir.ref<!fir.logical<4>>) -> ()
9+
! CHECK: %[[A1_LOADED:.*]] = fir.load %[[A1_DECL]]#0 : !fir.ref<!fir.logical<4>>
10+
! CHECK: %[[SA_ADDR:.*]] = fir.address_of(@_QPsa) : (!fir.ref<!fir.logical<4>>) -> ()
11+
! CHECK: %[[SA_CONVERT:.*]] = fir.convert %[[SA_ADDR]] : ((!fir.ref<!fir.logical<4>>) -> ()) -> ((!fir.logical<4>) -> ())
12+
! CHECK: fir.call %[[SA_CONVERT]](%[[A1_LOADED]]) fastmath<contract> : (!fir.logical<4>) -> ()
1013
! CHECK: func.func @_QPsa(%[[SA_ARG:.*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "x1"}) {
1114
write(6,*) "a1 = ", a1
1215
end program main

0 commit comments

Comments
 (0)