[flang-commits] [flang] [flang][DRAFT] Mark EXIT() intrinsic as not returning (PR #170603)
Eugene Epshteyn via flang-commits
flang-commits at lists.llvm.org
Sun Dec 7 19:41:01 PST 2025
https://github.com/eugeneepshteyn updated https://github.com/llvm/llvm-project/pull/170603
>From ce7db5501e0b4ff9853805f2bf4839f5431fdcd6 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 3 Dec 2025 23:38:09 -0500
Subject: [PATCH 1/3] [flang][DRAFT] unreachable after exit
---
flang/lib/Optimizer/Builder/Runtime/Stop.cpp | 2 ++
flang/test/Lower/Intrinsics/exit-noreturn.f90 | 14 ++++++++++++++
2 files changed, 16 insertions(+)
create mode 100644 flang/test/Lower/Intrinsics/exit-noreturn.f90
diff --git a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
index 5629371947641..98e3e940d92b7 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
@@ -17,9 +17,11 @@ using namespace Fortran::runtime;
void fir::runtime::genExit(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value status) {
auto exitFunc = fir::runtime::getRuntimeFunc<mkRTKey(Exit)>(loc, builder);
+ exitFunc->setAttr("noreturn", builder.getUnitAttr());
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
builder, loc, exitFunc.getFunctionType(), status);
fir::CallOp::create(builder, loc, exitFunc, args);
+ builder.create<fir::UnreachableOp>(loc);
}
void fir::runtime::genAbort(fir::FirOpBuilder &builder, mlir::Location loc) {
diff --git a/flang/test/Lower/Intrinsics/exit-noreturn.f90 b/flang/test/Lower/Intrinsics/exit-noreturn.f90
new file mode 100644
index 0000000000000..456d0b8779f17
--- /dev/null
+++ b/flang/test/Lower/Intrinsics/exit-noreturn.f90
@@ -0,0 +1,14 @@
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
+
+integer function test_exit(status)
+ integer, intent(in) :: status
+ if (status > 0) call exit(status)
+ if (status == 42) print *, "Unreachable"
+ test_exit = status
+end function test_exit
+
+! CHECK-LABEL: func.func @_QPtest_exit
+! CHECK: fir.call @_FortranAExit
+! CHECK-NEXT: fir.unreachable
+
+! CHECK: func.func private @_FortranAExit{{.*}} attributes {{.*}}noreturn
>From d69f1b604f9a2a6afef6c48784e514d9a630640a Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Wed, 3 Dec 2025 23:47:34 -0500
Subject: [PATCH 2/3] Added documentation for EXIT()
---
flang/docs/Intrinsics.md | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index 31bead9f8bfdc..80c7589602c4b 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -981,6 +981,31 @@ program test_etime
end program test_etime
```
+### Non-Standard Intrinsics: EXIT
+
+#### Description
+`EXIT([STATUS])` terminates the program execution.
+
+#### Usage and Info
+
+- **Standard:** GNU extension
+- **Class:** Subroutine
+- **Syntax:** `CALL EXIT([STATUS])`
+- **Arguments:**
+
+| Argument | Description |
+|----------|-------------|
+| `STATUS` | (Optional) Scalar INTEGER argument. If not present, then default success code is returned (usually, 0). |
+
+#### Example
+```Fortran
+program call_exit
+ integer :: status = 42
+ print *, "Exiting..."
+ call exit(status)
+end
+```
+
### Non-Standard Intrinsics: GETCWD
#### Description
>From bce370d3a8adada6a989373f9fd2a517f57579b9 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Sun, 7 Dec 2025 22:40:50 -0500
Subject: [PATCH 3/3] genUnreachable() is now exposed as
Fortran::lower::genUnreachable()
---
flang/include/flang/Lower/Runtime.h | 1 +
flang/lib/Lower/Runtime.cpp | 2 +-
flang/lib/Optimizer/Builder/Runtime/Stop.cpp | 4 +++-
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/flang/include/flang/Lower/Runtime.h b/flang/include/flang/Lower/Runtime.h
index 204093f9a766a..bfc8a87a75880 100644
--- a/flang/include/flang/Lower/Runtime.h
+++ b/flang/include/flang/Lower/Runtime.h
@@ -68,6 +68,7 @@ void genPointerAssociateRemapping(fir::FirOpBuilder &, mlir::Location,
void genPointerAssociateLowerBounds(fir::FirOpBuilder &, mlir::Location,
mlir::Value pointer, mlir::Value target,
mlir::Value lbounds);
+void genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc);
} // namespace lower
} // namespace Fortran
diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp
index 5f8586b9c8a88..8e67d6685581d 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -34,7 +34,7 @@ using namespace Fortran::runtime;
/// Runtime calls that do not return to the caller indicate this condition by
/// terminating the current basic block with an unreachable op.
-static void genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc) {
+void Fortran::lower::genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc) {
mlir::Block *curBlock = builder.getBlock();
mlir::Operation *parentOp = curBlock->getParentOp();
if (parentOp->getDialect()->getNamespace() ==
diff --git a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
index 98e3e940d92b7..d69225059703e 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
@@ -10,6 +10,7 @@
#include "flang/Optimizer/Builder/BoxValue.h"
#include "flang/Optimizer/Builder/FIRBuilder.h"
#include "flang/Optimizer/Builder/Runtime/RTBuilder.h"
+#include "flang/Lower/Runtime.h"
#include "flang/Runtime/stop.h"
using namespace Fortran::runtime;
@@ -21,13 +22,14 @@ void fir::runtime::genExit(fir::FirOpBuilder &builder, mlir::Location loc,
llvm::SmallVector<mlir::Value> args = fir::runtime::createArguments(
builder, loc, exitFunc.getFunctionType(), status);
fir::CallOp::create(builder, loc, exitFunc, args);
- builder.create<fir::UnreachableOp>(loc);
+ Fortran::lower::genUnreachable(builder, loc);
}
void fir::runtime::genAbort(fir::FirOpBuilder &builder, mlir::Location loc) {
mlir::func::FuncOp abortFunc =
fir::runtime::getRuntimeFunc<mkRTKey(Abort)>(loc, builder);
fir::CallOp::create(builder, loc, abortFunc, mlir::ValueRange{});
+ Fortran::lower::genUnreachable(builder, loc);
}
void fir::runtime::genReportFatalUserError(fir::FirOpBuilder &builder,
More information about the flang-commits
mailing list