[flang-commits] [flang] [flang][DRAFT] Mark EXIT() intrinsic as not returning (PR #170603)
Eugene Epshteyn via flang-commits
flang-commits at lists.llvm.org
Tue Dec 9 20:56:57 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 01/15] [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 02/15] 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 03/15] 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,
>From 7ecd2da356d76cf8497968595d01238763ff1bb0 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Sun, 7 Dec 2025 23:02:50 -0500
Subject: [PATCH 04/15] tco now depends on FortranLower
---
flang/170591/analysis.md | 61 ++++++++++++++++++
flang/170591/comments.json | 3 +
flang/170591/issue.json | 86 +++++++++++++++++++++++++
flang/170591/repro-main-full.f90 | 24 +++++++
flang/170591/repro-main.f90 | 8 +++
flang/170591/repro-main.mlir | 69 ++++++++++++++++++++
flang/170591/repro-main.s | 105 +++++++++++++++++++++++++++++++
flang/170591/run-main.sh | 20 ++++++
flang/tools/tco/CMakeLists.txt | 1 +
9 files changed, 377 insertions(+)
create mode 100644 flang/170591/analysis.md
create mode 100644 flang/170591/comments.json
create mode 100644 flang/170591/issue.json
create mode 100644 flang/170591/repro-main-full.f90
create mode 100644 flang/170591/repro-main.f90
create mode 100644 flang/170591/repro-main.mlir
create mode 100644 flang/170591/repro-main.s
create mode 100755 flang/170591/run-main.sh
diff --git a/flang/170591/analysis.md b/flang/170591/analysis.md
new file mode 100644
index 0000000000000..1e27eccdeaaa7
--- /dev/null
+++ b/flang/170591/analysis.md
@@ -0,0 +1,61 @@
+# Analysis of GitHub Issue 170591
+
+**Issue Title:** `[flang] _FortranAExit does not have [[noreturn]] semantic`
+**Issue URL:** https://github.com/llvm/llvm-project/issues/170591
+
+## Summary of the Issue:
+The user reported that the `flang` compiler does not correctly optimize code following a call to the intrinsic `exit()` (which translates to `_FortranAExit`). Specifically, at optimization level `-O3`, code that should be unreachable after `exit()` is still generated in the assembly output. This indicates that `flang` does not recognize `_FortranAExit` as a `noreturn` function.
+
+**Expected Behavior:** Code after `call exit(status)` should be optimized out because the program execution terminates at `exit()`.
+**Actual Behavior:** The `flang` compiler, even with `-O3`, generates assembly for statements that follow `call exit(status)`.
+
+## Reproducer(s):
+The issue body provided a Fortran function `KOHb_exit`. For local reproduction and detailed analysis, this function was isolated and compiled.
+
+**`repro-main.f90`:**
+```fortran
+integer function KOHb_exit(status)
+ integer, intent(in) :: status
+ if (status > 0) call exit(status) ! actually, _FortranAExit
+ KOHb_exit = 0
+ do i = 1, status
+ print '(A,I0)', "KOHb #", i
+ end do
+end function KOHb_exit
+```
+
+## Runner Script:
+A `run-main.sh` script was created to compile `repro-main.f90` with `flang -O3 -S` to generate assembly code.
+
+**`run-main.sh`:**
+```bash
+#!/bin/bash
+
+SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
+REPRO_DIR="$SCRIPT_DIR"
+
+FLANG_COMPILER="/home/eepshteyn/compilers/flang-upstream/bin/flang"
+
+echo "Compiling repro-main.f90 with -O3..."
+"$FLANG_COMPILER" -O3 -S "$REPRO_DIR/repro-main.f90" -o "$REPRO_DIR/repro-main.s"
+
+if [ $? -ne 0 ]; then
+ echo "Compilation failed!"
+ exit 1
+fi
+
+echo "Assembly generated in repro-main.s"
+```
+
+## Compiler Output Mentioned in the Issue:
+The issue mentions that at `-O3`, `flang` generates `print` statements in the assembly after `exit`. This was demonstrated via a Godbolt link showing the assembly output.
+
+## Check if the issue is still present in local compiler:
+The `run-main.sh` script was executed, generating `repro-main.s`. Analysis of `repro-main.s` revealed the following:
+1. The `_FortranAExit` call is present, correctly branched to based on the `status` argument.
+2. Immediately following the `callq _FortranAExit at PLT` instruction, the assembly code still contains instructions related to the `do` loop and `print` statement. These include calls to Fortran I/O routines such as `_FortranAioBeginExternalFormattedOutput`, `_FortranAioOutputAscii`, `_FortranAioOutputInteger32`, and `_FortranAioEndIoStatement`. The string literal "KOHb #" is also referenced.
+
+This confirms that the compiler *does not* optimize away the unreachable code after `_FortranAExit`.
+
+## Conclusion:
+The issue reported in GitHub issue 170591 is still present in the local `flang` compiler (version 22.0.0, commit e74b425ddcac22ccc4d0bd5d65f95ffc2682b62f). The compiler fails to apply the `[[noreturn]]` semantic to `_FortranAExit`, leading to the generation of unreachable code in optimized assembly.
diff --git a/flang/170591/comments.json b/flang/170591/comments.json
new file mode 100644
index 0000000000000..41b42e677b973
--- /dev/null
+++ b/flang/170591/comments.json
@@ -0,0 +1,3 @@
+[
+
+]
diff --git a/flang/170591/issue.json b/flang/170591/issue.json
new file mode 100644
index 0000000000000..475704a62e2fe
--- /dev/null
+++ b/flang/170591/issue.json
@@ -0,0 +1,86 @@
+{
+ "url": "https://api.github.com/repos/llvm/llvm-project/issues/170591",
+ "repository_url": "https://api.github.com/repos/llvm/llvm-project",
+ "labels_url": "https://api.github.com/repos/llvm/llvm-project/issues/170591/labels{/name}",
+ "comments_url": "https://api.github.com/repos/llvm/llvm-project/issues/170591/comments",
+ "events_url": "https://api.github.com/repos/llvm/llvm-project/issues/170591/events",
+ "html_url": "https://github.com/llvm/llvm-project/issues/170591",
+ "id": 3692500400,
+ "node_id": "I_kwDOBITxeM7cFxWw",
+ "number": 170591,
+ "title": "[flang] _FortranAExit does not have [[noreturn]] semantic",
+ "user": {
+ "login": "foxtran",
+ "id": 39676482,
+ "node_id": "MDQ6VXNlcjM5Njc2NDgy",
+ "avatar_url": "https://avatars.githubusercontent.com/u/39676482?v=4",
+ "gravatar_id": "",
+ "url": "https://api.github.com/users/foxtran",
+ "html_url": "https://github.com/foxtran",
+ "followers_url": "https://api.github.com/users/foxtran/followers",
+ "following_url": "https://api.github.com/users/foxtran/following{/other_user}",
+ "gists_url": "https://api.github.com/users/foxtran/gists{/gist_id}",
+ "starred_url": "https://api.github.com/users/foxtran/starred{/owner}{/repo}",
+ "subscriptions_url": "https://api.github.com/users/foxtran/subscriptions",
+ "organizations_url": "https://api.github.com/users/foxtran/orgs",
+ "repos_url": "https://api.github.com/users/foxtran/repos",
+ "events_url": "https://api.github.com/users/foxtran/events{/privacy}",
+ "received_events_url": "https://api.github.com/users/foxtran/received_events",
+ "type": "User",
+ "user_view_type": "public",
+ "site_admin": false
+ },
+ "labels": [
+ {
+ "id": 3891017139,
+ "node_id": "LA_kwDOBITxeM7n7DWz",
+ "url": "https://api.github.com/repos/llvm/llvm-project/labels/flang",
+ "name": "flang",
+ "color": "bfd4f2",
+ "default": false,
+ "description": "Flang issues not falling into any other category"
+ }
+ ],
+ "state": "open",
+ "locked": false,
+ "assignee": null,
+ "assignees": [
+
+ ],
+ "milestone": null,
+ "comments": 0,
+ "created_at": "2025-12-04T01:45:40Z",
+ "updated_at": "2025-12-04T01:56:46Z",
+ "closed_at": null,
+ "author_association": "MEMBER",
+ "type": null,
+ "active_lock_reason": null,
+ "sub_issues_summary": {
+ "total": 0,
+ "completed": 0,
+ "percent_completed": 0
+ },
+ "issue_dependencies_summary": {
+ "blocked_by": 0,
+ "total_blocked_by": 0,
+ "blocking": 0,
+ "total_blocking": 0
+ },
+ "body": "For the following code:\n```fortran\ninteger function KOHb_exit(status)\n integer, intent(in) :: status\n if (status > 0) call exit(status) ! actually, _FortranAExit\n KOHb_exit = 0\n do i = 1, status\n print '(A,I0)', \"KOHb #\", i\n end do\nend function KOHb_exit\n```\none would expect that this code will never have print statement in ASM at high level of optimizations, since execution after `exit` is not possible. However, current LLVM flang generates print statements at -O3:\nhttps://godbolt.org/z/EzK3nWfrq\n\nFor `error stop` (as well as `stop`), the code looks cool:\nhttps://godbolt.org/z/7bvhf4Ef3",
+ "closed_by": null,
+ "reactions": {
+ "url": "https://api.github.com/repos/llvm/llvm-project/issues/170591/reactions",
+ "total_count": 0,
+ "+1": 0,
+ "-1": 0,
+ "laugh": 0,
+ "hooray": 0,
+ "confused": 0,
+ "heart": 0,
+ "rocket": 0,
+ "eyes": 0
+ },
+ "timeline_url": "https://api.github.com/repos/llvm/llvm-project/issues/170591/timeline",
+ "performed_via_github_app": null,
+ "state_reason": null
+}
diff --git a/flang/170591/repro-main-full.f90 b/flang/170591/repro-main-full.f90
new file mode 100644
index 0000000000000..278f161cefc7e
--- /dev/null
+++ b/flang/170591/repro-main-full.f90
@@ -0,0 +1,24 @@
+program main
+ integer :: status_val
+
+ ! Test case 1: status > 0, should trigger exit
+ print *, "Calling KOHb_exit with status = 1"
+ status_val = KOHb_exit(1)
+ print *, "Returned from KOHb_exit (should not happen if exit is called): ", status_val
+
+ ! Test case 2: status <= 0, should not trigger exit
+ print *, "Calling KOHb_exit with status = 0"
+ status_val = KOHb_exit(0)
+ print *, "Returned from KOHb_exit: ", status_val
+
+end program main
+
+! The original function from the issue
+integer function KOHb_exit(status)
+ integer, intent(in) :: status
+ if (status > 0) call exit(status) ! actually, _FortranAExit
+ KOHb_exit = 0
+ do i = 1, status
+ print '(A,I0)', "KOHb #", i
+ end do
+end function KOHb_exit
diff --git a/flang/170591/repro-main.f90 b/flang/170591/repro-main.f90
new file mode 100644
index 0000000000000..20563a2ad4863
--- /dev/null
+++ b/flang/170591/repro-main.f90
@@ -0,0 +1,8 @@
+integer function KOHb_exit(status)
+ integer, intent(in) :: status
+ if (status > 0) call exit(status) ! actually, _FortranAExit
+ KOHb_exit = 0
+ do i = 1, status
+ print '(A,I0)', "KOHb #", i
+ end do
+end function KOHb_exit
diff --git a/flang/170591/repro-main.mlir b/flang/170591/repro-main.mlir
new file mode 100644
index 0000000000000..213cd2fa576c9
--- /dev/null
+++ b/flang/170591/repro-main.mlir
@@ -0,0 +1,69 @@
+module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (https://github.com/eugeneepshteyn/llvm-project.git b70be3dc14c1f54eaae33418ced28a3473ab7d70)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
+ func.func @_QPkohb_exit(%arg0: !fir.ref<i32> {fir.bindc_name = "status"}) -> i32 {
+ %c6_i32 = arith.constant 6 : i32
+ %c6 = arith.constant 6 : index
+ %c1 = arith.constant 1 : index
+ %c1_i32 = arith.constant 1 : i32
+ %c0_i32 = arith.constant 0 : i32
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFkohb_exitEi"}
+ %2 = fir.declare %1 {uniq_name = "_QFkohb_exitEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %3 = fir.alloca i32 {bindc_name = "kohb_exit", uniq_name = "_QFkohb_exitEkohb_exit"}
+ %4 = fir.declare %3 {uniq_name = "_QFkohb_exitEkohb_exit"} : (!fir.ref<i32>) -> !fir.ref<i32>
+ %5 = fir.declare %arg0 dummy_scope %0 arg 1 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFkohb_exitEstatus"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ %6 = fir.load %5 : !fir.ref<i32>
+ %7 = arith.cmpi sgt, %6, %c0_i32 : i32
+ fir.if %7 {
+ %14 = fir.load %5 : !fir.ref<i32>
+ fir.call @_FortranAExit(%14) fastmath<contract> : (i32) -> ()
+ }
+ fir.store %c0_i32 to %4 : !fir.ref<i32>
+ %8 = fir.convert %c1_i32 : (i32) -> index
+ %9 = fir.load %5 : !fir.ref<i32>
+ %10 = fir.convert %9 : (i32) -> index
+ %11 = fir.convert %8 : (index) -> i32
+ %12 = fir.do_loop %arg1 = %8 to %10 step %c1 iter_args(%arg2 = %11) -> (i32) {
+ fir.store %arg2 to %2 : !fir.ref<i32>
+ %14 = fir.address_of(@_QQclX28412C493029) : !fir.ref<!fir.char<1,6>>
+ %15 = fir.declare %14 typeparams %c6 {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX28412C493029"} : (!fir.ref<!fir.char<1,6>>, index) -> !fir.ref<!fir.char<1,6>>
+ %16 = fir.convert %15 : (!fir.ref<!fir.char<1,6>>) -> !fir.ref<i8>
+ %17 = fir.convert %c6 : (index) -> i64
+ %18 = fir.zero_bits !fir.box<none>
+ %19 = fir.address_of(@_QQclXa224fc2bcd1182277fdd6e03fbf16dbd) : !fir.ref<!fir.char<1,76>>
+ %20 = fir.convert %19 : (!fir.ref<!fir.char<1,76>>) -> !fir.ref<i8>
+ %21 = fir.call @_FortranAioBeginExternalFormattedOutput(%16, %17, %18, %c6_i32, %20, %c6_i32) fastmath<contract> : (!fir.ref<i8>, i64, !fir.box<none>, i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
+ %22 = fir.address_of(@_QQclX4B4F48622023) : !fir.ref<!fir.char<1,6>>
+ %23 = fir.declare %22 typeparams %c6 {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX4B4F48622023"} : (!fir.ref<!fir.char<1,6>>, index) -> !fir.ref<!fir.char<1,6>>
+ %24 = fir.convert %23 : (!fir.ref<!fir.char<1,6>>) -> !fir.ref<i8>
+ %25 = fir.convert %c6 : (index) -> i64
+ %26 = fir.call @_FortranAioOutputAscii(%21, %24, %25) fastmath<contract> : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
+ %27 = fir.load %2 : !fir.ref<i32>
+ %28 = fir.call @_FortranAioOutputInteger32(%21, %27) fastmath<contract> : (!fir.ref<i8>, i32) -> i1
+ %29 = fir.call @_FortranAioEndIoStatement(%21) fastmath<contract> : (!fir.ref<i8>) -> i32
+ %30 = fir.convert %c1 : (index) -> i32
+ %31 = fir.load %2 : !fir.ref<i32>
+ %32 = arith.addi %31, %30 overflow<nsw> : i32
+ fir.result %32 : i32
+ }
+ fir.store %12 to %2 : !fir.ref<i32>
+ %13 = fir.load %4 : !fir.ref<i32>
+ return %13 : i32
+ }
+ func.func private @_FortranAExit(i32) attributes {fir.runtime}
+ func.func private @_FortranAioBeginExternalFormattedOutput(!fir.ref<i8>, i64, !fir.box<none>, i32, !fir.ref<i8>, i32) -> !fir.ref<i8> attributes {fir.io, fir.runtime}
+ fir.global linkonce @_QQclX28412C493029 constant : !fir.char<1,6> {
+ %0 = fir.string_lit "(A,I0)"(6) : !fir.char<1,6>
+ fir.has_value %0 : !fir.char<1,6>
+ }
+ fir.global linkonce @_QQclXa224fc2bcd1182277fdd6e03fbf16dbd constant : !fir.char<1,76> {
+ %0 = fir.string_lit "/home/eepshteyn/src/flang-upstream/llvm-project/flang/170591/repro-main.f90\00"(76) : !fir.char<1,76>
+ fir.has_value %0 : !fir.char<1,76>
+ }
+ func.func private @_FortranAioOutputAscii(!fir.ref<i8>, !fir.ref<i8>, i64) -> i1 attributes {fir.io, fir.runtime}
+ fir.global linkonce @_QQclX4B4F48622023 constant : !fir.char<1,6> {
+ %0 = fir.string_lit "KOHb #"(6) : !fir.char<1,6>
+ fir.has_value %0 : !fir.char<1,6>
+ }
+ func.func private @_FortranAioOutputInteger32(!fir.ref<i8>, i32) -> i1 attributes {fir.io, fir.runtime}
+ func.func private @_FortranAioEndIoStatement(!fir.ref<i8>) -> i32 attributes {fir.io, fir.runtime}
+}
diff --git a/flang/170591/repro-main.s b/flang/170591/repro-main.s
new file mode 100644
index 0000000000000..30cd8a9f5983a
--- /dev/null
+++ b/flang/170591/repro-main.s
@@ -0,0 +1,105 @@
+ .file "FIRModule"
+ .text
+ .globl kohb_exit_
+ .p2align 4
+ .type kohb_exit_, at function
+kohb_exit_:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ pushq %r15
+ .cfi_def_cfa_offset 24
+ pushq %r14
+ .cfi_def_cfa_offset 32
+ pushq %r13
+ .cfi_def_cfa_offset 40
+ pushq %r12
+ .cfi_def_cfa_offset 48
+ pushq %rbx
+ .cfi_def_cfa_offset 56
+ pushq %rax
+ .cfi_def_cfa_offset 64
+ .cfi_offset %rbx, -56
+ .cfi_offset %r12, -48
+ .cfi_offset %r13, -40
+ .cfi_offset %r14, -32
+ .cfi_offset %r15, -24
+ .cfi_offset %rbp, -16
+ movslq (%rdi), %rbx
+ testq %rbx, %rbx
+ jle .LBB0_3
+ movl %ebx, %edi
+ callq _FortranAExit at PLT
+ incq %rbx
+ movl $1, %ebp
+ movq _QQclX28412C493029 at GOTPCREL(%rip), %r14
+ movq _QQclX9022f1477d515e3e3f2d41fd0f2d14e2 at GOTPCREL(%rip), %r15
+ movq _QQclX4B4F48622023 at GOTPCREL(%rip), %r12
+ .p2align 4
+.LBB0_2:
+ movl $6, %esi
+ movq %r14, %rdi
+ xorl %edx, %edx
+ movl $6, %ecx
+ movq %r15, %r8
+ movl $6, %r9d
+ callq _FortranAioBeginExternalFormattedOutput at PLT
+ movq %rax, %r13
+ movl $6, %edx
+ movq %rax, %rdi
+ movq %r12, %rsi
+ callq _FortranAioOutputAscii at PLT
+ movq %r13, %rdi
+ movl %ebp, %esi
+ callq _FortranAioOutputInteger32 at PLT
+ movq %r13, %rdi
+ callq _FortranAioEndIoStatement at PLT
+ incl %ebp
+ decq %rbx
+ cmpq $1, %rbx
+ ja .LBB0_2
+.LBB0_3:
+ xorl %eax, %eax
+ addq $8, %rsp
+ .cfi_def_cfa_offset 56
+ popq %rbx
+ .cfi_def_cfa_offset 48
+ popq %r12
+ .cfi_def_cfa_offset 40
+ popq %r13
+ .cfi_def_cfa_offset 32
+ popq %r14
+ .cfi_def_cfa_offset 24
+ popq %r15
+ .cfi_def_cfa_offset 16
+ popq %rbp
+ .cfi_def_cfa_offset 8
+ retq
+.Lfunc_end0:
+ .size kohb_exit_, .Lfunc_end0-kohb_exit_
+ .cfi_endproc
+
+ .type _QQclX28412C493029, at object
+ .section .rodata._QQclX28412C493029,"aG", at progbits,_QQclX28412C493029,comdat
+ .weak _QQclX28412C493029
+_QQclX28412C493029:
+ .ascii "(A,I0)"
+ .size _QQclX28412C493029, 6
+
+ .type _QQclX9022f1477d515e3e3f2d41fd0f2d14e2, at object
+ .section .rodata._QQclX9022f1477d515e3e3f2d41fd0f2d14e2,"aG", at progbits,_QQclX9022f1477d515e3e3f2d41fd0f2d14e2,comdat
+ .weak _QQclX9022f1477d515e3e3f2d41fd0f2d14e2
+ .p2align 4, 0x0
+_QQclX9022f1477d515e3e3f2d41fd0f2d14e2:
+ .asciz "/home/eepshteyn/eugene-tasks/gh-issue-dump/170591/repro-main.f90"
+ .size _QQclX9022f1477d515e3e3f2d41fd0f2d14e2, 65
+
+ .type _QQclX4B4F48622023, at object
+ .section .rodata._QQclX4B4F48622023,"aG", at progbits,_QQclX4B4F48622023,comdat
+ .weak _QQclX4B4F48622023
+_QQclX4B4F48622023:
+ .ascii "KOHb #"
+ .size _QQclX4B4F48622023, 6
+
+ .ident "flang version 22.0.0 (https://github.com/eugeneepshteyn/llvm-project.git e74b425ddcac22ccc4d0bd5d65f95ffc2682b62f)"
+ .section ".note.GNU-stack","", at progbits
diff --git a/flang/170591/run-main.sh b/flang/170591/run-main.sh
new file mode 100755
index 0000000000000..17464db272644
--- /dev/null
+++ b/flang/170591/run-main.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+# Get the directory of the script
+SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
+REPRO_DIR="$SCRIPT_DIR"
+
+# Define the flang compiler path
+FLANG_COMPILER="/home/eepshteyn/compilers/flang-upstream/bin/flang"
+
+# Compile the Fortran code with -O3 optimization
+echo "Compiling repro-main.f90 with -O3..."
+"$FLANG_COMPILER" -O3 -S "$REPRO_DIR/repro-main.f90" -o "$REPRO_DIR/repro-main.s"
+
+# Check if compilation was successful
+if [ $? -ne 0 ]; then
+ echo "Compilation failed!"
+ exit 1
+fi
+
+echo "Assembly generated in repro-main.s"
diff --git a/flang/tools/tco/CMakeLists.txt b/flang/tools/tco/CMakeLists.txt
index 5ab8952898a6c..9f1227f803b60 100644
--- a/flang/tools/tco/CMakeLists.txt
+++ b/flang/tools/tco/CMakeLists.txt
@@ -23,6 +23,7 @@ target_link_libraries(tco PRIVATE
FIROpenMPSupport
FlangOpenMPTransforms
FortranSupport
+ FortranLower
MIFDialect
)
>From 5b1fbdce6382dd5362c6b0fc546d32f7122cb2c3 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Sun, 7 Dec 2025 23:03:31 -0500
Subject: [PATCH 05/15] clang-format
---
flang/lib/Lower/Runtime.cpp | 3 ++-
flang/lib/Optimizer/Builder/Runtime/Stop.cpp | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp
index 8e67d6685581d..4254e25e3d85d 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -34,7 +34,8 @@ 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.
-void Fortran::lower::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 d69225059703e..094c2a131727c 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
@@ -7,10 +7,10 @@
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Builder/Runtime/Stop.h"
+#include "flang/Lower/Runtime.h"
#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;
>From 313f0c47a3825ee0902bc696cbe8e70f526155a4 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Sun, 7 Dec 2025 23:14:40 -0500
Subject: [PATCH 06/15] Removed analysis files checked in by mistake
---
flang/170591/analysis.md | 61 ------------------
flang/170591/comments.json | 3 -
flang/170591/issue.json | 86 -------------------------
flang/170591/repro-main-full.f90 | 24 -------
flang/170591/repro-main.f90 | 8 ---
flang/170591/repro-main.mlir | 69 --------------------
flang/170591/repro-main.s | 105 -------------------------------
flang/170591/run-main.sh | 20 ------
8 files changed, 376 deletions(-)
delete mode 100644 flang/170591/analysis.md
delete mode 100644 flang/170591/comments.json
delete mode 100644 flang/170591/issue.json
delete mode 100644 flang/170591/repro-main-full.f90
delete mode 100644 flang/170591/repro-main.f90
delete mode 100644 flang/170591/repro-main.mlir
delete mode 100644 flang/170591/repro-main.s
delete mode 100755 flang/170591/run-main.sh
diff --git a/flang/170591/analysis.md b/flang/170591/analysis.md
deleted file mode 100644
index 1e27eccdeaaa7..0000000000000
--- a/flang/170591/analysis.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# Analysis of GitHub Issue 170591
-
-**Issue Title:** `[flang] _FortranAExit does not have [[noreturn]] semantic`
-**Issue URL:** https://github.com/llvm/llvm-project/issues/170591
-
-## Summary of the Issue:
-The user reported that the `flang` compiler does not correctly optimize code following a call to the intrinsic `exit()` (which translates to `_FortranAExit`). Specifically, at optimization level `-O3`, code that should be unreachable after `exit()` is still generated in the assembly output. This indicates that `flang` does not recognize `_FortranAExit` as a `noreturn` function.
-
-**Expected Behavior:** Code after `call exit(status)` should be optimized out because the program execution terminates at `exit()`.
-**Actual Behavior:** The `flang` compiler, even with `-O3`, generates assembly for statements that follow `call exit(status)`.
-
-## Reproducer(s):
-The issue body provided a Fortran function `KOHb_exit`. For local reproduction and detailed analysis, this function was isolated and compiled.
-
-**`repro-main.f90`:**
-```fortran
-integer function KOHb_exit(status)
- integer, intent(in) :: status
- if (status > 0) call exit(status) ! actually, _FortranAExit
- KOHb_exit = 0
- do i = 1, status
- print '(A,I0)', "KOHb #", i
- end do
-end function KOHb_exit
-```
-
-## Runner Script:
-A `run-main.sh` script was created to compile `repro-main.f90` with `flang -O3 -S` to generate assembly code.
-
-**`run-main.sh`:**
-```bash
-#!/bin/bash
-
-SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
-REPRO_DIR="$SCRIPT_DIR"
-
-FLANG_COMPILER="/home/eepshteyn/compilers/flang-upstream/bin/flang"
-
-echo "Compiling repro-main.f90 with -O3..."
-"$FLANG_COMPILER" -O3 -S "$REPRO_DIR/repro-main.f90" -o "$REPRO_DIR/repro-main.s"
-
-if [ $? -ne 0 ]; then
- echo "Compilation failed!"
- exit 1
-fi
-
-echo "Assembly generated in repro-main.s"
-```
-
-## Compiler Output Mentioned in the Issue:
-The issue mentions that at `-O3`, `flang` generates `print` statements in the assembly after `exit`. This was demonstrated via a Godbolt link showing the assembly output.
-
-## Check if the issue is still present in local compiler:
-The `run-main.sh` script was executed, generating `repro-main.s`. Analysis of `repro-main.s` revealed the following:
-1. The `_FortranAExit` call is present, correctly branched to based on the `status` argument.
-2. Immediately following the `callq _FortranAExit at PLT` instruction, the assembly code still contains instructions related to the `do` loop and `print` statement. These include calls to Fortran I/O routines such as `_FortranAioBeginExternalFormattedOutput`, `_FortranAioOutputAscii`, `_FortranAioOutputInteger32`, and `_FortranAioEndIoStatement`. The string literal "KOHb #" is also referenced.
-
-This confirms that the compiler *does not* optimize away the unreachable code after `_FortranAExit`.
-
-## Conclusion:
-The issue reported in GitHub issue 170591 is still present in the local `flang` compiler (version 22.0.0, commit e74b425ddcac22ccc4d0bd5d65f95ffc2682b62f). The compiler fails to apply the `[[noreturn]]` semantic to `_FortranAExit`, leading to the generation of unreachable code in optimized assembly.
diff --git a/flang/170591/comments.json b/flang/170591/comments.json
deleted file mode 100644
index 41b42e677b973..0000000000000
--- a/flang/170591/comments.json
+++ /dev/null
@@ -1,3 +0,0 @@
-[
-
-]
diff --git a/flang/170591/issue.json b/flang/170591/issue.json
deleted file mode 100644
index 475704a62e2fe..0000000000000
--- a/flang/170591/issue.json
+++ /dev/null
@@ -1,86 +0,0 @@
-{
- "url": "https://api.github.com/repos/llvm/llvm-project/issues/170591",
- "repository_url": "https://api.github.com/repos/llvm/llvm-project",
- "labels_url": "https://api.github.com/repos/llvm/llvm-project/issues/170591/labels{/name}",
- "comments_url": "https://api.github.com/repos/llvm/llvm-project/issues/170591/comments",
- "events_url": "https://api.github.com/repos/llvm/llvm-project/issues/170591/events",
- "html_url": "https://github.com/llvm/llvm-project/issues/170591",
- "id": 3692500400,
- "node_id": "I_kwDOBITxeM7cFxWw",
- "number": 170591,
- "title": "[flang] _FortranAExit does not have [[noreturn]] semantic",
- "user": {
- "login": "foxtran",
- "id": 39676482,
- "node_id": "MDQ6VXNlcjM5Njc2NDgy",
- "avatar_url": "https://avatars.githubusercontent.com/u/39676482?v=4",
- "gravatar_id": "",
- "url": "https://api.github.com/users/foxtran",
- "html_url": "https://github.com/foxtran",
- "followers_url": "https://api.github.com/users/foxtran/followers",
- "following_url": "https://api.github.com/users/foxtran/following{/other_user}",
- "gists_url": "https://api.github.com/users/foxtran/gists{/gist_id}",
- "starred_url": "https://api.github.com/users/foxtran/starred{/owner}{/repo}",
- "subscriptions_url": "https://api.github.com/users/foxtran/subscriptions",
- "organizations_url": "https://api.github.com/users/foxtran/orgs",
- "repos_url": "https://api.github.com/users/foxtran/repos",
- "events_url": "https://api.github.com/users/foxtran/events{/privacy}",
- "received_events_url": "https://api.github.com/users/foxtran/received_events",
- "type": "User",
- "user_view_type": "public",
- "site_admin": false
- },
- "labels": [
- {
- "id": 3891017139,
- "node_id": "LA_kwDOBITxeM7n7DWz",
- "url": "https://api.github.com/repos/llvm/llvm-project/labels/flang",
- "name": "flang",
- "color": "bfd4f2",
- "default": false,
- "description": "Flang issues not falling into any other category"
- }
- ],
- "state": "open",
- "locked": false,
- "assignee": null,
- "assignees": [
-
- ],
- "milestone": null,
- "comments": 0,
- "created_at": "2025-12-04T01:45:40Z",
- "updated_at": "2025-12-04T01:56:46Z",
- "closed_at": null,
- "author_association": "MEMBER",
- "type": null,
- "active_lock_reason": null,
- "sub_issues_summary": {
- "total": 0,
- "completed": 0,
- "percent_completed": 0
- },
- "issue_dependencies_summary": {
- "blocked_by": 0,
- "total_blocked_by": 0,
- "blocking": 0,
- "total_blocking": 0
- },
- "body": "For the following code:\n```fortran\ninteger function KOHb_exit(status)\n integer, intent(in) :: status\n if (status > 0) call exit(status) ! actually, _FortranAExit\n KOHb_exit = 0\n do i = 1, status\n print '(A,I0)', \"KOHb #\", i\n end do\nend function KOHb_exit\n```\none would expect that this code will never have print statement in ASM at high level of optimizations, since execution after `exit` is not possible. However, current LLVM flang generates print statements at -O3:\nhttps://godbolt.org/z/EzK3nWfrq\n\nFor `error stop` (as well as `stop`), the code looks cool:\nhttps://godbolt.org/z/7bvhf4Ef3",
- "closed_by": null,
- "reactions": {
- "url": "https://api.github.com/repos/llvm/llvm-project/issues/170591/reactions",
- "total_count": 0,
- "+1": 0,
- "-1": 0,
- "laugh": 0,
- "hooray": 0,
- "confused": 0,
- "heart": 0,
- "rocket": 0,
- "eyes": 0
- },
- "timeline_url": "https://api.github.com/repos/llvm/llvm-project/issues/170591/timeline",
- "performed_via_github_app": null,
- "state_reason": null
-}
diff --git a/flang/170591/repro-main-full.f90 b/flang/170591/repro-main-full.f90
deleted file mode 100644
index 278f161cefc7e..0000000000000
--- a/flang/170591/repro-main-full.f90
+++ /dev/null
@@ -1,24 +0,0 @@
-program main
- integer :: status_val
-
- ! Test case 1: status > 0, should trigger exit
- print *, "Calling KOHb_exit with status = 1"
- status_val = KOHb_exit(1)
- print *, "Returned from KOHb_exit (should not happen if exit is called): ", status_val
-
- ! Test case 2: status <= 0, should not trigger exit
- print *, "Calling KOHb_exit with status = 0"
- status_val = KOHb_exit(0)
- print *, "Returned from KOHb_exit: ", status_val
-
-end program main
-
-! The original function from the issue
-integer function KOHb_exit(status)
- integer, intent(in) :: status
- if (status > 0) call exit(status) ! actually, _FortranAExit
- KOHb_exit = 0
- do i = 1, status
- print '(A,I0)', "KOHb #", i
- end do
-end function KOHb_exit
diff --git a/flang/170591/repro-main.f90 b/flang/170591/repro-main.f90
deleted file mode 100644
index 20563a2ad4863..0000000000000
--- a/flang/170591/repro-main.f90
+++ /dev/null
@@ -1,8 +0,0 @@
-integer function KOHb_exit(status)
- integer, intent(in) :: status
- if (status > 0) call exit(status) ! actually, _FortranAExit
- KOHb_exit = 0
- do i = 1, status
- print '(A,I0)', "KOHb #", i
- end do
-end function KOHb_exit
diff --git a/flang/170591/repro-main.mlir b/flang/170591/repro-main.mlir
deleted file mode 100644
index 213cd2fa576c9..0000000000000
--- a/flang/170591/repro-main.mlir
+++ /dev/null
@@ -1,69 +0,0 @@
-module attributes {dlti.dl_spec = #dlti.dl_spec<!llvm.ptr<270> = dense<32> : vector<4xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, i64 = dense<64> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, f80 = dense<128> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, i1 = dense<8> : vector<2xi64>, i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, f128 = dense<128> : vector<2xi64>, "dlti.endianness" = "little", "dlti.mangling_mode" = "e", "dlti.legal_int_widths" = array<i32: 8, 16, 32, 64>, "dlti.stack_alignment" = 128 : i64>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 22.0.0 (https://github.com/eugeneepshteyn/llvm-project.git b70be3dc14c1f54eaae33418ced28a3473ab7d70)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
- func.func @_QPkohb_exit(%arg0: !fir.ref<i32> {fir.bindc_name = "status"}) -> i32 {
- %c6_i32 = arith.constant 6 : i32
- %c6 = arith.constant 6 : index
- %c1 = arith.constant 1 : index
- %c1_i32 = arith.constant 1 : i32
- %c0_i32 = arith.constant 0 : i32
- %0 = fir.dummy_scope : !fir.dscope
- %1 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFkohb_exitEi"}
- %2 = fir.declare %1 {uniq_name = "_QFkohb_exitEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
- %3 = fir.alloca i32 {bindc_name = "kohb_exit", uniq_name = "_QFkohb_exitEkohb_exit"}
- %4 = fir.declare %3 {uniq_name = "_QFkohb_exitEkohb_exit"} : (!fir.ref<i32>) -> !fir.ref<i32>
- %5 = fir.declare %arg0 dummy_scope %0 arg 1 {fortran_attrs = #fir.var_attrs<intent_in>, uniq_name = "_QFkohb_exitEstatus"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
- %6 = fir.load %5 : !fir.ref<i32>
- %7 = arith.cmpi sgt, %6, %c0_i32 : i32
- fir.if %7 {
- %14 = fir.load %5 : !fir.ref<i32>
- fir.call @_FortranAExit(%14) fastmath<contract> : (i32) -> ()
- }
- fir.store %c0_i32 to %4 : !fir.ref<i32>
- %8 = fir.convert %c1_i32 : (i32) -> index
- %9 = fir.load %5 : !fir.ref<i32>
- %10 = fir.convert %9 : (i32) -> index
- %11 = fir.convert %8 : (index) -> i32
- %12 = fir.do_loop %arg1 = %8 to %10 step %c1 iter_args(%arg2 = %11) -> (i32) {
- fir.store %arg2 to %2 : !fir.ref<i32>
- %14 = fir.address_of(@_QQclX28412C493029) : !fir.ref<!fir.char<1,6>>
- %15 = fir.declare %14 typeparams %c6 {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX28412C493029"} : (!fir.ref<!fir.char<1,6>>, index) -> !fir.ref<!fir.char<1,6>>
- %16 = fir.convert %15 : (!fir.ref<!fir.char<1,6>>) -> !fir.ref<i8>
- %17 = fir.convert %c6 : (index) -> i64
- %18 = fir.zero_bits !fir.box<none>
- %19 = fir.address_of(@_QQclXa224fc2bcd1182277fdd6e03fbf16dbd) : !fir.ref<!fir.char<1,76>>
- %20 = fir.convert %19 : (!fir.ref<!fir.char<1,76>>) -> !fir.ref<i8>
- %21 = fir.call @_FortranAioBeginExternalFormattedOutput(%16, %17, %18, %c6_i32, %20, %c6_i32) fastmath<contract> : (!fir.ref<i8>, i64, !fir.box<none>, i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
- %22 = fir.address_of(@_QQclX4B4F48622023) : !fir.ref<!fir.char<1,6>>
- %23 = fir.declare %22 typeparams %c6 {fortran_attrs = #fir.var_attrs<parameter>, uniq_name = "_QQclX4B4F48622023"} : (!fir.ref<!fir.char<1,6>>, index) -> !fir.ref<!fir.char<1,6>>
- %24 = fir.convert %23 : (!fir.ref<!fir.char<1,6>>) -> !fir.ref<i8>
- %25 = fir.convert %c6 : (index) -> i64
- %26 = fir.call @_FortranAioOutputAscii(%21, %24, %25) fastmath<contract> : (!fir.ref<i8>, !fir.ref<i8>, i64) -> i1
- %27 = fir.load %2 : !fir.ref<i32>
- %28 = fir.call @_FortranAioOutputInteger32(%21, %27) fastmath<contract> : (!fir.ref<i8>, i32) -> i1
- %29 = fir.call @_FortranAioEndIoStatement(%21) fastmath<contract> : (!fir.ref<i8>) -> i32
- %30 = fir.convert %c1 : (index) -> i32
- %31 = fir.load %2 : !fir.ref<i32>
- %32 = arith.addi %31, %30 overflow<nsw> : i32
- fir.result %32 : i32
- }
- fir.store %12 to %2 : !fir.ref<i32>
- %13 = fir.load %4 : !fir.ref<i32>
- return %13 : i32
- }
- func.func private @_FortranAExit(i32) attributes {fir.runtime}
- func.func private @_FortranAioBeginExternalFormattedOutput(!fir.ref<i8>, i64, !fir.box<none>, i32, !fir.ref<i8>, i32) -> !fir.ref<i8> attributes {fir.io, fir.runtime}
- fir.global linkonce @_QQclX28412C493029 constant : !fir.char<1,6> {
- %0 = fir.string_lit "(A,I0)"(6) : !fir.char<1,6>
- fir.has_value %0 : !fir.char<1,6>
- }
- fir.global linkonce @_QQclXa224fc2bcd1182277fdd6e03fbf16dbd constant : !fir.char<1,76> {
- %0 = fir.string_lit "/home/eepshteyn/src/flang-upstream/llvm-project/flang/170591/repro-main.f90\00"(76) : !fir.char<1,76>
- fir.has_value %0 : !fir.char<1,76>
- }
- func.func private @_FortranAioOutputAscii(!fir.ref<i8>, !fir.ref<i8>, i64) -> i1 attributes {fir.io, fir.runtime}
- fir.global linkonce @_QQclX4B4F48622023 constant : !fir.char<1,6> {
- %0 = fir.string_lit "KOHb #"(6) : !fir.char<1,6>
- fir.has_value %0 : !fir.char<1,6>
- }
- func.func private @_FortranAioOutputInteger32(!fir.ref<i8>, i32) -> i1 attributes {fir.io, fir.runtime}
- func.func private @_FortranAioEndIoStatement(!fir.ref<i8>) -> i32 attributes {fir.io, fir.runtime}
-}
diff --git a/flang/170591/repro-main.s b/flang/170591/repro-main.s
deleted file mode 100644
index 30cd8a9f5983a..0000000000000
--- a/flang/170591/repro-main.s
+++ /dev/null
@@ -1,105 +0,0 @@
- .file "FIRModule"
- .text
- .globl kohb_exit_
- .p2align 4
- .type kohb_exit_, at function
-kohb_exit_:
- .cfi_startproc
- pushq %rbp
- .cfi_def_cfa_offset 16
- pushq %r15
- .cfi_def_cfa_offset 24
- pushq %r14
- .cfi_def_cfa_offset 32
- pushq %r13
- .cfi_def_cfa_offset 40
- pushq %r12
- .cfi_def_cfa_offset 48
- pushq %rbx
- .cfi_def_cfa_offset 56
- pushq %rax
- .cfi_def_cfa_offset 64
- .cfi_offset %rbx, -56
- .cfi_offset %r12, -48
- .cfi_offset %r13, -40
- .cfi_offset %r14, -32
- .cfi_offset %r15, -24
- .cfi_offset %rbp, -16
- movslq (%rdi), %rbx
- testq %rbx, %rbx
- jle .LBB0_3
- movl %ebx, %edi
- callq _FortranAExit at PLT
- incq %rbx
- movl $1, %ebp
- movq _QQclX28412C493029 at GOTPCREL(%rip), %r14
- movq _QQclX9022f1477d515e3e3f2d41fd0f2d14e2 at GOTPCREL(%rip), %r15
- movq _QQclX4B4F48622023 at GOTPCREL(%rip), %r12
- .p2align 4
-.LBB0_2:
- movl $6, %esi
- movq %r14, %rdi
- xorl %edx, %edx
- movl $6, %ecx
- movq %r15, %r8
- movl $6, %r9d
- callq _FortranAioBeginExternalFormattedOutput at PLT
- movq %rax, %r13
- movl $6, %edx
- movq %rax, %rdi
- movq %r12, %rsi
- callq _FortranAioOutputAscii at PLT
- movq %r13, %rdi
- movl %ebp, %esi
- callq _FortranAioOutputInteger32 at PLT
- movq %r13, %rdi
- callq _FortranAioEndIoStatement at PLT
- incl %ebp
- decq %rbx
- cmpq $1, %rbx
- ja .LBB0_2
-.LBB0_3:
- xorl %eax, %eax
- addq $8, %rsp
- .cfi_def_cfa_offset 56
- popq %rbx
- .cfi_def_cfa_offset 48
- popq %r12
- .cfi_def_cfa_offset 40
- popq %r13
- .cfi_def_cfa_offset 32
- popq %r14
- .cfi_def_cfa_offset 24
- popq %r15
- .cfi_def_cfa_offset 16
- popq %rbp
- .cfi_def_cfa_offset 8
- retq
-.Lfunc_end0:
- .size kohb_exit_, .Lfunc_end0-kohb_exit_
- .cfi_endproc
-
- .type _QQclX28412C493029, at object
- .section .rodata._QQclX28412C493029,"aG", at progbits,_QQclX28412C493029,comdat
- .weak _QQclX28412C493029
-_QQclX28412C493029:
- .ascii "(A,I0)"
- .size _QQclX28412C493029, 6
-
- .type _QQclX9022f1477d515e3e3f2d41fd0f2d14e2, at object
- .section .rodata._QQclX9022f1477d515e3e3f2d41fd0f2d14e2,"aG", at progbits,_QQclX9022f1477d515e3e3f2d41fd0f2d14e2,comdat
- .weak _QQclX9022f1477d515e3e3f2d41fd0f2d14e2
- .p2align 4, 0x0
-_QQclX9022f1477d515e3e3f2d41fd0f2d14e2:
- .asciz "/home/eepshteyn/eugene-tasks/gh-issue-dump/170591/repro-main.f90"
- .size _QQclX9022f1477d515e3e3f2d41fd0f2d14e2, 65
-
- .type _QQclX4B4F48622023, at object
- .section .rodata._QQclX4B4F48622023,"aG", at progbits,_QQclX4B4F48622023,comdat
- .weak _QQclX4B4F48622023
-_QQclX4B4F48622023:
- .ascii "KOHb #"
- .size _QQclX4B4F48622023, 6
-
- .ident "flang version 22.0.0 (https://github.com/eugeneepshteyn/llvm-project.git e74b425ddcac22ccc4d0bd5d65f95ffc2682b62f)"
- .section ".note.GNU-stack","", at progbits
diff --git a/flang/170591/run-main.sh b/flang/170591/run-main.sh
deleted file mode 100755
index 17464db272644..0000000000000
--- a/flang/170591/run-main.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-
-# Get the directory of the script
-SCRIPT_DIR=$(dirname "$(readlink -f "$0")")
-REPRO_DIR="$SCRIPT_DIR"
-
-# Define the flang compiler path
-FLANG_COMPILER="/home/eepshteyn/compilers/flang-upstream/bin/flang"
-
-# Compile the Fortran code with -O3 optimization
-echo "Compiling repro-main.f90 with -O3..."
-"$FLANG_COMPILER" -O3 -S "$REPRO_DIR/repro-main.f90" -o "$REPRO_DIR/repro-main.s"
-
-# Check if compilation was successful
-if [ $? -ne 0 ]; then
- echo "Compilation failed!"
- exit 1
-fi
-
-echo "Assembly generated in repro-main.s"
>From f323ed34ef0131acfe9c20eadf071e34018a8719 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Sun, 7 Dec 2025 23:29:20 -0500
Subject: [PATCH 07/15] fir-opt: link to FortranLower
---
flang/tools/fir-opt/CMakeLists.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/flang/tools/fir-opt/CMakeLists.txt b/flang/tools/fir-opt/CMakeLists.txt
index e735c2c2ff1a3..11e2ccca77bfa 100644
--- a/flang/tools/fir-opt/CMakeLists.txt
+++ b/flang/tools/fir-opt/CMakeLists.txt
@@ -28,6 +28,7 @@ target_link_libraries(fir-opt PRIVATE
FlangOpenMPTransforms
FIRAnalysis
MIFDialect
+ FortranLower
${test_libs}
)
>From 488474b18168579a518084e64345671746f77081 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 8 Dec 2025 11:39:30 -0500
Subject: [PATCH 08/15] Use fully qualified Fortran::lower::genUnreachable()
---
flang/lib/Lower/Runtime.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp
index 4254e25e3d85d..c8d19743cda26 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -125,7 +125,7 @@ void Fortran::lower::genStopStatement(
!currentBlock->back().hasTrait<mlir::OpTrait::IsTerminator>();
};
if (blockIsUnterminated())
- genUnreachable(builder, loc);
+ Fortran::lower::genUnreachable(builder, loc);
}
void Fortran::lower::genFailImageStatement(
@@ -135,7 +135,7 @@ void Fortran::lower::genFailImageStatement(
mlir::func::FuncOp callee =
fir::runtime::getRuntimeFunc<mkRTKey(FailImageStatement)>(loc, builder);
fir::CallOp::create(builder, loc, callee, mlir::ValueRange{});
- genUnreachable(builder, loc);
+ Fortran::lower::genUnreachable(builder, loc);
}
void Fortran::lower::genNotifyWaitStatement(
>From dad3fbb378804f6c6b0cf2447d844041e3f0675c Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 8 Dec 2025 22:15:34 -0500
Subject: [PATCH 09/15] Undid changes to tools CMakeLists.txt files
---
flang/tools/fir-opt/CMakeLists.txt | 1 -
flang/tools/tco/CMakeLists.txt | 1 -
2 files changed, 2 deletions(-)
diff --git a/flang/tools/fir-opt/CMakeLists.txt b/flang/tools/fir-opt/CMakeLists.txt
index 11e2ccca77bfa..e735c2c2ff1a3 100644
--- a/flang/tools/fir-opt/CMakeLists.txt
+++ b/flang/tools/fir-opt/CMakeLists.txt
@@ -28,7 +28,6 @@ target_link_libraries(fir-opt PRIVATE
FlangOpenMPTransforms
FIRAnalysis
MIFDialect
- FortranLower
${test_libs}
)
diff --git a/flang/tools/tco/CMakeLists.txt b/flang/tools/tco/CMakeLists.txt
index 9f1227f803b60..5ab8952898a6c 100644
--- a/flang/tools/tco/CMakeLists.txt
+++ b/flang/tools/tco/CMakeLists.txt
@@ -23,7 +23,6 @@ target_link_libraries(tco PRIVATE
FIROpenMPSupport
FlangOpenMPTransforms
FortranSupport
- FortranLower
MIFDialect
)
>From a75f16149fbf41b1b87b6394de9e37fac152cb9c Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Mon, 8 Dec 2025 22:30:04 -0500
Subject: [PATCH 10/15] Added documentation for ABORT extension
---
flang/docs/Intrinsics.md | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md
index ec26031da382b..3c32f443becdf 100644
--- a/flang/docs/Intrinsics.md
+++ b/flang/docs/Intrinsics.md
@@ -981,6 +981,25 @@ program test_etime
end program test_etime
```
+### Non-Standard Intrinsics: ABORT
+
+#### Description
+`ABORT()` terminates the program execution. If backtrace support is available, prints a backtrace.
+
+#### Usage and Info
+
+- **Standard:** GNU extension
+- **Class:** Subroutine
+- **Syntax:** `CALL ABORT()`
+
+#### Example
+```Fortran
+program call_abort
+ print *, "Aborting..."
+ call abort()
+end
+```
+
### Non-Standard Intrinsics: EXIT
#### Description
>From 7efe0bb01f61e16206d9cd8f5bc7076ff7ac0917 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Tue, 9 Dec 2025 22:44:14 -0500
Subject: [PATCH 11/15] Cloned genUnreachable() and modified it to avoid
dependencies issue
---
flang/include/flang/Lower/Runtime.h | 1 -
flang/lib/Lower/Runtime.cpp | 8 +++----
flang/lib/Optimizer/Builder/Runtime/Stop.cpp | 23 ++++++++++++++++++--
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/flang/include/flang/Lower/Runtime.h b/flang/include/flang/Lower/Runtime.h
index bfc8a87a75880..204093f9a766a 100644
--- a/flang/include/flang/Lower/Runtime.h
+++ b/flang/include/flang/Lower/Runtime.h
@@ -68,7 +68,6 @@ 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 c8d19743cda26..bee9178dcc643 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -34,8 +34,8 @@ 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.
-void Fortran::lower::genUnreachable(fir::FirOpBuilder &builder,
- mlir::Location loc) {
+static void genUnreachable(fir::FirOpBuilder &builder,
+ mlir::Location loc) {
mlir::Block *curBlock = builder.getBlock();
mlir::Operation *parentOp = curBlock->getParentOp();
if (parentOp->getDialect()->getNamespace() ==
@@ -125,7 +125,7 @@ void Fortran::lower::genStopStatement(
!currentBlock->back().hasTrait<mlir::OpTrait::IsTerminator>();
};
if (blockIsUnterminated())
- Fortran::lower::genUnreachable(builder, loc);
+ genUnreachable(builder, loc);
}
void Fortran::lower::genFailImageStatement(
@@ -135,7 +135,7 @@ void Fortran::lower::genFailImageStatement(
mlir::func::FuncOp callee =
fir::runtime::getRuntimeFunc<mkRTKey(FailImageStatement)>(loc, builder);
fir::CallOp::create(builder, loc, callee, mlir::ValueRange{});
- Fortran::lower::genUnreachable(builder, loc);
+ genUnreachable(builder, loc);
}
void Fortran::lower::genNotifyWaitStatement(
diff --git a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
index 094c2a131727c..bf097e8207545 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
@@ -15,6 +15,25 @@
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) {
+ mlir::Block *curBlock = builder.getBlock();
+#if 0
+ mlir::Operation *parentOp = curBlock->getParentOp();
+ if (parentOp->getDialect()->getNamespace() ==
+ mlir::omp::OpenMPDialect::getDialectNamespace())
+ Fortran::lower::genOpenMPTerminator(builder, parentOp, loc);
+ else if (Fortran::lower::isInsideOpenACCComputeConstruct(builder))
+ Fortran::lower::genOpenACCTerminator(builder, parentOp, loc);
+ else
+#endif
+ fir::UnreachableOp::create(builder, loc);
+ mlir::Block *newBlock = curBlock->splitBlock(builder.getInsertionPoint());
+ builder.setInsertionPointToStart(newBlock);
+}
+
void fir::runtime::genExit(fir::FirOpBuilder &builder, mlir::Location loc,
mlir::Value status) {
auto exitFunc = fir::runtime::getRuntimeFunc<mkRTKey(Exit)>(loc, builder);
@@ -22,14 +41,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);
- Fortran::lower::genUnreachable(builder, loc);
+ 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);
+ genUnreachable(builder, loc);
}
void fir::runtime::genReportFatalUserError(fir::FirOpBuilder &builder,
>From a824663f072f231688715a11759ff02dcde7f328 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Tue, 9 Dec 2025 22:49:57 -0500
Subject: [PATCH 12/15] clang-format
---
flang/lib/Lower/Runtime.cpp | 3 +--
flang/lib/Optimizer/Builder/Runtime/Stop.cpp | 5 ++---
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/flang/lib/Lower/Runtime.cpp b/flang/lib/Lower/Runtime.cpp
index bee9178dcc643..5f8586b9c8a88 100644
--- a/flang/lib/Lower/Runtime.cpp
+++ b/flang/lib/Lower/Runtime.cpp
@@ -34,8 +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) {
+static void 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 bf097e8207545..1a1e52eb0f032 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
@@ -17,8 +17,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) {
+static void genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc) {
mlir::Block *curBlock = builder.getBlock();
#if 0
mlir::Operation *parentOp = curBlock->getParentOp();
@@ -29,7 +28,7 @@ static void genUnreachable(fir::FirOpBuilder &builder,
Fortran::lower::genOpenACCTerminator(builder, parentOp, loc);
else
#endif
- fir::UnreachableOp::create(builder, loc);
+ fir::UnreachableOp::create(builder, loc);
mlir::Block *newBlock = curBlock->splitBlock(builder.getInsertionPoint());
builder.setInsertionPointToStart(newBlock);
}
>From 85547e3d8452367395b1ccea5f2ff85e8945b64c Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Tue, 9 Dec 2025 22:58:46 -0500
Subject: [PATCH 13/15] Fix(flang): Fix abort intrinsic LIT test
The LIT test was failing because it expected a
statement after , which is no longer generated.
This commit removes the line from the test
to align it with the current FIR output, where
implies no further execution.
---
flang/test/Lower/Intrinsics/abort.f90 | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/flang/test/Lower/Intrinsics/abort.f90 b/flang/test/Lower/Intrinsics/abort.f90
index 1b51708cbf7e7..27f9e4d774099 100644
--- a/flang/test/Lower/Intrinsics/abort.f90
+++ b/flang/test/Lower/Intrinsics/abort.f90
@@ -2,8 +2,8 @@
! CHECK-LABEL: func.func @_QPabort_test() {
! CHECK: fir.call @_FortranAAbort() {{.*}}: () -> ()
-! CHECK: return
-! CHECK: }
+! CHECK-NEXT: fir.unreachable
+
subroutine abort_test()
call abort
>From 0b4fae9fd2d9fe67649577fdcc320be26e3622e9 Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Tue, 9 Dec 2025 23:18:27 -0500
Subject: [PATCH 14/15] Fixed abort.f90 test again
---
flang/test/Lower/Intrinsics/abort.f90 | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/flang/test/Lower/Intrinsics/abort.f90 b/flang/test/Lower/Intrinsics/abort.f90
index 27f9e4d774099..213a310f9a41f 100644
--- a/flang/test/Lower/Intrinsics/abort.f90
+++ b/flang/test/Lower/Intrinsics/abort.f90
@@ -1,9 +1,10 @@
-! RUN: bbc -emit-fir %s -o - | FileCheck %s
+! RUN: %flang_fc1 -emit-fir %s -o - | FileCheck %s
! CHECK-LABEL: func.func @_QPabort_test() {
! CHECK: fir.call @_FortranAAbort() {{.*}}: () -> ()
! CHECK-NEXT: fir.unreachable
-
+! CHECK-NEXT: }
+! CHECK: func.func private @_FortranAAbort{{.*}} attributes {{.*}}noreturn
subroutine abort_test()
call abort
>From e8812d401291a1c1baa5d9eaafcc60d8733c6ded Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Tue, 9 Dec 2025 23:19:00 -0500
Subject: [PATCH 15/15] Add 'noreturn' to Abort
---
flang/lib/Optimizer/Builder/Runtime/Stop.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
index 1a1e52eb0f032..004753cc06050 100644
--- a/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
+++ b/flang/lib/Optimizer/Builder/Runtime/Stop.cpp
@@ -20,6 +20,10 @@ using namespace Fortran::runtime;
static void genUnreachable(fir::FirOpBuilder &builder, mlir::Location loc) {
mlir::Block *curBlock = builder.getBlock();
#if 0
+ // TODO: using FortranLower functionality from from FIRBuilder
+ // results in linking issues with multiple tools. It seems that
+ // FIRBuilder is a dependency of FortranLower, not the other way
+ // around.
mlir::Operation *parentOp = curBlock->getParentOp();
if (parentOp->getDialect()->getNamespace() ==
mlir::omp::OpenMPDialect::getDialectNamespace())
@@ -46,6 +50,7 @@ void fir::runtime::genExit(fir::FirOpBuilder &builder, mlir::Location loc,
void fir::runtime::genAbort(fir::FirOpBuilder &builder, mlir::Location loc) {
mlir::func::FuncOp abortFunc =
fir::runtime::getRuntimeFunc<mkRTKey(Abort)>(loc, builder);
+ abortFunc->setAttr("noreturn", builder.getUnitAttr());
fir::CallOp::create(builder, loc, abortFunc, mlir::ValueRange{});
genUnreachable(builder, loc);
}
More information about the flang-commits
mailing list