Skip to content

Commit 85b89ed

Browse files
clementvalvdonaldsonschweitzpgijeanPerier
committed
[flang] Lower simple RETURN statement
This patch adds the lowering for the RETURN statement without alternate returns in the main program or in subroutine and functions. This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: kiranchandramohan Differential Revision: https://reviews.llvm.org/D119429 Co-authored-by: V Donaldson <[email protected]> Co-authored-by: Eric Schweitz <[email protected]> Co-authored-by: Jean Perier <[email protected]>
1 parent 2d4dc1c commit 85b89ed

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

flang/lib/Lower/Bridge.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,13 @@ class FirConverter : public Fortran::lower::AbstractConverter {
337337

338338
void genFIRProcedureExit(Fortran::lower::pft::FunctionLikeUnit &funit,
339339
const Fortran::semantics::Symbol &symbol) {
340+
if (mlir::Block *finalBlock = funit.finalBlock) {
341+
// The current block must end with a terminator.
342+
if (blockIsUnterminated())
343+
builder->create<mlir::cf::BranchOp>(toLocation(), finalBlock);
344+
// Set insertion point to final block.
345+
builder->setInsertionPoint(finalBlock, finalBlock->end());
346+
}
340347
if (Fortran::semantics::IsFunction(symbol)) {
341348
TODO(toLocation(), "Function lowering");
342349
} else {
@@ -652,7 +659,24 @@ class FirConverter : public Fortran::lower::AbstractConverter {
652659
}
653660

654661
void genFIR(const Fortran::parser::ReturnStmt &stmt) {
655-
TODO(toLocation(), "ReturnStmt lowering");
662+
Fortran::lower::pft::FunctionLikeUnit *funit =
663+
getEval().getOwningProcedure();
664+
assert(funit && "not inside main program, function or subroutine");
665+
if (funit->isMainProgram()) {
666+
genExitRoutine();
667+
return;
668+
}
669+
mlir::Location loc = toLocation();
670+
if (stmt.v) {
671+
TODO(loc, "Alternate return statement");
672+
}
673+
// Branch to the last block of the SUBROUTINE, which has the actual return.
674+
if (!funit->finalBlock) {
675+
mlir::OpBuilder::InsertPoint insPt = builder->saveInsertionPoint();
676+
funit->finalBlock = builder->createBlock(&builder->getRegion());
677+
builder->restoreInsertionPoint(insPt);
678+
}
679+
builder->create<mlir::cf::BranchOp>(loc, funit->finalBlock);
656680
}
657681

658682
void genFIR(const Fortran::parser::CycleStmt &) {
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
! RUN: bbc %s -o "-" -emit-fir | FileCheck %s
2+
3+
program basic
4+
return
5+
end program
6+
7+
! CHECK-LABEL: func @_QQmain() {
8+
! CHECK: return
9+
! CHECK: }
10+
11+
subroutine sub1()
12+
return
13+
end
14+
15+
! CHECK-LABEL: func @_QPsub1() {
16+
! CHECK: cf.br ^bb1
17+
! CHECK: ^bb1: // pred: ^bb0
18+
! CHECK: return
19+
20+
subroutine sub2()
21+
goto 3
22+
2 return
23+
3 goto 2
24+
end
25+
26+
! CHECK-LABEL: func @_QPsub2() {
27+
! CHECK: cf.br ^bb2
28+
! CHECK: ^bb1: // pred: ^bb2
29+
! CHECK: cf.br ^bb3
30+
! CHECK: ^bb2: // pred: ^bb0
31+
! CHECK: cf.br ^bb1
32+
! CHECK: ^bb3: // pred: ^bb1
33+
! CHECK: return
34+

0 commit comments

Comments
 (0)