[flang-commits] [flang] [flang] Implement IERRNO intrinsic (PR #124281)
Jean-Didier PAILLEUX via flang-commits
flang-commits at lists.llvm.org
Fri Jan 24 07:08:35 PST 2025
https://github.com/JDPailleux created https://github.com/llvm/llvm-project/pull/124281
Add the implementation of the IERRNO intrinsic to get the last system error number, as given by the C errno variable.
This intrinsic is also used in RAMSES (https://github.com/ramses-organisation/ramses/).
>From 6ad466c73531820ddbccd54fdda9d34ff5ac692c Mon Sep 17 00:00:00 2001
From: Jean-Didier Pailleux <jean-didier.pailleux at sipearl.com>
Date: Fri, 24 Jan 2025 11:32:45 +0100
Subject: [PATCH] [flang] Implement IERRNO intrinsic
---
.../include/flang/Optimizer/Builder/IntrinsicCall.h | 2 ++
.../flang/Optimizer/Builder/Runtime/Command.h | 4 ++++
flang/include/flang/Runtime/command.h | 4 ++++
flang/lib/Evaluate/intrinsics.cpp | 1 +
flang/lib/Optimizer/Builder/IntrinsicCall.cpp | 8 ++++++++
flang/lib/Optimizer/Builder/Runtime/Command.cpp | 8 ++++++++
flang/runtime/command.cpp | 2 ++
flang/test/Lower/Intrinsics/ierrno.f90 | 12 ++++++++++++
8 files changed, 41 insertions(+)
create mode 100644 flang/test/Lower/Intrinsics/ierrno.f90
diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
index 9c9c0609f4fc3c..d2b5fdb27f92b7 100644
--- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
+++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h
@@ -307,6 +307,8 @@ struct IntrinsicLibrary {
mlir::Value genIeor(mlir::Type, llvm::ArrayRef<mlir::Value>);
fir::ExtendedValue genIndex(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
mlir::Value genIor(mlir::Type, llvm::ArrayRef<mlir::Value>);
+ mlir::Value genIerrno(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args);
fir::ExtendedValue genIparity(mlir::Type, llvm::ArrayRef<fir::ExtendedValue>);
fir::ExtendedValue genIsContiguous(mlir::Type,
llvm::ArrayRef<fir::ExtendedValue>);
diff --git a/flang/include/flang/Optimizer/Builder/Runtime/Command.h b/flang/include/flang/Optimizer/Builder/Runtime/Command.h
index 0d60a367d99981..293964b4716e59 100644
--- a/flang/include/flang/Optimizer/Builder/Runtime/Command.h
+++ b/flang/include/flang/Optimizer/Builder/Runtime/Command.h
@@ -58,5 +58,9 @@ mlir::Value genGetEnvVariable(fir::FirOpBuilder &, mlir::Location,
mlir::Value genGetCwd(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value c);
+/// Generate a call to the Ierrno runtime function which implements
+/// the IERRNO intrinsic.
+mlir::Value genIerrno(fir::FirOpBuilder &, mlir::Location);
+
} // namespace fir::runtime
#endif // FORTRAN_OPTIMIZER_BUILDER_RUNTIME_COMMAND_H
diff --git a/flang/include/flang/Runtime/command.h b/flang/include/flang/Runtime/command.h
index 7ab3f6442dcf92..53b501d9ac250b 100644
--- a/flang/include/flang/Runtime/command.h
+++ b/flang/include/flang/Runtime/command.h
@@ -59,6 +59,10 @@ std::int32_t RTNAME(GetEnvVariable)(const Descriptor &name,
// Calls getcwd()
std::int32_t RTNAME(GetCwd)(
const Descriptor &cwd, const char *sourceFile, int line);
+
+// IERRNO
+// Returns the last system error number, as given by the C errno variable.
+int RTNAME(Ierrno)();
}
} // namespace Fortran::runtime
diff --git a/flang/lib/Evaluate/intrinsics.cpp b/flang/lib/Evaluate/intrinsics.cpp
index f234241cfe14a6..3878d3d12cb723 100644
--- a/flang/lib/Evaluate/intrinsics.cpp
+++ b/flang/lib/Evaluate/intrinsics.cpp
@@ -591,6 +591,7 @@ static const IntrinsicInterface genericIntrinsicFunction[]{
{{"i", OperandUnsigned}, {"j", OperandUnsigned, Rank::elementalOrBOZ}},
OperandUnsigned},
{"ieor", {{"i", BOZ}, {"j", SameIntOrUnsigned}}, SameIntOrUnsigned},
+ {"ierrno", {}, DefaultInt},
{"image_index",
{{"coarray", AnyData, Rank::coarray}, {"sub", AnyInt, Rank::vector}},
DefaultInt, Rank::scalar, IntrinsicClass::transformationalFunction},
diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
index 6a343645ab8786..11dd7783380af7 100644
--- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
+++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp
@@ -403,6 +403,7 @@ static constexpr IntrinsicHandler handlers[]{
{"ieee_unordered", &I::genIeeeUnordered},
{"ieee_value", &I::genIeeeValue},
{"ieor", &I::genIeor},
+ {"ierrno", &I::genIerrno},
{"index",
&I::genIndex,
{{{"string", asAddr},
@@ -5546,6 +5547,13 @@ mlir::Value IntrinsicLibrary::genIeor(mlir::Type resultType,
args[1]);
}
+// IERRNO
+mlir::Value IntrinsicLibrary::genIerrno(mlir::Type resultType,
+ llvm::ArrayRef<mlir::Value> args) {
+ assert(args.size() == 0);
+ return fir::runtime::genIerrno(builder, loc);
+}
+
// INDEX
fir::ExtendedValue
IntrinsicLibrary::genIndex(mlir::Type resultType,
diff --git a/flang/lib/Optimizer/Builder/Runtime/Command.cpp b/flang/lib/Optimizer/Builder/Runtime/Command.cpp
index 8320d89493b336..8c8e25608ac2ad 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Command.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Command.cpp
@@ -101,3 +101,11 @@ mlir::Value fir::runtime::genGetCwd(fir::FirOpBuilder &builder,
builder, loc, runtimeFuncTy, cwd, sourceFile, sourceLine);
return builder.create<fir::CallOp>(loc, func, args).getResult(0);
}
+
+mlir::Value fir::runtime::genIerrno(fir::FirOpBuilder &builder,
+ mlir::Location loc) {
+ auto runtimeFunc =
+ fir::runtime::getRuntimeFunc<mkRTKey(Ierrno)>(loc, builder);
+ mlir::FunctionType runtimeFuncTy = runtimeFunc.getFunctionType();
+ return builder.create<fir::CallOp>(loc, runtimeFunc).getResult(0);
+}
diff --git a/flang/runtime/command.cpp b/flang/runtime/command.cpp
index a555e26f96a66c..43345267c961fd 100644
--- a/flang/runtime/command.cpp
+++ b/flang/runtime/command.cpp
@@ -261,4 +261,6 @@ std::int32_t RTNAME(GetCwd)(
return status;
}
+int RTNAME(Ierrno)() { return errno; }
+
} // namespace Fortran::runtime
diff --git a/flang/test/Lower/Intrinsics/ierrno.f90 b/flang/test/Lower/Intrinsics/ierrno.f90
new file mode 100644
index 00000000000000..1179eface9bdf7
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/ierrno.f90
@@ -0,0 +1,12 @@
+! RUN: bbc -emit-fir -hlfir=false %s -o - | FileCheck --check-prefixes=CHECK %s
+! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir %s -o - | FileCheck --check-prefixes=CHECK %s
+
+! CHECK-LABEL: func @_QPtest_ierrno(
+subroutine test_ierrno(name)
+ integer :: i
+ i = ierrno()
+! CHECK: %[[VAL_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtest_ierrnoEi"}
+! CHECK: %[[VAL_1:.*]] = fir.call @_FortranAIerrno
+! CHECK: fir.store %[[VAL_1]] to %[[VAL_0]] : !fir.ref<i32>
+! CHECK: return
+end subroutine test_ierrno
More information about the flang-commits
mailing list