mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:58:11 +08:00
[Flang] Make handling of %VAL consistent with gfortran (#157873)
Prevent fir.convert operation from being generated between logical and pointer types.
This commit is contained in:
@@ -516,16 +516,8 @@ Fortran::lower::genCallOpAndResult(
|
||||
mlir::Value cast;
|
||||
auto *context = builder.getContext();
|
||||
|
||||
// Special handling for %VAL arguments: internal procedures expect
|
||||
// reference parameters. When %VAL is used, the argument should be
|
||||
// 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()) {
|
||||
auto loadOp = mlir::cast<fir::LoadOp>(fst.getDefiningOp());
|
||||
mlir::Value originalStorage = loadOp.getMemref();
|
||||
cast = originalStorage;
|
||||
} else if (mlir::isa<fir::BoxProcType>(snd) &&
|
||||
mlir::isa<mlir::FunctionType>(fst.getType())) {
|
||||
if (mlir::isa<fir::BoxProcType>(snd) &&
|
||||
mlir::isa<mlir::FunctionType>(fst.getType())) {
|
||||
mlir::FunctionType funcTy = mlir::FunctionType::get(context, {}, {});
|
||||
fir::BoxProcType boxProcTy = builder.getBoxProcType(funcTy);
|
||||
if (mlir::Value host = argumentHostAssocs(converter, fst)) {
|
||||
@@ -1677,17 +1669,8 @@ void prepareUserCallArguments(
|
||||
break;
|
||||
}
|
||||
// For %VAL arguments, we should pass the value directly without
|
||||
// conversion to reference types. If argTy is different from value type,
|
||||
// it might be due to signature mismatch with internal procedures.
|
||||
if (argTy == value.getType())
|
||||
caller.placeInput(arg, value);
|
||||
else if (fir::isa_ref_type(argTy) &&
|
||||
fir::dyn_cast_ptrEleTy(argTy) == value.getType()) {
|
||||
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));
|
||||
// conversion to reference types.
|
||||
caller.placeInput(arg, builder.createConvert(loc, argTy, value));
|
||||
|
||||
} break;
|
||||
case PassBy::BaseAddressValueAttribute:
|
||||
|
||||
@@ -1521,8 +1521,8 @@ bool fir::ConvertOp::canBeConverted(mlir::Type inType, mlir::Type outType) {
|
||||
(isInteger(inType) && isFloatCompatible(outType)) ||
|
||||
(isFloatCompatible(inType) && isInteger(outType)) ||
|
||||
(isFloatCompatible(inType) && isFloatCompatible(outType)) ||
|
||||
(isIntegerCompatible(inType) && isPointerCompatible(outType)) ||
|
||||
(isPointerCompatible(inType) && isIntegerCompatible(outType)) ||
|
||||
(isInteger(inType) && isPointerCompatible(outType)) ||
|
||||
(isPointerCompatible(inType) && isInteger(outType)) ||
|
||||
(mlir::isa<fir::BoxType>(inType) &&
|
||||
mlir::isa<fir::BoxType>(outType)) ||
|
||||
(mlir::isa<fir::BoxProcType>(inType) &&
|
||||
|
||||
@@ -6,7 +6,10 @@ program main
|
||||
call sa(%val(a1))
|
||||
! CHECK: %[[A1_ADDR:.*]] = fir.address_of(@_QFEa1) : !fir.ref<!fir.logical<4>>
|
||||
! 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>>)
|
||||
! CHECK: fir.call @_QPsa(%[[A1_DECL]]#0) fastmath<contract> : (!fir.ref<!fir.logical<4>>) -> ()
|
||||
! CHECK: %[[A1_LOADED:.*]] = fir.load %[[A1_DECL]]#0 : !fir.ref<!fir.logical<4>>
|
||||
! CHECK: %[[SA_ADDR:.*]] = fir.address_of(@_QPsa) : (!fir.ref<!fir.logical<4>>) -> ()
|
||||
! CHECK: %[[SA_CONVERT:.*]] = fir.convert %[[SA_ADDR]] : ((!fir.ref<!fir.logical<4>>) -> ()) -> ((!fir.logical<4>) -> ())
|
||||
! CHECK: fir.call %[[SA_CONVERT]](%[[A1_LOADED]]) fastmath<contract> : (!fir.logical<4>) -> ()
|
||||
! CHECK: func.func @_QPsa(%[[SA_ARG:.*]]: !fir.ref<!fir.logical<4>> {fir.bindc_name = "x1"}) {
|
||||
write(6,*) "a1 = ", a1
|
||||
end program main
|
||||
|
||||
Reference in New Issue
Block a user