[flang-commits] [flang] 76134f4 - [flang] Lower entry statement
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Tue Mar 15 14:02:50 PDT 2022
Author: Valentin Clement
Date: 2022-03-15T22:02:41+01:00
New Revision: 76134f4138fcd1ef4fec989db8c050e793ee187d
URL: https://github.com/llvm/llvm-project/commit/76134f4138fcd1ef4fec989db8c050e793ee187d
DIFF: https://github.com/llvm/llvm-project/commit/76134f4138fcd1ef4fec989db8c050e793ee187d.diff
LOG: [flang] Lower entry statement
This patch add the lowering for the entry statement.
This patch is part of the upstreaming effort from fir-dev branch.
Depends on D121697
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D121698
Co-authored-by: V Donaldson <vdonaldson at nvidia.com>
Co-authored-by: Jean Perier <jperier at nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>
Added:
flang/test/Lower/entry-statement.f90
Modified:
flang/lib/Lower/Bridge.cpp
flang/lib/Lower/ConvertExpr.cpp
Removed:
################################################################################
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 900978887c8bb..7493531504b8b 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -835,12 +835,21 @@ class FirConverter : public Fortran::lower::AbstractConverter {
// tags all result variables with one of the largest types to allow
// them to share the same storage. Convert this to the actual type.
if (resultRef.getType() != resultRefType)
- TODO(loc, "Convert to actual type");
+ resultRef = builder->createConvert(loc, resultRefType, resultRef);
return builder->create<fir::LoadOp>(loc, resultRef);
});
builder->create<mlir::func::ReturnOp>(loc, resultVal);
}
+ /// Get the return value of a call to \p symbol, which is a subroutine entry
+ /// point that has alternative return specifiers.
+ const mlir::Value
+ getAltReturnResult(const Fortran::semantics::Symbol &symbol) {
+ assert(Fortran::semantics::HasAlternateReturns(symbol) &&
+ "subroutine does not have alternate returns");
+ return getSymbolAddress(symbol);
+ }
+
void genFIRProcedureExit(Fortran::lower::pft::FunctionLikeUnit &funit,
const Fortran::semantics::Symbol &symbol) {
if (mlir::Block *finalBlock = funit.finalBlock) {
@@ -852,6 +861,10 @@ class FirConverter : public Fortran::lower::AbstractConverter {
}
if (Fortran::semantics::IsFunction(symbol)) {
genReturnSymbol(symbol);
+ } else if (Fortran::semantics::HasAlternateReturns(symbol)) {
+ mlir::Value retval = builder->create<fir::LoadOp>(
+ toLocation(), getAltReturnResult(symbol));
+ builder->create<mlir::func::ReturnOp>(toLocation(), retval);
} else {
genExitRoutine();
}
@@ -2049,10 +2062,7 @@ class FirConverter : public Fortran::lower::AbstractConverter {
void genFIR(const Fortran::parser::EndFunctionStmt &) {} // nop
void genFIR(const Fortran::parser::EndIfStmt &) {} // nop
void genFIR(const Fortran::parser::EndSubroutineStmt &) {} // nop
-
- void genFIR(const Fortran::parser::EntryStmt &) {
- TODO(toLocation(), "EntryStmt lowering");
- }
+ void genFIR(const Fortran::parser::EntryStmt &) {} // nop
void genFIR(const Fortran::parser::IfStmt &) {
TODO(toLocation(), "IfStmt lowering");
diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp
index eafe098e3c949..5a8ba4d1cd799 100644
--- a/flang/lib/Lower/ConvertExpr.cpp
+++ b/flang/lib/Lower/ConvertExpr.cpp
@@ -658,6 +658,19 @@ class ScalarExprLowering {
return createFltCmpOp<OpTy>(pred, left, genval(ex.right()));
}
+ /// Create a call to the runtime to compare two CHARACTER values.
+ /// Precondition: This assumes that the two values have `fir.boxchar` type.
+ mlir::Value createCharCompare(mlir::arith::CmpIPredicate pred,
+ const ExtValue &left, const ExtValue &right) {
+ return fir::runtime::genCharCompare(builder, getLoc(), pred, left, right);
+ }
+
+ template <typename A>
+ mlir::Value createCharCompare(const A &ex, mlir::arith::CmpIPredicate pred) {
+ ExtValue left = genval(ex.left());
+ return createCharCompare(pred, left, genval(ex.right()));
+ }
+
/// Returns a reference to a symbol or its box/boxChar descriptor if it has
/// one.
ExtValue gen(Fortran::semantics::SymbolRef sym) {
@@ -1077,7 +1090,7 @@ class ScalarExprLowering {
template <int KIND>
ExtValue genval(const Fortran::evaluate::Relational<Fortran::evaluate::Type<
Fortran::common::TypeCategory::Character, KIND>> &op) {
- TODO(getLoc(), "genval char comparison");
+ return createCharCompare(op, translateRelational(op.opr));
}
ExtValue
diff --git a/flang/test/Lower/entry-statement.f90 b/flang/test/Lower/entry-statement.f90
new file mode 100644
index 0000000000000..4c83a3b4c63cb
--- /dev/null
+++ b/flang/test/Lower/entry-statement.f90
@@ -0,0 +1,158 @@
+! RUN: bbc -emit-fir -o - %s | FileCheck %s
+
+
+! CHECK-LABEL: func @_QPcompare1(
+! CHECK-SAME: %{{.*}}: !fir.ref<!fir.logical<4>>{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}) {
+subroutine compare1(x, c1, c2)
+ character(*) c1, c2, d1, d2
+ logical x, y
+ x = c1 < c2
+ return
+
+ ! CHECK-LABEL: func @_QPcompare2(
+ ! CHECK-SAME: %{{.*}}: !fir.ref<!fir.logical<4>>{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}) {
+ entry compare2(y, d2, d1)
+ y = d1 < d2
+ end
+
+ program entries
+ character(10) hh, qq, m
+ character(len=4) s1, s2
+ integer mm
+ logical r
+ s1 = 'a111'
+ s2 = 'a222'
+ call compare1(r, s1, s2); print*, r
+ call compare2(r, s1, s2); print*, r
+ call ss(mm); print*, mm
+ call e1(mm, 17); print*, mm
+ call e2(17, mm); print*, mm
+ call e3(mm); print*, mm
+ print*, jj(11)
+ print*, rr(22)
+ m = 'abcd efgh'
+ print*, hh(m)
+ print*, qq(m)
+ call dd1
+ call dd2
+ call dd3(6)
+ 6 continue
+ end
+
+ ! CHECK-LABEL: func @_QPss(
+ ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}) {
+ subroutine ss(n1)
+ ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"}
+ ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"}
+ integer n17, n2
+ nx = 100
+ n1 = nx + 10
+ return
+
+ ! CHECK-LABEL: func @_QPe1(
+ ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}, %{{.*}}: !fir.ref<i32>{{.*}}) {
+ entry e1(n2, n17)
+ ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"}
+ ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"}
+ ny = 200
+ n2 = ny + 20
+ return
+
+ ! CHECK-LABEL: func @_QPe2(
+ ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}, %{{.*}}: !fir.ref<i32>{{.*}}) {
+ entry e2(n3, n1)
+ ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"}
+ ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"}
+
+ ! CHECK-LABEL: func @_QPe3(
+ ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}) {
+ entry e3(n1)
+ ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Enx"}
+ ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Eny"}
+ n1 = 30
+ end
+
+ ! CHECK-LABEL: func @_QPjj(
+ ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}) -> i32
+ function jj(n1)
+ ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Ejj"}
+ jj = 100
+ jj = jj + n1
+ return
+
+ ! CHECK-LABEL: func @_QPrr(
+ ! CHECK-SAME: %{{.*}}: !fir.ref<i32>{{.*}}) -> f32
+ entry rr(n2)
+ ! CHECK: fir.alloca i32 {{{.*}}uniq_name = "{{.*}}Ejj"}
+ rr = 200.0
+ rr = rr + n2
+ end
+
+ ! CHECK-LABEL: func @_QPhh(
+ ! CHECK-SAME: %{{.*}}: !fir.ref<!fir.char<1,10>>{{.*}}, %{{.*}}: index{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}) -> !fir.boxchar<1>
+ function hh(c1)
+ character(10) c1, hh, qq
+ hh = c1
+ return
+ ! CHECK-LABEL: func @_QPqq(
+ ! CHECK-SAME: %{{.*}}: !fir.ref<!fir.char<1,10>>{{.*}}, %{{.*}}: index{{.*}}, %{{.*}}: !fir.boxchar<1>{{.*}}) -> !fir.boxchar<1>
+ entry qq(c1)
+ qq = c1
+ end
+
+ ! CHECK-LABEL: func @_QPchar_array()
+ function char_array()
+ character(10), c(5)
+ ! CHECK-LABEL: func @_QPchar_array_entry(
+ ! CHECK-SAME: %{{.*}}: !fir.boxchar<1>{{.*}}) -> f32 {
+ entry char_array_entry(c)
+ end
+
+ ! CHECK-LABEL: func @_QPdd1()
+ subroutine dd1
+ ! CHECK: %[[kk:[0-9]*]] = fir.alloca i32 {bindc_name = "kk", uniq_name =
+ ! "_QFdd1Ekk"}
+ ! CHECK: br ^bb1
+ ! CHECK: ^bb1: // pred: ^bb0
+ ! CHECK: %[[ten:.*]] = arith.constant 10 : i32
+ ! CHECK: fir.store %[[ten:.*]] to %[[kk]] : !fir.ref<i32>
+ ! CHECK: br ^bb2
+ ! CHECK: ^bb2: // pred: ^bb1
+ ! CHECK: %[[twenty:.*]] = arith.constant 20 : i32
+ ! CHECK: fir.store %[[twenty:.*]] to %[[kk]] : !fir.ref<i32>
+ ! CHECK: br ^bb3
+ ! CHECK: ^bb3: // pred: ^bb2
+ ! CHECK: return
+ kk = 10
+
+ ! CHECK-LABEL: func @_QPdd2()
+ ! CHECK: %[[kk:[0-9]*]] = fir.alloca i32 {bindc_name = "kk", uniq_name =
+ ! "_QFdd1Ekk"}
+ ! CHECK: br ^bb1
+ ! CHECK: ^bb1: // pred: ^bb0
+ ! CHECK: %[[twenty:.*]] = arith.constant 20 : i32
+ ! CHECK: fir.store %[[twenty:.*]] to %[[kk]] : !fir.ref<i32>
+ ! CHECK: br ^bb2
+ ! CHECK: ^bb2: // pred: ^bb1
+ ! CHECK: return
+ entry dd2
+ kk = 20
+ return
+
+ ! CHECK-LABEL: func @_QPdd3
+ ! CHECK: %[[dd3:[0-9]*]] = fir.alloca index {bindc_name = "dd3"}
+ ! CHECK: %[[kk:[0-9]*]] = fir.alloca i32 {bindc_name = "kk", uniq_name =
+ ! "_QFdd1Ekk"}
+ ! CHECK: %[[zero:.*]] = arith.constant 0 : index
+ ! CHECK: fir.store %[[zero:.*]] to %[[dd3]] : !fir.ref<index>
+ ! CHECK: br ^bb1
+ ! CHECK: ^bb1: // pred: ^bb0
+ ! CHECK: %[[thirty:.*]] = arith.constant 30 : i32
+ ! CHECK: fir.store %[[thirty:.*]] to %[[kk:[0-9]*]] : !fir.ref<i32>
+ ! CHECK: br ^bb2
+ ! CHECK: ^bb2: // pred: ^bb1
+ ! CHECK: %[[altret:[0-9]*]] = fir.load %[[dd3]] : !fir.ref<index>
+ ! CHECK: return %[[altret:[0-9]*]] : index
+ entry dd3(*)
+ kk = 30
+ end
More information about the flang-commits
mailing list