[flang-commits] [flang] f1dcf3a - [flang] Lower integer comparison operation
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Fri Feb 25 12:01:36 PST 2022
Author: Valentin Clement
Date: 2022-02-25T21:01:27+01:00
New Revision: f1dcf3ae92d0e12a89fef77f0cfb1e974c98f7c5
URL: https://github.com/llvm/llvm-project/commit/f1dcf3ae92d0e12a89fef77f0cfb1e974c98f7c5
DIFF: https://github.com/llvm/llvm-project/commit/f1dcf3ae92d0e12a89fef77f0cfb1e974c98f7c5.diff
LOG: [flang] Lower integer comparison operation
This patch handles the lowering of comprison
operator between integers.
The comparison is lowered to a `arith.cmpi` operation.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: PeteSteinfeld, schweitz, rovka
Differential Revision: https://reviews.llvm.org/D120559
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>
Co-authored-by: Jean Perier <jperier at nvidia.com>
Added:
flang/test/Lower/integer-operations.f90
Modified:
flang/lib/Lower/ConvertExpr.cpp
Removed:
################################################################################
diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp
index 93deacea6713..ff5ae1318a3f 100644
--- a/flang/lib/Lower/ConvertExpr.cpp
+++ b/flang/lib/Lower/ConvertExpr.cpp
@@ -109,6 +109,27 @@ enum class ConstituentSemantics {
RefOpaque
};
+/// Convert parser's INTEGER relational operators to MLIR. TODO: using
+/// unordered, but we may want to cons ordered in certain situation.
+static mlir::arith::CmpIPredicate
+translateRelational(Fortran::common::RelationalOperator rop) {
+ switch (rop) {
+ case Fortran::common::RelationalOperator::LT:
+ return mlir::arith::CmpIPredicate::slt;
+ case Fortran::common::RelationalOperator::LE:
+ return mlir::arith::CmpIPredicate::sle;
+ case Fortran::common::RelationalOperator::EQ:
+ return mlir::arith::CmpIPredicate::eq;
+ case Fortran::common::RelationalOperator::NE:
+ return mlir::arith::CmpIPredicate::ne;
+ case Fortran::common::RelationalOperator::GT:
+ return mlir::arith::CmpIPredicate::sgt;
+ case Fortran::common::RelationalOperator::GE:
+ return mlir::arith::CmpIPredicate::sge;
+ }
+ llvm_unreachable("unhandled INTEGER relational operator");
+}
+
/// Place \p exv in memory if it is not already a memory reference. If
/// \p forceValueType is provided, the value is first casted to the provided
/// type before being stored (this is mainly intended for logicals whose value
@@ -338,6 +359,20 @@ class ScalarExprLowering {
return builder.createRealConstant(getLoc(), fltTy, value);
}
+ template <typename OpTy>
+ mlir::Value createCompareOp(mlir::arith::CmpIPredicate pred,
+ const ExtValue &left, const ExtValue &right) {
+ if (const fir::UnboxedValue *lhs = left.getUnboxed())
+ if (const fir::UnboxedValue *rhs = right.getUnboxed())
+ return builder.create<OpTy>(getLoc(), pred, *lhs, *rhs);
+ fir::emitFatalError(getLoc(), "array compare should be handled in genarr");
+ }
+ template <typename OpTy, typename A>
+ mlir::Value createCompareOp(const A &ex, mlir::arith::CmpIPredicate pred) {
+ ExtValue left = genval(ex.left());
+ return createCompareOp<OpTy>(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) {
@@ -494,7 +529,8 @@ class ScalarExprLowering {
template <int KIND>
ExtValue genval(const Fortran::evaluate::Relational<Fortran::evaluate::Type<
Fortran::common::TypeCategory::Integer, KIND>> &op) {
- TODO(getLoc(), "genval integer comparison");
+ return createCompareOp<mlir::arith::CmpIOp>(op,
+ translateRelational(op.opr));
}
template <int KIND>
ExtValue genval(const Fortran::evaluate::Relational<Fortran::evaluate::Type<
@@ -514,7 +550,7 @@ class ScalarExprLowering {
ExtValue
genval(const Fortran::evaluate::Relational<Fortran::evaluate::SomeType> &op) {
- TODO(getLoc(), "genval comparison");
+ return std::visit([&](const auto &x) { return genval(x); }, op.u);
}
template <Fortran::common::TypeCategory TC1, int KIND,
diff --git a/flang/test/Lower/integer-operations.f90 b/flang/test/Lower/integer-operations.f90
new file mode 100644
index 000000000000..76ec658695a7
--- /dev/null
+++ b/flang/test/Lower/integer-operations.f90
@@ -0,0 +1,109 @@
+! RUN: bbc %s -o "-" | FileCheck %s
+
+! Test integer intrinsic operation lowering to fir.
+
+! CHECK-LABEL:eq0_test
+LOGICAL FUNCTION eq0_test(x0, x1)
+INTEGER(4) :: x0
+INTEGER(4) :: x1
+! CHECK-DAG:[[reg1:%[0-9]+]] = fir.load %arg0
+! CHECK-DAG:[[reg2:%[0-9]+]] = fir.load %arg1
+! CHECK:[[reg3:%[0-9]+]] = arith.cmpi eq, [[reg1]], [[reg2]] : i32
+! CHECK:fir.convert [[reg3]] {{.*}} -> !fir.logical<4>
+eq0_test = x0 .EQ. x1
+END FUNCTION
+
+! CHECK-LABEL:ne1_test
+LOGICAL FUNCTION ne1_test(x0, x1)
+INTEGER(4) :: x0
+INTEGER(4) :: x1
+! CHECK-DAG:[[reg1:%[0-9]+]] = fir.load %arg0
+! CHECK-DAG:[[reg2:%[0-9]+]] = fir.load %arg1
+! CHECK:[[reg3:%[0-9]+]] = arith.cmpi ne, [[reg1]], [[reg2]] : i32
+! CHECK:fir.convert [[reg3]] {{.*}} -> !fir.logical<4>
+ne1_test = x0 .NE. x1
+END FUNCTION
+
+! CHECK-LABEL:lt2_test
+LOGICAL FUNCTION lt2_test(x0, x1)
+INTEGER(4) :: x0
+INTEGER(4) :: x1
+! CHECK-DAG:[[reg1:%[0-9]+]] = fir.load %arg0
+! CHECK-DAG:[[reg2:%[0-9]+]] = fir.load %arg1
+! CHECK:[[reg3:%[0-9]+]] = arith.cmpi slt, [[reg1]], [[reg2]] : i32
+! CHECK:fir.convert [[reg3]] {{.*}} -> !fir.logical<4>
+lt2_test = x0 .LT. x1
+END FUNCTION
+
+! CHECK-LABEL:le3_test
+LOGICAL FUNCTION le3_test(x0, x1)
+INTEGER(4) :: x0
+INTEGER(4) :: x1
+! CHECK-DAG:[[reg1:%[0-9]+]] = fir.load %arg0
+! CHECK-DAG:[[reg2:%[0-9]+]] = fir.load %arg1
+! CHECK:[[reg3:%[0-9]+]] = arith.cmpi sle, [[reg1]], [[reg2]] : i32
+! CHECK:fir.convert [[reg3]] {{.*}} -> !fir.logical<4>
+le3_test = x0 .LE. x1
+END FUNCTION
+
+! CHECK-LABEL:gt4_test
+LOGICAL FUNCTION gt4_test(x0, x1)
+INTEGER(4) :: x0
+INTEGER(4) :: x1
+! CHECK-DAG:[[reg1:%[0-9]+]] = fir.load %arg0
+! CHECK-DAG:[[reg2:%[0-9]+]] = fir.load %arg1
+! CHECK:[[reg3:%[0-9]+]] = arith.cmpi sgt, [[reg1]], [[reg2]] : i32
+! CHECK:fir.convert [[reg3]] {{.*}} -> !fir.logical<4>
+gt4_test = x0 .GT. x1
+END FUNCTION
+
+! CHECK-LABEL:ge5_test
+LOGICAL FUNCTION ge5_test(x0, x1)
+INTEGER(4) :: x0
+INTEGER(4) :: x1
+! CHECK-DAG:[[reg1:%[0-9]+]] = fir.load %arg0
+! CHECK-DAG:[[reg2:%[0-9]+]] = fir.load %arg1
+! CHECK:[[reg3:%[0-9]+]] = arith.cmpi sge, [[reg1]], [[reg2]] : i32
+! CHECK:fir.convert [[reg3]] {{.*}} -> !fir.logical<4>
+ge5_test = x0 .GE. x1
+END FUNCTION
+
+! CHECK-LABEL:add6_test
+INTEGER(4) FUNCTION add6_test(x0, x1)
+INTEGER(4) :: x0
+INTEGER(4) :: x1
+! CHECK-DAG:[[reg1:%[0-9]+]] = fir.load %arg0
+! CHECK-DAG:[[reg2:%[0-9]+]] = fir.load %arg1
+! CHECK:addi [[reg1]], [[reg2]] : i32
+add6_test = x0 + x1
+END FUNCTION
+
+! CHECK-LABEL:sub7_test
+INTEGER(4) FUNCTION sub7_test(x0, x1)
+INTEGER(4) :: x0
+INTEGER(4) :: x1
+! CHECK-DAG:[[reg1:%[0-9]+]] = fir.load %arg0
+! CHECK-DAG:[[reg2:%[0-9]+]] = fir.load %arg1
+! CHECK:subi [[reg1]], [[reg2]] : i32
+sub7_test = x0 - x1
+END FUNCTION
+
+! CHECK-LABEL:mult8_test
+INTEGER(4) FUNCTION mult8_test(x0, x1)
+INTEGER(4) :: x0
+INTEGER(4) :: x1
+! CHECK-DAG:[[reg1:%[0-9]+]] = fir.load %arg0
+! CHECK-DAG:[[reg2:%[0-9]+]] = fir.load %arg1
+! CHECK:muli [[reg1]], [[reg2]] : i32
+mult8_test = x0 * x1
+END FUNCTION
+
+! CHECK-LABEL:div9_test
+INTEGER(4) FUNCTION div9_test(x0, x1)
+INTEGER(4) :: x0
+INTEGER(4) :: x1
+! CHECK-DAG:[[reg1:%[0-9]+]] = fir.load %arg0
+! CHECK-DAG:[[reg2:%[0-9]+]] = fir.load %arg1
+! CHECK:arith.divsi [[reg1]], [[reg2]] : i32
+div9_test = x0 / x1
+END FUNCTION
More information about the flang-commits
mailing list