[flang-commits] [flang] a3c05df - [flang] Fix invalid branch optimization
V Donaldson via flang-commits
flang-commits at lists.llvm.org
Sun Sep 11 19:38:10 PDT 2022
Author: V Donaldson
Date: 2022-09-11T19:37:32-07:00
New Revision: a3c05df16bc66d8ac84c1b10a74f59b12eb25a94
URL: https://github.com/llvm/llvm-project/commit/a3c05df16bc66d8ac84c1b10a74f59b12eb25a94
DIFF: https://github.com/llvm/llvm-project/commit/a3c05df16bc66d8ac84c1b10a74f59b12eb25a94.diff
LOG: [flang] Fix invalid branch optimization
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
Added:
Modified:
flang/lib/Lower/PFTBuilder.cpp
flang/test/Lower/select-case-statement.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/PFTBuilder.cpp b/flang/lib/Lower/PFTBuilder.cpp
index 16cfde1e02145..59a9b2cdcb67c 100644
--- a/flang/lib/Lower/PFTBuilder.cpp
+++ b/flang/lib/Lower/PFTBuilder.cpp
@@ -503,7 +503,7 @@ class PFTBuilder {
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;
}
diff --git a/flang/test/Lower/select-case-statement.f90 b/flang/test/Lower/select-case-statement.f90
index 5eaff33dc89d0..d62e9e2d05f4d 100644
--- a/flang/test/Lower/select-case-statement.f90
+++ b/flang/test/Lower/select-case-statement.f90
@@ -252,7 +252,6 @@ subroutine scharacter1(s)
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 @@ subroutine sempty(n)
! 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)
@@ -452,6 +492,9 @@ program p
call sempty(2) ! no output
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.
More information about the flang-commits
mailing list