[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