[flang-commits] [flang] 747211b - [flang] Handle emboxing of a fir.ref<none> to an unlimited polymorphic box
Valentin Clement via flang-commits
flang-commits at lists.llvm.org
Mon Jan 9 08:52:53 PST 2023
Author: Valentin Clement
Date: 2023-01-09T17:52:44+01:00
New Revision: 747211b7126532eaa8f31b37fd4f6a0110e51358
URL: https://github.com/llvm/llvm-project/commit/747211b7126532eaa8f31b37fd4f6a0110e51358
DIFF: https://github.com/llvm/llvm-project/commit/747211b7126532eaa8f31b37fd4f6a0110e51358.diff
LOG: [flang] Handle emboxing of a fir.ref<none> to an unlimited polymorphic box
When an array element is extracted from an unlimited polymorphic array, the
emboxing of this element has to retrive the type code and element size from
the initial array. This patch retrive this information through the extracted
type descriptor.
This situation can be found in code like:
```
subroutine sub1(a)
class(*) :: a(:)
select type (x=>a(1))
type is (integer)
x = 10
end select
end subroutine
```
Reviewed By: jeanPerier, PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D141274
Added:
Modified:
flang/lib/Optimizer/CodeGen/CodeGen.cpp
flang/test/Fir/polymorphic.fir
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
index 49d711f69f413..5ca04cbcc633e 100644
--- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp
+++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp
@@ -1568,6 +1568,26 @@ struct EmboxCommonConversion : public FIROpConversion<OP> {
// information.
auto [eleSize, cfiTy] = getSizeAndTypeCode(
loc, rewriter, useInputType ? inputType : boxTy.getEleTy(), typeparams);
+
+ // When emboxing a fir.ref<none> to an unlimited polymorphic box, get the
+ // type code and element size from the box used to extract the type desc.
+ if (fir::isUnlimitedPolymorphicType(boxTy) &&
+ inputType.isa<mlir::NoneType>() && typeDesc) {
+ if (auto *typeDescOp = typeDesc.getDefiningOp()) {
+ if (auto loadOp = mlir::dyn_cast<mlir::LLVM::LoadOp>(typeDescOp)) {
+ if (auto *gepOp = loadOp.getAddr().getDefiningOp()) {
+ if (auto gep = mlir::dyn_cast<mlir::LLVM::GEPOp>(gepOp)) {
+ mlir::Type idxTy = this->lowerTy().indexType();
+ eleSize = this->loadElementSizeFromBox(loc, idxTy, gep.getBase(),
+ rewriter);
+ cfiTy = this->getValueFromBox(loc, gep.getBase(), cfiTy.getType(),
+ rewriter, kTypePosInBox);
+ }
+ }
+ }
+ }
+ }
+
auto mod = box->template getParentOfType<mlir::ModuleOp>();
mlir::Value descriptor = populateDescriptor(
loc, mod, boxTy, inputType, rewriter, rank, eleSize, cfiTy, typeDesc);
diff --git a/flang/test/Fir/polymorphic.fir b/flang/test/Fir/polymorphic.fir
index 68b4cbbfc9cf1..d85fd6daa1cbd 100644
--- a/flang/test/Fir/polymorphic.fir
+++ b/flang/test/Fir/polymorphic.fir
@@ -68,6 +68,40 @@ func.func @_QMpolymorphic_testPtest_embox() {
// CHECK: %[[LOADED_DESC:.*]] = load { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[ALLOCA_DESC]], align 8
// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] } %[[LOADED_DESC]], ptr @_QFEx, align 8
+// Test emboxing of an array element from an unlimited polymorphic array.
+
+func.func @_QMunlimitedPsub1(%arg0: !fir.class<!fir.array<?xnone>> {fir.bindc_name = "a"}) {
+ %c1_i64 = arith.constant 1 : i64
+ %c1_i64_0 = arith.constant 1 : i64
+ %0 = arith.subi %c1_i64, %c1_i64_0 : i64
+ %1 = fir.coordinate_of %arg0, %0 : (!fir.class<!fir.array<?xnone>>, i64) -> !fir.ref<none>
+ %2 = fir.box_tdesc %arg0 : (!fir.class<!fir.array<?xnone>>) -> !fir.tdesc<none>
+ %3 = fir.embox %1 tdesc %2 : (!fir.ref<none>, !fir.tdesc<none>) -> !fir.class<none>
+ fir.select_type %3 : !fir.class<none> [#fir.type_is<i32>, ^bb1, unit, ^bb2]
+^bb1:
+ %4 = fir.box_addr %3 : (!fir.class<none>) -> !fir.ref<i32>
+ %c10_i32 = arith.constant 10 : i32
+ fir.store %c10_i32 to %4 : !fir.ref<i32>
+ cf.br ^bb2
+^bb2: // 2 preds: ^bb0, ^bb1
+ return
+}
+
+// CHECK-LABEL: define void @_QMunlimitedPsub1(
+// CHECK-SAME: ptr %[[ARRAY:.*]]) {
+// CHECK: %[[BOX:.*]] = alloca { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] }
+// CHECK: %[[TYPE_DESC_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %[[ARRAY]], i32 0, i32 8
+// CHECK: %[[TYPE_DESC:.*]] = load ptr, ptr %[[TYPE_DESC_GEP]]
+// CHECK: %[[ELE_SIZE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %0, i32 0, i32 1
+// CHECK: %[[ELE_SIZE:.*]] = load i64, ptr %[[ELE_SIZE_GEP]]
+// CHECK: %[[TYPE_CODE_GEP:.*]] = getelementptr { ptr, i64, i32, i8, i8, i8, i8, [1 x [3 x i64]], ptr, [1 x i64] }, ptr %0, i32 0, i32 4
+// CHECK: %[[TYPE_CODE:.*]] = load i32, ptr %[[TYPE_CODE_GEP]]
+// CHECK: %{{.*}} = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } undef, i64 %[[ELE_SIZE]], 1
+// CHECK: %[[TYPE_CODE_TRUNC:.*]] = trunc i32 %[[TYPE_CODE]] to i8
+// CHECK: %{{.*}} = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %{{.*}}, i8 %[[TYPE_CODE_TRUNC]], 4
+// CHECK: %{{.*}} = insertvalue { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %{{.*}}, ptr %[[TYPE_DESC]], 7
+// CHECK: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } %24, ptr %[[BOX]]
+
fir.global internal @_QFEx : !fir.class<!fir.ptr<!fir.array<?xnone>>> {
%0 = fir.zero_bits !fir.ptr<!fir.array<?xnone>>
@@ -89,3 +123,4 @@ fir.global linkonce @_QQcl.2E2F64756D6D792E66393000 constant : !fir.char<1,12> {
%0 = fir.string_lit "./dummy.f90\00"(12) : !fir.char<1,12>
fir.has_value %0 : !fir.char<1,12>
}
+
More information about the flang-commits
mailing list