[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