[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