[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