Valentin Clement (バレンタイン クレメン) 12ba74e181
[flang] Do not produce result for void runtime call (#123155)
Runtime function call to a void function are producing a ssa value
because the FunctionType result is set to NoneType with is later
translated to a empty struct. This is not an issue when going to LLVM IR
but it breaks when lowering a gpu module to PTX. This patch update the
RTModel to correctly set the FunctionType result type to nothing.

This is one runtime call before this patch at the LLVM IR dialect step.
```
%45 = llvm.call @_FortranAAssign(%arg0, %1, %44, %4) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i32) -> !llvm.struct<()>
```

After the patch the call would be correctly formed
```
llvm.call @_FortranAAssign(%arg0, %1, %44, %4) : (!llvm.ptr, !llvm.ptr, !llvm.ptr, i32) -> ()
```

Without the patch it would lead to error like:
```
ptxas /tmp/mlir-cuda_device_mod-nvptx64-nvidia-cuda-sm_60-e804b6.ptx, line 10; error   : Output parameter cannot be an incomplete array.
ptxas /tmp/mlir-cuda_device_mod-nvptx64-nvidia-cuda-sm_60-e804b6.ptx, line 125; error   : Call has wrong number of parameters
```

The change is pretty much mechanical.
2025-01-16 12:34:38 -08:00

118 lines
5.7 KiB
C++

//===-- Inquiry.h - generate inquiry runtime API calls ----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Builder/Runtime/Inquiry.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
#include "flang/Runtime/inquiry.h"
#include "flang/Runtime/support.h"
using namespace Fortran::runtime;
/// Generate call to `Lbound` runtime routine when the DIM argument is present.
mlir::Value fir::runtime::genLboundDim(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value array,
mlir::Value dim) {
mlir::func::FuncOp lboundFunc =
fir::runtime::getRuntimeFunc<mkRTKey(LboundDim)>(loc, builder);
auto fTy = lboundFunc.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
auto args = fir::runtime::createArguments(builder, loc, fTy, array, dim,
sourceFile, sourceLine);
return builder.create<fir::CallOp>(loc, lboundFunc, args).getResult(0);
}
void fir::runtime::genLbound(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultAddr, mlir::Value array,
mlir::Value kind) {
mlir::func::FuncOp func =
fir::runtime::getRuntimeFunc<mkRTKey(Lbound)>(loc, builder);
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
auto args = fir::runtime::createArguments(
builder, loc, fTy, resultAddr, array, kind, sourceFile, sourceLine);
builder.create<fir::CallOp>(loc, func, args);
}
/// Generate call to `Ubound` runtime routine. Calls to UBOUND with a DIM
/// argument get transformed into an expression equivalent to
/// SIZE() + LBOUND() - 1, so they don't have an intrinsic in the runtime.
void fir::runtime::genUbound(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultBox, mlir::Value array,
mlir::Value kind) {
mlir::func::FuncOp uboundFunc =
fir::runtime::getRuntimeFunc<mkRTKey(Ubound)>(loc, builder);
auto fTy = uboundFunc.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));
auto args = fir::runtime::createArguments(builder, loc, fTy, resultBox, array,
kind, sourceFile, sourceLine);
builder.create<fir::CallOp>(loc, uboundFunc, args);
}
/// Generate call to `Size` runtime routine. This routine is a version when
/// the DIM argument is present.
mlir::Value fir::runtime::genSizeDim(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value array,
mlir::Value dim) {
mlir::func::FuncOp sizeFunc =
fir::runtime::getRuntimeFunc<mkRTKey(SizeDim)>(loc, builder);
auto fTy = sizeFunc.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(3));
auto args = fir::runtime::createArguments(builder, loc, fTy, array, dim,
sourceFile, sourceLine);
return builder.create<fir::CallOp>(loc, sizeFunc, args).getResult(0);
}
/// Generate call to `Size` runtime routine. This routine is a version when
/// the DIM argument is absent.
mlir::Value fir::runtime::genSize(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Value array) {
mlir::func::FuncOp sizeFunc =
fir::runtime::getRuntimeFunc<mkRTKey(Size)>(loc, builder);
auto fTy = sizeFunc.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(2));
auto args = fir::runtime::createArguments(builder, loc, fTy, array,
sourceFile, sourceLine);
return builder.create<fir::CallOp>(loc, sizeFunc, args).getResult(0);
}
/// Generate call to `Is_contiguous` runtime routine.
mlir::Value fir::runtime::genIsContiguous(fir::FirOpBuilder &builder,
mlir::Location loc,
mlir::Value array) {
mlir::func::FuncOp isContiguousFunc =
fir::runtime::getRuntimeFunc<mkRTKey(IsContiguous)>(loc, builder);
auto fTy = isContiguousFunc.getFunctionType();
auto args = fir::runtime::createArguments(builder, loc, fTy, array);
return builder.create<fir::CallOp>(loc, isContiguousFunc, args).getResult(0);
}
void fir::runtime::genShape(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value resultAddr, mlir::Value array,
mlir::Value kind) {
mlir::func::FuncOp func =
fir::runtime::getRuntimeFunc<mkRTKey(Shape)>(loc, builder);
auto fTy = func.getFunctionType();
auto sourceFile = fir::factory::locationToFilename(builder, loc);
auto sourceLine =
fir::factory::locationToLineNo(builder, loc, fTy.getInput(4));
auto args = fir::runtime::createArguments(
builder, loc, fTy, resultAddr, array, kind, sourceFile, sourceLine);
builder.create<fir::CallOp>(loc, func, args);
}