[flang-commits] [flang] [flang] legacy branch target (PR #75628)
via flang-commits
flang-commits at lists.llvm.org
Fri Dec 15 09:08:07 PST 2023
https://github.com/vdonaldson created https://github.com/llvm/llvm-project/pull/75628
Branching to an endif statement from outside of the if is nonconformant:
subroutine jump(n)
goto 6
if (n == 3) then
goto 7
6 end if
print *, 'pass'
return
7 print *, 'fail'
end
However, this branch was permitted up to f90. Account for this usage when rewriting if constructs and if statements by suppressing rewriting if the end statement is labeled.
>From a2895a17313b37d85c47f8737da8c624cef90c3a Mon Sep 17 00:00:00 2001
From: V Donaldson <vdonaldson at nvidia.com>
Date: Fri, 15 Dec 2023 09:06:44 -0800
Subject: [PATCH] [flang] legacy branch target
Branching to an endif statement from outside of the if is nonconformant:
subroutine jump(n)
goto 6
if (n == 3) then
goto 7
6 end if
print *, 'pass'
return
7 print *, 'fail'
end
However, this branch was permitted up to f90. Account for this usage when
rewriting if constructs and if statements by suppressing rewriting if the
end statement is labeled.
---
flang/lib/Lower/PFTBuilder.cpp | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp
index 8e224c17edad19..0e32e2c7d96a77 100644
--- a/flang/lib/Lower/PFTBuilder.cpp
+++ b/flang/lib/Lower/PFTBuilder.cpp
@@ -541,15 +541,15 @@ class PFTBuilder {
/// The transformation is only valid for forward branch targets at the same
/// construct nesting level as the IfConstruct. The result must not violate
/// construct nesting requirements or contain an EntryStmt. The result
- /// is subject to normal un/structured code classification analysis. The
- /// result is allowed to violate the F18 Clause 11.1.2.1 prohibition on
- /// transfer of control into the interior of a construct block, as that does
- /// not compromise correct code generation. When two transformation
- /// candidates overlap, at least one must be disallowed. In such cases,
- /// the current heuristic favors simple code generation, which happens to
- /// favor later candidates over earlier candidates. That choice is probably
- /// not significant, but could be changed.
- ///
+ /// is subject to normal un/structured code classification analysis. Except
+ /// for a branch to the EndIfStmt, the result is allowed to violate the F18
+ /// Clause 11.1.2.1 prohibition on transfer of control into the interior of
+ /// a construct block, as that does not compromise correct code generation.
+ /// When two transformation candidates overlap, at least one must be
+ /// disallowed. In such cases, the current heuristic favors simple code
+ /// generation, which happens to favor later candidates over earlier
+ /// candidates. That choice is probably not significant, but could be
+ /// changed.
void rewriteIfGotos() {
auto &evaluationList = *evaluationListStack.back();
if (!evaluationList.size())
@@ -616,7 +616,8 @@ class PFTBuilder {
if (eval.isA<parser::IfConstruct>() && eval.evaluationList->size() == 3) {
const auto bodyEval = std::next(eval.evaluationList->begin());
if (const auto *gotoStmt = bodyEval->getIf<parser::GotoStmt>()) {
- ifCandidateStack.push_back({it, gotoStmt->v});
+ if (!bodyEval->lexicalSuccessor->label)
+ ifCandidateStack.push_back({it, gotoStmt->v});
} else if (doStmt) {
if (const auto *cycleStmt = bodyEval->getIf<parser::CycleStmt>()) {
std::string cycleName = getConstructName(*cycleStmt);
More information about the flang-commits
mailing list