[flang-commits] [PATCH] D133630: [flang] Fix invalid branch optimization

vdonaldson via Phabricator via flang-commits flang-commits at lists.llvm.org
Fri Sep 9 22:04:01 PDT 2022


vdonaldson created this revision.
vdonaldson added a project: Flang.
Herald added subscribers: mehdi_amini, jdoerfert.
Herald added a project: All.
vdonaldson requested review of this revision.

Branch optimization in function rewriteIfGotos attempts to rewrite code
such as

  <<IfConstruct>>
    1 If[Then]Stmt: if(cond) goto L
    2 GotoStmt: goto L
    3 EndIfStmt
  <<End IfConstruct>>
  4 Statement: ...
  5 Statement: ...
  6 Statement: L ...

to eliminate a branch and a trivial basic block to get:

  <<IfConstruct>>
    1 If[Then]Stmt [negate]: if(cond) goto L
    4 Statement: ...
    5 Statement: ...
    3 EndIfStmt
  <<End IfConstruct>>
  6 Statement: L ...

Among other requirements, this is invalid if any statement between the
GOTO and its target is an intermediate construct statement such as a
CASE or ELSE IF statement, like the CASE DEFAULT statement in:

    select case(i)
    case (:2)
      n = i * 10
    case (5:)
      n = i * 1000
      if (i <= 6) goto 9 ! exit over 'case default'; may not be rewritten
      n = i * 10000
    case default
      n = i * 100
  9 end select


https://reviews.llvm.org/D133630

Files:
  flang/lib/Lower/PFTBuilder.cpp
  flang/test/Lower/select-case-statement.f90


Index: flang/test/Lower/select-case-statement.f90
===================================================================
--- flang/test/Lower/select-case-statement.f90
+++ flang/test/Lower/select-case-statement.f90
@@ -252,7 +252,6 @@
     print*, n
   end subroutine
 
-
   ! CHECK-LABEL: func @_QPscharacter2
   subroutine scharacter2(s)
     ! CHECK-DAG: %[[V_0:[0-9]+]] = fir.alloca !fir.box<!fir.heap<!fir.char<1,?>>>
@@ -337,6 +336,47 @@
     ! CHECK:   return
   end subroutine
 
+  ! CHECK-LABEL: func @_QPsgoto
+  ! select case with goto exit
+  subroutine sgoto
+    n = 0
+    do i=1,8
+      ! CHECK:   %[[i:[0-9]+]] = fir.alloca {{.*}} "_QFsgotoEi"
+      ! CHECK: ^bb2:  // pred: ^bb1
+      ! CHECK:   %[[selector:[0-9]+]] = fir.load %[[i]] : !fir.ref<i32>
+      ! CHECK:   fir.select_case %[[selector]] : i32 [#fir.upper, %c2{{.*}}, ^bb3, #fir.lower, %c5{{.*}}, ^bb4, unit, ^bb7]
+      ! CHECK: ^bb3:  // pred: ^bb2
+      ! CHECK:   arith.muli %c10{{[^0]}}
+      ! CHECK:   br ^bb9
+      ! CHECK: ^bb4:  // pred: ^bb2
+      ! CHECK:   arith.muli %c1000{{[^0]}}
+      ! CHECK:   cond_br {{.*}}, ^bb5, ^bb6
+      ! CHECK: ^bb5:  // pred: ^bb4
+      ! CHECK:   br ^bb8
+      ! CHECK: ^bb6:  // pred: ^bb4
+      ! CHECK:   arith.muli %c10000{{[^0]}}
+      ! CHECK:   br ^bb9
+      ! CHECK: ^bb7:  // pred: ^bb2
+      ! CHECK:   arith.muli %c100{{[^0]}}
+      ! CHECK:   br ^bb8
+      ! CHECK: ^bb8:  // 2 preds: ^bb5, ^bb7
+      ! CHECK:   br ^bb9
+      ! CHECK: ^bb9:  // 3 preds: ^bb3, ^bb6, ^bb8
+      ! CHECK:   fir.call @_FortranAioBeginExternalListOutput
+      select case(i)
+      case (:2)
+        n = i * 10
+      case (5:)
+        n = i * 1000
+        if (i <= 6) goto 9
+        n = i * 10000
+      case default
+        n = i * 100
+  9   end select
+      print*, n
+    enddo
+    ! CHECK:   return
+  end
 
   ! CHECK-LABEL: func @_QPswhere
   subroutine swhere(num)
@@ -453,6 +493,9 @@
     call sempty(3)            ! expected output: 3 i:case default; 3 c:case default
 
     print*
+    call sgoto                ! expected output:  10 20 300 400 5000 6000 70000 80000 
+
+    print*
     call swhere(1)            ! expected output: 42.
     call sforall(1)           ! expected output: 42.
   end
Index: flang/lib/Lower/PFTBuilder.cpp
===================================================================
--- flang/lib/Lower/PFTBuilder.cpp
+++ flang/lib/Lower/PFTBuilder.cpp
@@ -503,7 +503,7 @@
     for (auto it = evaluationList.begin(), end = evaluationList.end();
          it != end; ++it) {
       auto &eval = *it;
-      if (eval.isA<parser::EntryStmt>()) {
+      if (eval.isA<parser::EntryStmt>() || eval.isIntermediateConstructStmt()) {
         ifCandidateStack.clear();
         continue;
       }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D133630.459251.patch
Type: text/x-patch
Size: 2764 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/flang-commits/attachments/20220910/40fe85a4/attachment.bin>


More information about the flang-commits mailing list