[flang-commits] [flang] 440e9ba - [flang] Lower add, mul, div, and sub to HLFIR
Jean Perier via flang-commits
flang-commits at lists.llvm.org
Thu Dec 1 08:40:57 PST 2022
Author: Jean Perier
Date: 2022-12-01T17:39:53+01:00
New Revision: 440e9baa6238dc6a58b694dd99b4c649a1ae7bd9
URL: https://github.com/llvm/llvm-project/commit/440e9baa6238dc6a58b694dd99b4c649a1ae7bd9
DIFF: https://github.com/llvm/llvm-project/commit/440e9baa6238dc6a58b694dd99b4c649a1ae7bd9.diff
LOG: [flang] Lower add, mul, div, and sub to HLFIR
Only lower operations when the operands are scalar for now.
Differential Revision: https://reviews.llvm.org/D139108
Added:
flang/test/Lower/HLFIR/binary-ops.f90
Modified:
flang/lib/Lower/ConvertExprToHLFIR.cpp
Removed:
################################################################################
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 81b4d63889729..d4c6f5358aff5 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -244,6 +244,46 @@ class HlfirDesignatorBuilder {
mlir::Location loc;
};
+//===--------------------------------------------------------------------===//
+// Binary Operation implementation
+//===--------------------------------------------------------------------===//
+
+template <typename T>
+struct BinaryOp {
+ static hlfir::EntityWithAttributes gen(mlir::Location loc,
+ fir::FirOpBuilder &builder,
+ hlfir::Entity lhs, hlfir::Entity rhs) {
+ TODO(loc, "binary op implementation in HLFIR");
+ }
+};
+
+#undef GENBIN
+#define GENBIN(GenBinEvOp, GenBinTyCat, GenBinFirOp) \
+ template <int KIND> \
+ struct BinaryOp<Fortran::evaluate::GenBinEvOp<Fortran::evaluate::Type< \
+ Fortran::common::TypeCategory::GenBinTyCat, KIND>>> { \
+ static hlfir::EntityWithAttributes gen(mlir::Location loc, \
+ fir::FirOpBuilder &builder, \
+ hlfir::Entity lhs, \
+ hlfir::Entity rhs) { \
+ return hlfir::EntityWithAttributes{ \
+ builder.create<GenBinFirOp>(loc, lhs, rhs)}; \
+ } \
+ };
+
+GENBIN(Add, Integer, mlir::arith::AddIOp)
+GENBIN(Add, Real, mlir::arith::AddFOp)
+GENBIN(Add, Complex, fir::AddcOp)
+GENBIN(Subtract, Integer, mlir::arith::SubIOp)
+GENBIN(Subtract, Real, mlir::arith::SubFOp)
+GENBIN(Subtract, Complex, fir::SubcOp)
+GENBIN(Multiply, Integer, mlir::arith::MulIOp)
+GENBIN(Multiply, Real, mlir::arith::MulFOp)
+GENBIN(Multiply, Complex, fir::MulcOp)
+GENBIN(Divide, Integer, mlir::arith::DivSIOp)
+GENBIN(Divide, Real, mlir::arith::DivFOp)
+GENBIN(Divide, Complex, fir::DivcOp)
+
/// Lower Expr to HLFIR.
class HlfirBuilder {
public:
@@ -339,7 +379,13 @@ class HlfirBuilder {
template <typename D, typename R, typename LO, typename RO>
hlfir::EntityWithAttributes
gen(const Fortran::evaluate::Operation<D, R, LO, RO> &op) {
- TODO(getLoc(), "lowering binary op to HLFIR");
+ auto &builder = getBuilder();
+ mlir::Location loc = getLoc();
+ if (op.Rank() != 0)
+ 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);
}
template <int KIND>
diff --git a/flang/test/Lower/HLFIR/binary-ops.f90 b/flang/test/Lower/HLFIR/binary-ops.f90
new file mode 100644
index 0000000000000..79c9ef6a31440
--- /dev/null
+++ b/flang/test/Lower/HLFIR/binary-ops.f90
@@ -0,0 +1,134 @@
+! Test lowering of binary intrinsic operations to HLFIR
+! RUN: bbc -emit-fir -hlfir -o - %s 2>&1 | FileCheck %s
+
+subroutine int_add(x, y, z)
+ integer :: x, y, z
+ x = y + z
+end subroutine
+! CHECK-LABEL: func.func @_QPint_add(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_6]], %[[VAL_7]] : i32
+
+subroutine real_add(x, y, z)
+ real :: x, y, z
+ x = y + z
+end subroutine
+! CHECK-LABEL: func.func @_QPreal_add(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<f32>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
+! CHECK: %[[VAL_8:.*]] = arith.addf %[[VAL_6]], %[[VAL_7]] fastmath<contract> : f32
+
+subroutine complex_add(x, y, z)
+ complex :: x, y, z
+ x = y + z
+end subroutine
+! CHECK-LABEL: func.func @_QPcomplex_add(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: %[[VAL_8:.*]] = fir.addc %[[VAL_6]], %[[VAL_7]] : !fir.complex<4>
+
+subroutine int_sub(x, y, z)
+ integer :: x, y, z
+ x = y - z
+end subroutine
+! CHECK-LABEL: func.func @_QPint_sub(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_8:.*]] = arith.subi %[[VAL_6]], %[[VAL_7]] : i32
+
+subroutine real_sub(x, y, z)
+ real :: x, y, z
+ x = y - z
+end subroutine
+! CHECK-LABEL: func.func @_QPreal_sub(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<f32>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
+! CHECK: %[[VAL_8:.*]] = arith.subf %[[VAL_6]], %[[VAL_7]] fastmath<contract> : f32
+
+subroutine complex_sub(x, y, z)
+ complex :: x, y, z
+ x = y - z
+end subroutine
+! CHECK-LABEL: func.func @_QPcomplex_sub(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: %[[VAL_8:.*]] = fir.subc %[[VAL_6]], %[[VAL_7]] : !fir.complex<4>
+
+subroutine int_mul(x, y, z)
+ integer :: x, y, z
+ x = y * z
+end subroutine
+! CHECK-LABEL: func.func @_QPint_mul(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_8:.*]] = arith.muli %[[VAL_6]], %[[VAL_7]] : i32
+
+subroutine real_mul(x, y, z)
+ real :: x, y, z
+ x = y * z
+end subroutine
+! CHECK-LABEL: func.func @_QPreal_mul(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<f32>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
+! CHECK: %[[VAL_8:.*]] = arith.mulf %[[VAL_6]], %[[VAL_7]] fastmath<contract> : f32
+
+subroutine complex_mul(x, y, z)
+ complex :: x, y, z
+ x = y * z
+end subroutine
+! CHECK-LABEL: func.func @_QPcomplex_mul(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: %[[VAL_8:.*]] = fir.mulc %[[VAL_6]], %[[VAL_7]] : !fir.complex<4>
+
+subroutine int_div(x, y, z)
+ integer :: x, y, z
+ x = y / z
+end subroutine
+! CHECK-LABEL: func.func @_QPint_div(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_8:.*]] = arith.divsi %[[VAL_6]], %[[VAL_7]] : i32
+
+subroutine real_div(x, y, z)
+ real :: x, y, z
+ x = y / z
+end subroutine
+! CHECK-LABEL: func.func @_QPreal_div(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<f32>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<f32>
+! CHECK: %[[VAL_8:.*]] = arith.divf %[[VAL_6]], %[[VAL_7]] fastmath<contract> : f32
+
+subroutine complex_div(x, y, z)
+ complex :: x, y, z
+ x = y / z
+end subroutine
+! CHECK-LABEL: func.func @_QPcomplex_div(
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %{{.*}}y"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %{{.*}}z"} : (!fir.ref<!fir.complex<4>>) -> (!fir.ref<!fir.complex<4>>, !fir.ref<!fir.complex<4>>)
+! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_4]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref<!fir.complex<4>>
+! CHECK: %[[VAL_8:.*]] = fir.divc %[[VAL_6]], %[[VAL_7]] : !fir.complex<4>
More information about the flang-commits
mailing list