[flang-commits] [flang] 991a90a - [flang] Lower evaluate::Extremum
Jean Perier via flang-commits
flang-commits at lists.llvm.org
Fri Dec 2 00:30:12 PST 2022
Author: Jean Perier
Date: 2022-12-02T09:29:39+01:00
New Revision: 991a90a00d571cfe3ed3da3f2ad766d4afce6c2b
URL: https://github.com/llvm/llvm-project/commit/991a90a00d571cfe3ed3da3f2ad766d4afce6c2b
DIFF: https://github.com/llvm/llvm-project/commit/991a90a00d571cfe3ed3da3f2ad766d4afce6c2b.diff
LOG: [flang] Lower evaluate::Extremum
Update BinaryOp<T>::gen so that const T& is threaded and some
operation knowledge that is not encoded by the type T or the arguments
can be used. For Extremum, it is the order (Greater or Lesser) that is
required, but this will also be required for evaluate::Relational.
Differential Revision: https://reviews.llvm.org/D139124
Added:
Modified:
flang/lib/Lower/ConvertExprToHLFIR.cpp
flang/test/Lower/HLFIR/binary-ops.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index a8860f639f609..284b1cc7ea674 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -252,7 +252,7 @@ class HlfirDesignatorBuilder {
template <typename T>
struct BinaryOp {
static hlfir::EntityWithAttributes gen(mlir::Location loc,
- fir::FirOpBuilder &builder,
+ fir::FirOpBuilder &builder, const T &,
hlfir::Entity lhs, hlfir::Entity rhs) {
TODO(loc, "binary op implementation in HLFIR");
}
@@ -263,9 +263,11 @@ struct BinaryOp {
template <int KIND> \
struct BinaryOp<Fortran::evaluate::GenBinEvOp<Fortran::evaluate::Type< \
Fortran::common::TypeCategory::GenBinTyCat, KIND>>> { \
+ using Op = Fortran::evaluate::GenBinEvOp<Fortran::evaluate::Type< \
+ Fortran::common::TypeCategory::GenBinTyCat, KIND>>; \
static hlfir::EntityWithAttributes gen(mlir::Location loc, \
fir::FirOpBuilder &builder, \
- hlfir::Entity lhs, \
+ const Op &, hlfir::Entity lhs, \
hlfir::Entity rhs) { \
return hlfir::EntityWithAttributes{ \
builder.create<GenBinFirOp>(loc, lhs, rhs)}; \
@@ -287,9 +289,11 @@ GENBIN(Divide, Complex, fir::DivcOp)
template <Fortran::common::TypeCategory TC, int KIND>
struct BinaryOp<Fortran::evaluate::Power<Fortran::evaluate::Type<TC, KIND>>> {
+ using Op = Fortran::evaluate::Power<Fortran::evaluate::Type<TC, KIND>>;
static hlfir::EntityWithAttributes gen(mlir::Location loc,
fir::FirOpBuilder &builder,
- hlfir::Entity lhs, hlfir::Entity rhs) {
+ const Op &op, hlfir::Entity lhs,
+ hlfir::Entity rhs) {
mlir::Type ty = Fortran::lower::getFIRType(builder.getContext(), TC, KIND,
/*params=*/llvm::None);
return hlfir::EntityWithAttributes{
@@ -300,9 +304,12 @@ struct BinaryOp<Fortran::evaluate::Power<Fortran::evaluate::Type<TC, KIND>>> {
template <Fortran::common::TypeCategory TC, int KIND>
struct BinaryOp<
Fortran::evaluate::RealToIntPower<Fortran::evaluate::Type<TC, KIND>>> {
+ using Op =
+ Fortran::evaluate::RealToIntPower<Fortran::evaluate::Type<TC, KIND>>;
static hlfir::EntityWithAttributes gen(mlir::Location loc,
fir::FirOpBuilder &builder,
- hlfir::Entity lhs, hlfir::Entity rhs) {
+ const Op &op, hlfir::Entity lhs,
+ hlfir::Entity rhs) {
mlir::Type ty = Fortran::lower::getFIRType(builder.getContext(), TC, KIND,
/*params=*/llvm::None);
return hlfir::EntityWithAttributes{
@@ -310,6 +317,30 @@ struct BinaryOp<
}
};
+template <Fortran::common::TypeCategory TC, int KIND>
+struct BinaryOp<
+ Fortran::evaluate::Extremum<Fortran::evaluate::Type<TC, KIND>>> {
+ using Op = Fortran::evaluate::Extremum<Fortran::evaluate::Type<TC, KIND>>;
+ static hlfir::EntityWithAttributes gen(mlir::Location loc,
+ fir::FirOpBuilder &builder,
+ const Op &op, hlfir::Entity lhs,
+ hlfir::Entity rhs) {
+ // evaluate::Extremum is only created by the front-end when building
+ // compiler generated expressions (like when folding LEN() or shape/bounds
+ // inquiries). MIN and MAX are represented as evaluate::ProcedureRef and are
+ // not going through here. So far the frontend does not generate character
+ // Extremum so there is no way to test it.
+ if constexpr (TC == Fortran::common::TypeCategory::Character) {
+ fir::emitFatalError(loc, "Fortran::evaluate::Extremum are unexpected");
+ }
+ llvm::SmallVector<mlir::Value, 2> args{lhs, rhs};
+ fir::ExtendedValue res = op.ordering == Fortran::evaluate::Ordering::Greater
+ ? Fortran::lower::genMax(builder, loc, args)
+ : Fortran::lower::genMin(builder, loc, args);
+ return hlfir::EntityWithAttributes{fir::getBase(res)};
+ }
+};
+
/// Lower Expr to HLFIR.
class HlfirBuilder {
public:
@@ -411,7 +442,7 @@ class HlfirBuilder {
TODO(loc, "elemental operations in HLFIR");
auto left = hlfir::loadTrivialScalar(loc, builder, gen(op.left()));
auto right = hlfir::loadTrivialScalar(loc, builder, gen(op.right()));
- return BinaryOp<D>::gen(loc, builder, left, right);
+ return BinaryOp<D>::gen(loc, builder, op.derived(), left, right);
}
template <int KIND>
diff --git a/flang/test/Lower/HLFIR/binary-ops.f90 b/flang/test/Lower/HLFIR/binary-ops.f90
index 0c3abbc554a01..678cd23bf5615 100644
--- a/flang/test/Lower/HLFIR/binary-ops.f90
+++ b/flang/test/Lower/HLFIR/binary-ops.f90
@@ -193,3 +193,17 @@ subroutine complex_to_int_power(x, y, z)
! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
! CHECK: %[[VAL_8:.*]] = fir.call @_FortranAcpowi(%[[VAL_6]], %[[VAL_7]]) fastmath<contract> : (!fir.complex<4>, i32) -> !fir.complex<4>
+
+subroutine extremum(c, n, l)
+ integer(8), intent(in) :: l
+ integer(8) :: n
+ character(l) :: c
+ ! evaluate::Extremum is created by semantics while analyzing LEN().
+ n = len(c, 8)
+end subroutine
+! CHECK-LABEL: func.func @_QPextremum(
+! CHECK: hlfir.declare {{.*}}c
+! CHECK: %[[VAL_11:.*]] = arith.constant 0 : i64
+! CHECK: %[[VAL_12:.*]] = fir.load %{{.*}} : !fir.ref<i64>
+! CHECK: %[[VAL_13:.*]] = arith.cmpi sgt, %[[VAL_11]], %[[VAL_12]] : i64
+! CHECK: arith.select %[[VAL_13]], %[[VAL_11]], %[[VAL_12]] : i64
More information about the flang-commits
mailing list