[flang] Support extention intrinsic ABORT

The semantic checks and runtime have been supported. This supports the
lowering of intrinsic ABORT.

`gfortran` prints a backtrace before abort, unless `-fno-backtrace` is
given. This is good to use. The intrinsic BACKTRACE is not supported
yet, so add TODO in the runtime.

This extention is needed in SPEC2017 521.wrf_r in
https://github.com/llvm/llvm-project/issues/55955.

Reviewed By: klausler

Differential Revision: https://reviews.llvm.org/D130439
This commit is contained in:
Peixin Qiao 2022-08-02 23:02:12 +08:00
parent 9b867928f4
commit 1f9212d8d5
5 changed files with 32 additions and 1 deletions

View File

@ -27,6 +27,9 @@ namespace fir::runtime {
/// Generate call to EXIT intrinsic runtime routine.
void genExit(fir::FirOpBuilder &, mlir::Location, mlir::Value status);
/// Generate call to ABORT intrinsic runtime routine.
void genAbort(fir::FirOpBuilder &, mlir::Location);
/// Generate call to crash the program with an error message when detecting
/// an invalid situation at runtime.
void genReportFatalUserError(fir::FirOpBuilder &, mlir::Location,

View File

@ -441,6 +441,8 @@ struct IntrinsicLibrary {
getRuntimeCallGenerator(llvm::StringRef name,
mlir::FunctionType soughtFuncType);
void genAbort(llvm::ArrayRef<fir::ExtendedValue>);
/// Lowering for the ABS intrinsic. The ABS intrinsic expects one argument in
/// the llvm::ArrayRef. The ABS intrinsic is lowered into MLIR/FIR operation
/// if the argument is an integer, into llvm intrinsics if the argument is
@ -685,6 +687,7 @@ static constexpr bool handleDynamicOptional = true;
/// argument must not be lowered by value. In which case, the lowering rules
/// should be provided for all the intrinsic arguments for completeness.
static constexpr IntrinsicHandler handlers[]{
{"abort", &I::genAbort},
{"abs", &I::genAbs},
{"achar", &I::genChar},
{"adjustl",
@ -2105,6 +2108,12 @@ mlir::Value IntrinsicLibrary::genConversion(mlir::Type resultType,
return builder.convertWithSemantics(loc, resultType, args[0]);
}
// ABORT
void IntrinsicLibrary::genAbort(llvm::ArrayRef<fir::ExtendedValue> args) {
assert(args.size() == 0);
fir::runtime::genAbort(builder, loc);
}
// ABS
mlir::Value IntrinsicLibrary::genAbs(mlir::Type resultType,
llvm::ArrayRef<mlir::Value> args) {

View File

@ -22,6 +22,12 @@ void fir::runtime::genExit(fir::FirOpBuilder &builder, mlir::Location loc,
builder.create<fir::CallOp>(loc, exitFunc, args);
}
void fir::runtime::genAbort(fir::FirOpBuilder &builder, mlir::Location loc) {
mlir::func::FuncOp abortFunc =
fir::runtime::getRuntimeFunc<mkRTKey(Abort)>(loc, builder);
builder.create<fir::CallOp>(loc, abortFunc, llvm::None);
}
void fir::runtime::genReportFatalUserError(fir::FirOpBuilder &builder,
mlir::Location loc,
llvm::StringRef message) {

View File

@ -142,7 +142,10 @@ void RTNAME(PauseStatementText)(const char *code, std::size_t length) {
std::exit(status);
}
[[noreturn]] void RTNAME(Abort)() { std::abort(); }
[[noreturn]] void RTNAME(Abort)() {
// TODO: Add backtrace call, unless with `-fno-backtrace`.
std::abort();
}
[[noreturn]] void RTNAME(ReportFatalUserError)(
const char *message, const char *source, int line) {

View File

@ -0,0 +1,10 @@
! RUN: bbc -emit-fir %s -o - | FileCheck %s
! CHECK-LABEL: func.func @_QPabort_test() {
! CHECK: %[[VAL_0:.*]] = fir.call @_FortranAAbort() : () -> none
! CHECK: return
! CHECK: }
subroutine abort_test()
call abort
end subroutine