mirror of
https://github.com/intel/llvm.git
synced 2026-02-06 06:31:50 +08:00
[flang] Lower complex part
Implements HLFIR lowering for %im and %re. Reviewed By: jeanPerier Differential Revision: https://reviews.llvm.org/D145005
This commit is contained in:
@@ -88,6 +88,7 @@ private:
|
||||
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 @@ private:
|
||||
// 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 @@ private:
|
||||
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 @@ private:
|
||||
|
||||
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
|
||||
|
||||
@@ -336,7 +336,9 @@ mlir::LogicalResult hlfir::DesignateOp::verify() {
|
||||
// length may differ 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;
|
||||
|
||||
@@ -112,3 +112,58 @@ end subroutine
|
||||
! 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>>
|
||||
|
||||
Reference in New Issue
Block a user