[flang-commits] [flang] be3b40c - [flang] Lower basic binary operation for scalars
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Fri Feb 18 06:50:38 PST 2022
Author: Valentin Clement
Date: 2022-02-18T15:50:31+01:00
New Revision: be3b40c059355115a8041f5bd866ad8d99950611
URL: https://github.com/llvm/llvm-project/commit/be3b40c059355115a8041f5bd866ad8d99950611
DIFF: https://github.com/llvm/llvm-project/commit/be3b40c059355115a8041f5bd866ad8d99950611.diff
LOG: [flang] Lower basic binary operation for scalars
Lower simple binary operation (+, -, *, /) for scalars.
This patch is part of the upstreaming effort from fir-dev branch.
Depends on D120058
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D120063
Co-authored-by: Jean Perier <jperier at nvidia.com>
Co-authored-by: Eric Schweitz <eschweitz at nvidia.com>
Added:
Modified:
flang/lib/Lower/ConvertExpr.cpp
flang/test/Lower/assignment.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/ConvertExpr.cpp b/flang/lib/Lower/ConvertExpr.cpp
index 466a74fe031eb..07e5fb8fa1a57 100644
--- a/flang/lib/Lower/ConvertExpr.cpp
+++ b/flang/lib/Lower/ConvertExpr.cpp
@@ -206,12 +206,27 @@ class ScalarExprLowering {
return builder.create<fir::NegcOp>(getLoc(), genunbox(op.left()));
}
+ template <typename OpTy>
+ mlir::Value createBinaryOp(const ExtValue &left, const ExtValue &right) {
+ assert(fir::isUnboxedValue(left) && fir::isUnboxedValue(right));
+ mlir::Value lhs = fir::getBase(left);
+ mlir::Value rhs = fir::getBase(right);
+ assert(lhs.getType() == rhs.getType() && "types must be the same");
+ return builder.create<OpTy>(getLoc(), lhs, rhs);
+ }
+
+ template <typename OpTy, typename A>
+ mlir::Value createBinaryOp(const A &ex) {
+ ExtValue left = genval(ex.left());
+ return createBinaryOp<OpTy>(left, genval(ex.right()));
+ }
+
#undef GENBIN
#define GENBIN(GenBinEvOp, GenBinTyCat, GenBinFirOp) \
template <int KIND> \
ExtValue genval(const Fortran::evaluate::GenBinEvOp<Fortran::evaluate::Type< \
Fortran::common::TypeCategory::GenBinTyCat, KIND>> &x) { \
- TODO(getLoc(), "genval GenBinEvOp"); \
+ return createBinaryOp<GenBinFirOp>(x); \
}
GENBIN(Add, Integer, mlir::arith::AddIOp)
diff --git a/flang/test/Lower/assignment.f90 b/flang/test/Lower/assignment.f90
index 32c2086de7de2..ce9689a708a8f 100644
--- a/flang/test/Lower/assignment.f90
+++ b/flang/test/Lower/assignment.f90
@@ -63,5 +63,195 @@ real function negr(a)
! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<!fir.complex<4>>
! CHECK: %[[NEG:.*]] = fir.negc %[[A_VAL]] : !fir.complex<4>
! CHECK: fir.store %[[NEG]] to %[[FCTRES]] : !fir.ref<!fir.complex<4>>
+
+integer function addi(a, b)
+ integer :: a, b
+ addi = a + b
+end
+
+! CHECK-LABEL: func @_QPaddi(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<i32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca i32
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
+! CHECK: %[[ADD:.*]] = arith.addi %[[A_VAL]], %[[B_VAL]] : i32
+! CHECK: fir.store %[[ADD]] to %[[FCTRES]] : !fir.ref<i32>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<i32>
+! CHECK: return %[[RET]] : i32
+
+integer function subi(a, b)
+ integer :: a, b
+ subi = a - b
+end
+
+! CHECK-LABEL: func @_QPsubi(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<i32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca i32
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
+! CHECK: %[[SUB:.*]] = arith.subi %[[A_VAL]], %[[B_VAL]] : i32
+! CHECK: fir.store %[[SUB]] to %[[FCTRES]] : !fir.ref<i32>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<i32>
+! CHECK: return %[[RET]] : i32
+
+integer function muli(a, b)
+ integer :: a, b
+ muli = a * b
+end
+
+! CHECK-LABEL: func @_QPmuli(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<i32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca i32
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
+! CHECK: %[[MUL:.*]] = arith.muli %[[A_VAL]], %[[B_VAL]] : i32
+! CHECK: fir.store %[[MUL]] to %[[FCTRES]] : !fir.ref<i32>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<i32>
+! CHECK: return %[[RET]] : i32
+
+integer function divi(a, b)
+ integer :: a, b
+ divi = a / b
+end
+
+! CHECK-LABEL: func @_QPdivi(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<i32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<i32> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca i32
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<i32>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<i32>
+! CHECK: %[[DIV:.*]] = arith.divsi %[[A_VAL]], %[[B_VAL]] : i32
+! CHECK: fir.store %[[DIV]] to %[[FCTRES]] : !fir.ref<i32>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<i32>
+! CHECK: return %[[RET]] : i32
+
+real function addf(a, b)
+ real :: a, b
+ addf = a + b
+end
+
+! CHECK-LABEL: func @_QPaddf(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<f32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca f32
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<f32>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<f32>
+! CHECK: %[[ADD:.*]] = arith.addf %[[A_VAL]], %[[B_VAL]] : f32
+! CHECK: fir.store %[[ADD]] to %[[FCTRES]] : !fir.ref<f32>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<f32>
+! CHECK: return %[[RET]] : f32
+
+real function subf(a, b)
+ real :: a, b
+ subf = a - b
+end
+
+! CHECK-LABEL: func @_QPsubf(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<f32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca f32
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<f32>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<f32>
+! CHECK: %[[SUB:.*]] = arith.subf %[[A_VAL]], %[[B_VAL]] : f32
+! CHECK: fir.store %[[SUB]] to %[[FCTRES]] : !fir.ref<f32>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<f32>
+! CHECK: return %[[RET]] : f32
+
+real function mulf(a, b)
+ real :: a, b
+ mulf = a * b
+end
+
+! CHECK-LABEL: func @_QPmulf(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<f32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca f32
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<f32>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<f32>
+! CHECK: %[[MUL:.*]] = arith.mulf %[[A_VAL]], %[[B_VAL]] : f32
+! CHECK: fir.store %[[MUL]] to %[[FCTRES]] : !fir.ref<f32>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<f32>
+! CHECK: return %[[RET]] : f32
+
+real function divf(a, b)
+ real :: a, b
+ divf = a / b
+end
+
+! CHECK-LABEL: func @_QPdivf(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<f32> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<f32> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca f32
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<f32>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<f32>
+! CHECK: %[[DIV:.*]] = arith.divf %[[A_VAL]], %[[B_VAL]] : f32
+! CHECK: fir.store %[[DIV]] to %[[FCTRES]] : !fir.ref<f32>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<f32>
+! CHECK: return %[[RET]] : f32
+
+complex function addc(a, b)
+ complex :: a, b
+ addc = a + b
+end
+
+! CHECK-LABEL: func @_QPaddc(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.complex<4>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<!fir.complex<4>> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca !fir.complex<4>
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[ADD:.*]] = fir.addc %[[A_VAL]], %[[B_VAL]] : !fir.complex<4>
+! CHECK: fir.store %[[ADD]] to %[[FCTRES]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<!fir.complex<4>>
+! CHECK: return %[[RET]] : !fir.complex<4>
+
+complex function subc(a, b)
+ complex :: a, b
+ subc = a - b
+end
+
+! CHECK-LABEL: func @_QPsubc(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.complex<4>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<!fir.complex<4>> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca !fir.complex<4>
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[SUB:.*]] = fir.subc %[[A_VAL]], %[[B_VAL]] : !fir.complex<4>
+! CHECK: fir.store %[[SUB]] to %[[FCTRES]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<!fir.complex<4>>
+! CHECK: return %[[RET]] : !fir.complex<4>
+
+complex function mulc(a, b)
+ complex :: a, b
+ mulc = a * b
+end
+
+! CHECK-LABEL: func @_QPmulc(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.complex<4>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<!fir.complex<4>> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca !fir.complex<4>
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[MUL:.*]] = fir.mulc %[[A_VAL]], %[[B_VAL]] : !fir.complex<4>
+! CHECK: fir.store %[[MUL]] to %[[FCTRES]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<!fir.complex<4>>
+! CHECK: return %[[RET]] : !fir.complex<4>
+
+complex function divc(a, b)
+ complex :: a, b
+ divc = a / b
+end
+
+! CHECK-LABEL: func @_QPdivc(
+! CHECK-SAME: %[[A:.*]]: !fir.ref<!fir.complex<4>> {fir.bindc_name = "a"},
+! CHECK-SAME: %[[B:.*]]: !fir.ref<!fir.complex<4>> {fir.bindc_name = "b"}
+! CHECK: %[[FCTRES:.*]] = fir.alloca !fir.complex<4>
+! CHECK: %[[A_VAL:.*]] = fir.load %[[A]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[B_VAL:.*]] = fir.load %[[B]] : !fir.ref<!fir.complex<4>>
+! CHECK: %[[DIV:.*]] = fir.divc %[[A_VAL]], %[[B_VAL]] : !fir.complex<4>
+! CHECK: fir.store %[[DIV]] to %[[FCTRES]] : !fir.ref<!fir.complex<4>>
! CHECK: %[[RET:.*]] = fir.load %[[FCTRES]] : !fir.ref<!fir.complex<4>>
! CHECK: return %[[RET]] : !fir.complex<4>
More information about the flang-commits
mailing list