[flang-commits] [flang] ba45f63 - [flang] Lower complex part
Ethan Luis McDonough via flang-commits
flang-commits at lists.llvm.org
Tue Mar 7 09:40:36 PST 2023
Author: Ethan Luis McDonough
Date: 2023-03-07T11:40:27-06:00
New Revision: ba45f63782fa04a530d451dedb3cd58ed6e99664
URL: https://github.com/llvm/llvm-project/commit/ba45f63782fa04a530d451dedb3cd58ed6e99664
DIFF: https://github.com/llvm/llvm-project/commit/ba45f63782fa04a530d451dedb3cd58ed6e99664.diff
LOG: [flang] Lower complex part
Implements HLFIR lowering for %im and %re.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D145005
Added:
Modified:
flang/lib/Lower/ConvertExprToHLFIR.cpp
flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
flang/test/Lower/HLFIR/designators.f90
Removed:
################################################################################
diff --git a/flang/lib/Lower/ConvertExprToHLFIR.cpp b/flang/lib/Lower/ConvertExprToHLFIR.cpp
index 68839bacd6ef..2dd61bb15833 100644
--- a/flang/lib/Lower/ConvertExprToHLFIR.cpp
+++ b/flang/lib/Lower/ConvertExprToHLFIR.cpp
@@ -88,6 +88,7 @@ class HlfirDesignatorBuilder {
std::string componentName{};
mlir::Value componentShape;
hlfir::DesignateOp::Subscripts subscripts;
+ std::optional<bool> complexPart;
mlir::Value resultShape;
llvm::SmallVector<mlir::Value> typeParams;
llvm::SmallVector<mlir::Value, 2> substring;
@@ -98,8 +99,14 @@ class HlfirDesignatorBuilder {
// fir.box)...
template <typename T>
mlir::Type computeDesignatorType(mlir::Type resultValueType,
- const PartInfo &partInfo,
+ PartInfo &partInfo,
const T &designatorNode) {
+ // Get base's shape if its a sequence type with no previously computed
+ // result shape
+ if (partInfo.base && resultValueType.isa<fir::SequenceType>() &&
+ !partInfo.resultShape)
+ partInfo.resultShape =
+ hlfir::genShape(getLoc(), getBuilder(), *partInfo.base);
// Dynamic type of polymorphic base must be kept if the designator is
// polymorphic.
if (isPolymorphic(designatorNode))
@@ -144,11 +151,10 @@ class HlfirDesignatorBuilder {
fir::FortranVariableOpInterface
genDesignate(mlir::Type designatorType, PartInfo &partInfo,
fir::FortranVariableFlagsAttr attributes) {
- std::optional<bool> complexPart;
auto designate = getBuilder().create<hlfir::DesignateOp>(
getLoc(), designatorType, partInfo.base.value().getBase(),
partInfo.componentName, partInfo.componentShape, partInfo.subscripts,
- partInfo.substring, complexPart, partInfo.resultShape,
+ partInfo.substring, partInfo.complexPart, partInfo.resultShape,
partInfo.typeParams, attributes);
return mlir::cast<fir::FortranVariableOpInterface>(
designate.getOperation());
@@ -240,7 +246,21 @@ class HlfirDesignatorBuilder {
fir::FortranVariableOpInterface
gen(const Fortran::evaluate::ComplexPart &complexPart) {
- TODO(getLoc(), "lowering complex part to HLFIR");
+ PartInfo partInfo;
+ fir::factory::Complex cmplxHelper(getBuilder(), getLoc());
+
+ bool complexBit =
+ complexPart.part() == Fortran::evaluate::ComplexPart::Part::IM;
+ partInfo.complexPart = {complexBit};
+
+ mlir::Type resultType = visit(complexPart.complex(), partInfo);
+
+ // Determine complex part type
+ mlir::Type base = hlfir::getFortranElementType(resultType);
+ mlir::Type cmplxValueType = cmplxHelper.getComplexPartType(base);
+ mlir::Type designatorType = changeElementType(resultType, cmplxValueType);
+
+ return genDesignate(designatorType, partInfo, complexPart);
}
fir::FortranVariableOpInterface
diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
index 53259fe495ba..13103c50d0df 100644
--- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
+++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp
@@ -336,7 +336,9 @@ mlir::LogicalResult hlfir::DesignateOp::verify() {
// length may
diff er because of substrings.
if (resultElementType != outputElementType &&
!(resultElementType.isa<fir::CharacterType>() &&
- outputElementType.isa<fir::CharacterType>()))
+ outputElementType.isa<fir::CharacterType>()) &&
+ !(resultElementType.isa<mlir::FloatType>() &&
+ outputElementType.isa<fir::RealType>()))
return emitOpError(
"result element type is not consistent with operands, expected ")
<< outputElementType;
diff --git a/flang/test/Lower/HLFIR/designators.f90 b/flang/test/Lower/HLFIR/designators.f90
index a2aaad536e19..777d6ea5182e 100644
--- a/flang/test/Lower/HLFIR/designators.f90
+++ b/flang/test/Lower/HLFIR/designators.f90
@@ -112,3 +112,58 @@ subroutine char_array_section_cst_len(x, n)
! CHECK: %[[VAL_19:.*]] = arith.select %[[VAL_18]], %[[VAL_17]], %[[VAL_14]] : index
! CHECK: %[[VAL_20:.*]] = fir.shape %[[VAL_19]] : (index) -> !fir.shape<1>
! CHECK: %[[VAL_21:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_10]]:%[[VAL_12]]#1:%[[VAL_13]]) shape %[[VAL_20]] typeparams %[[VAL_3]] : (!fir.box<!fir.array<?x!fir.char<1,5>>>, index, index, index, !fir.shape<1>, index) -> !fir.box<!fir.array<?x!fir.char<1,5>>>
+
+! Checks related to complex numbers
+
+subroutine complex_imag_ref(x)
+ complex :: x(:)
+ print *, x%im
+end subroutine
+! CHECK-LABEL: func.func @_QPcomplex_imag_ref(
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFcomplex_imag_refEx"} : (!fir.box<!fir.array<?x!fir.complex<4>>>) -> (!fir.box<!fir.array<?x!fir.complex<4>>>, !fir.box<!fir.array<?x!fir.complex<4>>>)
+! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_4:.*]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_5:.*]] = hlfir.designate %[[VAL_2]]#0 imag shape %[[VAL_3]] : (!fir.box<!fir.array<?x!fir.complex<4>>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+
+subroutine complex_real_ref(x)
+ complex :: x(:)
+ print *, x%re
+end subroutine
+! CHECK-LABEL: func.func @_QPcomplex_real_ref(
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFcomplex_real_refEx"} : (!fir.box<!fir.array<?x!fir.complex<4>>>) -> (!fir.box<!fir.array<?x!fir.complex<4>>>, !fir.box<!fir.array<?x!fir.complex<4>>>)
+! CHECK: %[[VAL_3:.*]] = fir.shape %[[VAL_4:.*]]#1 : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_5:.*]] = hlfir.designate %[[VAL_2]]#0 real shape %[[VAL_3]] : (!fir.box<!fir.array<?x!fir.complex<4>>>, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
+
+subroutine complex_individual_ref(x, n)
+ complex :: x(:)
+ integer :: n
+ print *, x(n)%im
+end subroutine
+! CHECK-LABEL: func.func @_QPcomplex_individual_ref(
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFcomplex_individual_refEn"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFcomplex_individual_refEx"} : (!fir.box<!fir.array<?x!fir.complex<4>>>) -> (!fir.box<!fir.array<?x!fir.complex<4>>>, !fir.box<!fir.array<?x!fir.complex<4>>>)
+! CHECK: %[[VAL_4:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_5:.*]] = fir.convert %[[VAL_4]] : (i32) -> i64
+! CHECK: %[[VAL_6:.*]] = hlfir.designate %1#0 (%[[VAL_5]]) imag : (!fir.box<!fir.array<?x!fir.complex<4>>>, i64) -> !fir.ref<f32>
+
+subroutine complex_slice_ref(x, start, end)
+ complex :: x(:)
+ integer :: start, end
+ print *, x(start:end)%re
+end subroutine
+! CHECK-LABEL: func.func @_QPcomplex_slice_ref(
+! CHECK: %[[VAL_2:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFcomplex_slice_refEend"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFcomplex_slice_refEstart"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %arg0 {uniq_name = "_QFcomplex_slice_refEx"} : (!fir.box<!fir.array<?x!fir.complex<4>>>) -> (!fir.box<!fir.array<?x!fir.complex<4>>>, !fir.box<!fir.array<?x!fir.complex<4>>>)
+! CHECK: %[[VAL_5:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_5]] : (i32) -> i64
+! CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_2]]#0 : !fir.ref<i32>
+! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_7]] : (i32) -> i64
+! CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_6]] : (i64) -> index
+! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_8]] : (i64) -> index
+! CHECK: %[[VAL_11:.*]] = arith.subi %[[VAL_10]], %[[VAL_9]] : index
+! CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_11]], %{{.*}} : index
+! CHECK: %[[VAL_13:.*]] = arith.divsi %[[VAL_12]], %{{.*}} : index
+! CHECK: %[[VAL_14:.*]] = arith.cmpi sgt, %[[VAL_13]], %{{.*}} : index
+! CHECK: %[[VAL_15:.*]] = arith.select %[[VAL_14]], %[[VAL_13]], %{{.*}} : index
+! CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_15]] : (index) -> !fir.shape<1>
+! CHECK: %[[VAL_17:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_9]]:%[[VAL_10]]:%{{.*}}) real shape %[[VAL_16]] : (!fir.box<!fir.array<?x!fir.complex<4>>>, index, index, index, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
More information about the flang-commits
mailing list