[PATCH] D118701: [flang][optimizer] support aggregate types inside tuple and record type

Jean Perier via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 1 05:56:33 PST 2022


jeanPerier created this revision.
jeanPerier added reviewers: schweitz, clementval.
jeanPerier added a project: Flang.
Herald added subscribers: mehdi_amini, jdoerfert.
jeanPerier requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Allow fir.box type to be a member of a tuple<> or fir.type<>, in which
case it should be ensured it should be ensured the fir.box member is not
translate to the struct type of a Fortran runtime descriptor, and not a
pointer to it.

FIR type translation was also flattening nested tuple while lowering to LLVM
dialect types. There does not seem to be a deep reason for doing that
and doing it causes issues in fir.coordinate_of generated on such tuple
(a fir.coordinate_of getting tuple<B, C> in tuple<A, tuple<B, C>>
ended-up lowered to an LLVM GEP getting B).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D118701

Files:
  flang/lib/Optimizer/CodeGen/TypeConverter.h
  flang/lib/Optimizer/Dialect/FIRType.cpp
  flang/test/Fir/types-to-llvm.fir


Index: flang/test/Fir/types-to-llvm.fir
===================================================================
--- flang/test/Fir/types-to-llvm.fir
+++ flang/test/Fir/types-to-llvm.fir
@@ -400,3 +400,21 @@
 func private @foo3(%arg : !fir.tdesc<!fir.type<derived7{f1:f32,f2:f32}>>)
 // CHECK-LABEL: foo3
 // CHECK-SAME:  !llvm.ptr<i8>
+
+// -----
+
+// Test nested tuple types
+func private @foo0(%arg0: tuple<i64, tuple<f32, i64>>)
+// CHECK-LABEL: foo0
+// CHECK-SAME: !llvm.struct<(i64, struct<(f32, i64)>)>
+
+// -----
+
+// Test that fir.box inside tuple and derived type are lowered to struct type.
+func private @foo0(%arg0: tuple<i64, !fir.box<i32>>)
+// CHECK-LABEL: foo0
+// CHECK-SAME: !llvm.struct<(i64, struct<(ptr<i32>, i{{.*}})>)>
+
+func private @foo1(%arg0: !fir.type<derived8{a:i64,b:!fir.box<i32>}>)
+// CHECK-LABEL: foo1
+// CHECK-SAME: !llvm.struct<"derived8", (i64, struct<(ptr<i32>, i{{.*}})>)>
Index: flang/lib/Optimizer/Dialect/FIRType.cpp
===================================================================
--- flang/lib/Optimizer/Dialect/FIRType.cpp
+++ flang/lib/Optimizer/Dialect/FIRType.cpp
@@ -61,11 +61,11 @@
 }
 
 bool verifyRecordMemberType(mlir::Type ty) {
-  return !(ty.isa<BoxType>() || ty.isa<BoxCharType>() ||
-           ty.isa<BoxProcType>() || ty.isa<ShapeType>() ||
-           ty.isa<ShapeShiftType>() || ty.isa<ShiftType>() ||
-           ty.isa<SliceType>() || ty.isa<FieldType>() || ty.isa<LenType>() ||
-           ty.isa<ReferenceType>() || ty.isa<TypeDescType>());
+  return !(ty.isa<BoxCharType>() || ty.isa<BoxProcType>() ||
+           ty.isa<ShapeType>() || ty.isa<ShapeShiftType>() ||
+           ty.isa<ShiftType>() || ty.isa<SliceType>() || ty.isa<FieldType>() ||
+           ty.isa<LenType>() || ty.isa<ReferenceType>() ||
+           ty.isa<TypeDescType>());
 }
 
 bool verifySameLists(llvm::ArrayRef<RecordType::TypePair> a1,
Index: flang/lib/Optimizer/CodeGen/TypeConverter.h
===================================================================
--- flang/lib/Optimizer/CodeGen/TypeConverter.h
+++ flang/lib/Optimizer/CodeGen/TypeConverter.h
@@ -111,11 +111,15 @@
     });
     addConversion([&](mlir::TupleType tuple) {
       LLVM_DEBUG(llvm::dbgs() << "type convert: " << tuple << '\n');
-      llvm::SmallVector<mlir::Type> inMembers;
-      tuple.getFlattenedTypes(inMembers);
       llvm::SmallVector<mlir::Type> members;
-      for (auto mem : inMembers)
-        members.push_back(convertType(mem).cast<mlir::Type>());
+      for (auto mem : tuple.getTypes()) {
+        // Prevent fir.box from degenerating to a pointer to a descriptor in the
+        // context of a tuple type.
+        if (auto box = mem.dyn_cast<fir::BoxType>())
+          members.push_back(convertBoxTypeAsStruct(box));
+        else
+          members.push_back(convertType(mem).cast<mlir::Type>());
+      }
       return mlir::LLVM::LLVMStructType::getLiteral(&getContext(), members,
                                                     /*isPacked=*/false);
     });
@@ -140,7 +144,12 @@
     }
     llvm::SmallVector<mlir::Type> members;
     for (auto mem : derived.getTypeList()) {
-      members.push_back(convertType(mem.second).cast<mlir::Type>());
+      // Prevent fir.box from degenerating to a pointer to a descriptor in the
+      // context of a record type.
+      if (auto box = mem.second.dyn_cast<fir::BoxType>())
+        members.push_back(convertBoxTypeAsStruct(box));
+      else
+        members.push_back(convertType(mem.second).cast<mlir::Type>());
     }
     if (mlir::failed(st.setBody(members, /*isPacked=*/false)))
       return failure();
@@ -227,6 +236,14 @@
                                                /*isPacked=*/false));
   }
 
+  /// Convert fir.box type to the corresponding llvm struct type instead of a
+  /// pointer to this struct type.
+  mlir::Type convertBoxTypeAsStruct(BoxType box) {
+    return convertBoxType(box)
+        .cast<mlir::LLVM::LLVMPointerType>()
+        .getElementType();
+  }
+
   unsigned characterBitsize(fir::CharacterType charTy) {
     return kindMapping.getCharacterBitsize(charTy.getFKind());
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D118701.404903.patch
Type: text/x-patch
Size: 4113 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220201/492016ee/attachment.bin>


More information about the llvm-commits mailing list