[flang] [llvm] [flang][cuda] Add support for derived-type component with managed/unified attributes (PR #177409)

Valentin Clement バレンタイン クレメン via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 22 12:51:23 PST 2026


https://github.com/clementval updated https://github.com/llvm/llvm-project/pull/177409

>From 65fc0c3880e04b90bce660428a3199949a6b1f81 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Wed, 21 Jan 2026 19:58:26 -0800
Subject: [PATCH 1/4] [flang][cuda] Add support for derived-type component with
 managed/unified attributes

---
 flang-rt/include/flang-rt/runtime/type-info.h |  6 +++-
 flang-rt/lib/runtime/assign.cpp               |  6 +++-
 flang-rt/lib/runtime/copy.cpp                 |  4 +++
 flang-rt/lib/runtime/derived.cpp              | 24 +++++++++++---
 flang-rt/lib/runtime/type-info.cpp            | 33 +++++++++++++++----
 flang/lib/Semantics/runtime-type-info.cpp     | 16 +++++++++
 flang/module/__fortran_type_info.f90          |  5 ++-
 .../Lower/CUDA/cuda-allocatable-device.cuf    | 24 +++++++++++++-
 8 files changed, 102 insertions(+), 16 deletions(-)

diff --git a/flang-rt/include/flang-rt/runtime/type-info.h b/flang-rt/include/flang-rt/runtime/type-info.h
index a6528312750a0..89f70c1a23d51 100644
--- a/flang-rt/include/flang-rt/runtime/type-info.h
+++ b/flang-rt/include/flang-rt/runtime/type-info.h
@@ -57,7 +57,11 @@ class Component {
     Allocatable = 3,
     Automatic = 4,
     PointerDevice = 5,
-    AllocatableDevice = 6
+    AllocatableDevice = 6,
+    PointerManaged = 7,
+    AllocatableManaged = 8,
+    PointerUnified = 9,
+    AllocatableUnified = 10
   };
 
   RT_API_ATTRS const Descriptor &name() const { return name_.descriptor(); }
diff --git a/flang-rt/lib/runtime/assign.cpp b/flang-rt/lib/runtime/assign.cpp
index dd5d4b945881e..d3b9d565c620d 100644
--- a/flang-rt/lib/runtime/assign.cpp
+++ b/flang-rt/lib/runtime/assign.cpp
@@ -649,7 +649,9 @@ RT_API_ATTRS int DerivedAssignTicket<IS_COMPONENTWISE>::Continue(
       }
       break;
     case typeInfo::Component::Genre::Pointer:
-    case typeInfo::Component::Genre::PointerDevice: {
+    case typeInfo::Component::Genre::PointerDevice:
+    case typeInfo::Component::Genre::PointerManaged:
+    case typeInfo::Component::Genre::PointerUnified: {
       std::size_t componentByteSize{
           this->component_->SizeInBytes(this->instance_)};
       if (IS_COMPONENTWISE && toIsContiguous_ && fromIsContiguous_) {
@@ -682,6 +684,8 @@ RT_API_ATTRS int DerivedAssignTicket<IS_COMPONENTWISE>::Continue(
     } break;
     case typeInfo::Component::Genre::Allocatable:
     case typeInfo::Component::Genre::AllocatableDevice:
+    case typeInfo::Component::Genre::AllocatableManaged:
+    case typeInfo::Component::Genre::AllocatableUnified:
     case typeInfo::Component::Genre::Automatic: {
       auto *toDesc{reinterpret_cast<Descriptor *>(
           this->instance_.template Element<char>(this->subscripts_) +
diff --git a/flang-rt/lib/runtime/copy.cpp b/flang-rt/lib/runtime/copy.cpp
index 8b7db61b014e1..d1d35d2bbd686 100644
--- a/flang-rt/lib/runtime/copy.cpp
+++ b/flang-rt/lib/runtime/copy.cpp
@@ -170,6 +170,10 @@ RT_API_ATTRS void CopyElement(const Descriptor &to, const SubscriptValue toAt[],
           if (component->genre() == typeInfo::Component::Genre::Allocatable ||
               component->genre() ==
                   typeInfo::Component::Genre::AllocatableDevice ||
+              component->genre() ==
+                  typeInfo::Component::Genre::AllocatableManaged ||
+              component->genre() ==
+                  typeInfo::Component::Genre::AllocatableUnified ||
               component->genre() == typeInfo::Component::Genre::Automatic) {
             Descriptor &toDesc{
                 *reinterpret_cast<Descriptor *>(toPtr + component->offset())};
diff --git a/flang-rt/lib/runtime/derived.cpp b/flang-rt/lib/runtime/derived.cpp
index 7fc426b9efc9a..8aa6be510a13a 100644
--- a/flang-rt/lib/runtime/derived.cpp
+++ b/flang-rt/lib/runtime/derived.cpp
@@ -65,7 +65,9 @@ RT_API_ATTRS int InitializeTicket::Continue(WorkQueue &workQueue) {
   for (; !Componentwise::IsComplete(); SkipToNextComponent()) {
     char *rawComponent{rawInstance + component_->offset()};
     if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableDevice) {
+        component_->genre() == typeInfo::Component::Genre::AllocatableDevice ||
+        component_->genre() == typeInfo::Component::Genre::AllocatableManaged ||
+        component_->genre() == typeInfo::Component::Genre::AllocatableUnified) {
       Descriptor &allocDesc{*reinterpret_cast<Descriptor *>(rawComponent)};
       component_->EstablishDescriptor(
           allocDesc, instance_, workQueue.terminator());
@@ -79,7 +81,9 @@ RT_API_ATTRS int InitializeTicket::Continue(WorkQueue &workQueue) {
         Fortran::runtime::memcpy(rawComponent, init, bytes);
       }
     } else if (component_->genre() == typeInfo::Component::Genre::Pointer ||
-        component_->genre() == typeInfo::Component::Genre::PointerDevice) {
+        component_->genre() == typeInfo::Component::Genre::PointerDevice ||
+        component_->genre() == typeInfo::Component::Genre::PointerManaged ||
+        component_->genre() == typeInfo::Component::Genre::PointerUnified) {
       // Data pointers without explicit initialization are established
       // so that they are valid right-hand side targets of pointer
       // assignment statements.
@@ -164,7 +168,9 @@ RT_API_ATTRS int InitializeClone(const Descriptor &clone,
 RT_API_ATTRS int InitializeCloneTicket::Continue(WorkQueue &workQueue) {
   while (!IsComplete()) {
     if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableDevice) {
+        component_->genre() == typeInfo::Component::Genre::AllocatableDevice ||
+        component_->genre() == typeInfo::Component::Genre::AllocatableManaged ||
+        component_->genre() == typeInfo::Component::Genre::AllocatableUnified) {
       Descriptor &origDesc{*instance_.ElementComponent<Descriptor>(
           subscripts_, component_->offset())};
       if (origDesc.IsAllocated()) {
@@ -343,7 +349,11 @@ RT_API_ATTRS int FinalizeTicket::Continue(WorkQueue &workQueue) {
   while (!IsComplete()) {
     if ((component_->genre() == typeInfo::Component::Genre::Allocatable ||
             component_->genre() ==
-                typeInfo::Component::Genre::AllocatableDevice) &&
+                typeInfo::Component::Genre::AllocatableDevice ||
+            component_->genre() ==
+                typeInfo::Component::Genre::AllocatableManaged ||
+            component_->genre() ==
+                typeInfo::Component::Genre::AllocatableUnified) &&
         component_->category() == TypeCategory::Derived) {
       // Component may be polymorphic or unlimited polymorphic. Need to use the
       // dynamic type to check whether finalization is needed.
@@ -366,6 +376,8 @@ RT_API_ATTRS int FinalizeTicket::Continue(WorkQueue &workQueue) {
       }
     } else if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
         component_->genre() == typeInfo::Component::Genre::AllocatableDevice ||
+        component_->genre() == typeInfo::Component::Genre::AllocatableManaged ||
+        component_->genre() == typeInfo::Component::Genre::AllocatableUnified ||
         component_->genre() == typeInfo::Component::Genre::Automatic) {
       if (const typeInfo::DerivedType *compType{component_->derivedType()};
           compType && !compType->noFinalizationNeeded()) {
@@ -449,7 +461,9 @@ RT_API_ATTRS int DestroyTicket::Continue(WorkQueue &workQueue) {
   while (!IsComplete()) {
     const auto *componentDerived{component_->derivedType()};
     if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableDevice) {
+        component_->genre() == typeInfo::Component::Genre::AllocatableDevice ||
+        component_->genre() == typeInfo::Component::Genre::AllocatableManaged ||
+        component_->genre() == typeInfo::Component::Genre::AllocatableUnified) {
       if (fixedStride_ &&
           (!componentDerived || componentDerived->noDestructionNeeded())) {
         // common fast path, just deallocate in every element
diff --git a/flang-rt/lib/runtime/type-info.cpp b/flang-rt/lib/runtime/type-info.cpp
index 1157dda09c412..99bf48b5def36 100644
--- a/flang-rt/lib/runtime/type-info.cpp
+++ b/flang-rt/lib/runtime/type-info.cpp
@@ -95,16 +95,25 @@ RT_API_ATTRS std::size_t Component::SizeInBytes(
 RT_API_ATTRS void Component::EstablishDescriptor(Descriptor &descriptor,
     const Descriptor &container, Terminator &terminator) const {
   ISO::CFI_attribute_t attribute{static_cast<ISO::CFI_attribute_t>(
-      genre_ == Genre::Allocatable || genre_ == Genre::AllocatableDevice
+      genre_ == Genre::Allocatable || genre_ == Genre::AllocatableDevice ||
+              genre_ == Genre::AllocatableManaged ||
+              genre_ == Genre::AllocatableUnified
           ? CFI_attribute_allocatable
-          : genre_ == Genre::Pointer || genre_ == Genre::PointerDevice
+          : genre_ == Genre::Pointer || genre_ == Genre::PointerDevice ||
+              genre_ == Genre::PointerManaged || genre_ == Genre::PointerUnified
           ? CFI_attribute_pointer
           : CFI_attribute_other)};
   TypeCategory cat{category()};
-  unsigned allocatorIdx{
-      genre_ == Genre::AllocatableDevice || genre_ == Genre::PointerDevice
-          ? kDeviceAllocatorPos
-          : kDefaultAllocator};
+  unsigned allocatorIdx{kDefaultAllocator};
+  if (genre_ == Genre::AllocatableDevice || genre_ == Genre::PointerDevice) {
+    allocatorIdx = kDeviceAllocatorPos;
+  } else if (genre_ == Genre::AllocatableManaged ||
+      genre_ == Genre::PointerManaged) {
+    allocatorIdx = kManagedAllocatorPos;
+  } else if (genre_ == Genre::AllocatableUnified ||
+      genre_ == Genre::PointerUnified) {
+    allocatorIdx = kUnifiedAllocatorPos;
+  }
   if (cat == TypeCategory::Character) {
     std::size_t lengthInChars{0};
     if (auto length{characterLen_.GetValue(&container)}) {
@@ -128,7 +137,9 @@ RT_API_ATTRS void Component::EstablishDescriptor(Descriptor &descriptor,
         cat, kind_, nullptr, rank_, nullptr, attribute, false, allocatorIdx);
   }
   if (rank_ && genre_ != Genre::Allocatable && genre_ != Genre::Pointer &&
-      genre_ != Genre::AllocatableDevice && genre_ != Genre::PointerDevice) {
+      genre_ != Genre::AllocatableDevice && genre_ != Genre::PointerDevice &&
+      genre_ != Genre::AllocatableManaged && genre_ != Genre::PointerManaged &&
+      genre_ != Genre::AllocatableUnified && genre_ != Genre::PointerUnified) {
     const typeInfo::Value *boundValues{bounds()};
     RUNTIME_CHECK(terminator, boundValues != nullptr);
     auto byteStride{static_cast<SubscriptValue>(descriptor.ElementBytes())};
@@ -281,10 +292,18 @@ FILE *Component::Dump(FILE *f) const {
     std::fputs("    Pointer          ", f);
   } else if (genre_ == Genre::PointerDevice) {
     std::fputs("    PointerDevice    ", f);
+  } else if (genre_ == Genre::PointerManaged) {
+    std::fputs("    PointerManaged   ", f);
+  } else if (genre_ == Genre::PointerUnified) {
+    std::fputs("    PointerUnified   ", f);
   } else if (genre_ == Genre::Allocatable) {
     std::fputs("    Allocatable.     ", f);
   } else if (genre_ == Genre::AllocatableDevice) {
     std::fputs("    AllocatableDevice", f);
+  } else if (genre_ == Genre::AllocatableManaged) {
+    std::fputs("    AllocatableManaged", f);
+  } else if (genre_ == Genre::AllocatableUnified) {
+    std::fputs("    AllocatableUnified", f);
   } else if (genre_ == Genre::Automatic) {
     std::fputs("    Automatic        ", f);
   } else {
diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp
index 8f92fda65685a..b6c712ecdae20 100644
--- a/flang/lib/Semantics/runtime-type-info.cpp
+++ b/flang/lib/Semantics/runtime-type-info.cpp
@@ -773,6 +773,10 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
       symbol, foldingContext)};
   bool isDevice{object.cudaDataAttr() &&
       *object.cudaDataAttr() == common::CUDADataAttr::Device};
+  bool isManaged{object.cudaDataAttr() &&
+      *object.cudaDataAttr() == common::CUDADataAttr::Managed};
+  bool isUnified{object.cudaDataAttr() &&
+      *object.cudaDataAttr() == common::CUDADataAttr::Unified};
   CHECK(typeAndShape.has_value());
   auto dyType{typeAndShape->type()};
   int rank{typeAndShape->Rank()};
@@ -888,6 +892,12 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
     if (isDevice) {
       AddValue(values, componentSchema_, "genre"s,
           GetEnumValue("allocatabledevice"));
+    } else if (isManaged) {
+      AddValue(values, componentSchema_, "genre"s,
+          GetEnumValue("allocatablemanaged"));
+    } else if (isUnified) {
+      AddValue(values, componentSchema_, "genre"s,
+          GetEnumValue("allocatableunified"));
     } else {
       AddValue(values, componentSchema_, "genre"s, GetEnumValue("allocatable"));
     }
@@ -895,6 +905,12 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
     if (isDevice) {
       AddValue(
           values, componentSchema_, "genre"s, GetEnumValue("pointerdevice"));
+    } else if (isManaged) {
+      AddValue(
+          values, componentSchema_, "genre"s, GetEnumValue("pointermanaged"));
+    } else if (isUnified) {
+      AddValue(
+          values, componentSchema_, "genre"s, GetEnumValue("pointerunified"));
     } else {
       AddValue(values, componentSchema_, "genre"s, GetEnumValue("pointer"));
     }
diff --git a/flang/module/__fortran_type_info.f90 b/flang/module/__fortran_type_info.f90
index ae8eeef4a55e8..a8d9959feb872 100644
--- a/flang/module/__fortran_type_info.f90
+++ b/flang/module/__fortran_type_info.f90
@@ -75,7 +75,10 @@
   end type
 
   enum, bind(c) ! Component::Genre
-    enumerator :: Data = 1, Pointer = 2, Allocatable = 3, Automatic = 4, PointerDevice = 5, AllocatableDevice = 6
+    enumerator :: Data = 1, Pointer = 2, Allocatable = 3, Automatic = 4
+    enumerator :: PointerDevice = 5, AllocatableDevice = 6
+    enumerator :: PointerManaged = 7, AllocatableManaged = 8
+    enumerator :: PointerUnified = 9, AllocatableUnified = 10
   end enum
 
   enum, bind(c) ! common::TypeCategory
diff --git a/flang/test/Lower/CUDA/cuda-allocatable-device.cuf b/flang/test/Lower/CUDA/cuda-allocatable-device.cuf
index 57c588e5beafa..428aec073fbb6 100644
--- a/flang/test/Lower/CUDA/cuda-allocatable-device.cuf
+++ b/flang/test/Lower/CUDA/cuda-allocatable-device.cuf
@@ -6,17 +6,39 @@ module m
     real(kind=8), pointer, dimension(:), device :: pd
   end type
 
+  type managed_array
+    real(kind=8), allocatable, dimension(:), managed :: ad
+    real(kind=8), pointer, dimension(:), managed :: pd
+  end type
+
+  type unified_array
+    real(kind=8), allocatable, dimension(:), unified :: ad
+    real(kind=8), pointer, dimension(:), unified :: pd
+  end type
+
   type(device_array), allocatable :: da(:)
+  type(managed_array), allocatable :: ma(:)
+  type(unified_array), allocatable :: ua(:)
 end module
 
 ! CHECK-LABEL: fir.global linkonce_odr @_QMmE.c.device_array
 ! CHECK: fir.insert_value %{{.*}}, %c6{{.*}}, ["genre"
 ! CHECK: fir.insert_value %{{.*}}, %c5{{.*}}, ["genre"
 
+! CHECK-LABEL: fir.global linkonce_odr @_QMmE.c.managed_array
+! CHECK: fir.insert_value %{{.*}}, %c8{{.*}}, ["genre"
+! CHECK: fir.insert_value %{{.*}}, %c7{{.*}}, ["genre"
+
+! CHECK-LABEL: fir.global linkonce_odr @_QMmE.c.unified_array
+! CHECK: fir.insert_value %{{.*}}, %c10{{.*}}, ["genre"
+! CHECK: fir.insert_value %{{.*}}, %c9{{.*}}, ["genre"
+
 program main
   use m
   type(device_array) :: local
+  type(managed_array) :: local_ma
+  type(unified_array) :: local_ua
 end
 
 ! CHECK-LABEL: func.func @_QQmain()
-! CHECK: fir.call @_FortranAInitialize
+! CHECK-COUNT-3: fir.call @_FortranAInitialize

>From 7c7663f35235224ce6e1d783f35321cba18c5e23 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Thu, 22 Jan 2026 12:09:09 -0800
Subject: [PATCH 2/4] Separate memorySpace from genre

---
 flang-rt/include/flang-rt/runtime/type-info.h | 18 +++++----
 flang-rt/lib/runtime/assign.cpp               |  8 +---
 flang-rt/lib/runtime/copy.cpp                 |  6 ---
 flang-rt/lib/runtime/derived.cpp              | 31 +++-------------
 flang-rt/lib/runtime/type-info.cpp            | 37 ++++---------------
 flang/lib/Semantics/runtime-type-info.cpp     | 35 ++++++------------
 flang/module/__fortran_type_info.f90          | 10 +++--
 .../Lower/CUDA/cuda-allocatable-device.cuf    | 20 +++++++---
 flang/test/Lower/volatile-openmp.f90          |  8 ++--
 flang/test/Semantics/typeinfo01.f90           | 14 +++----
 flang/test/Semantics/typeinfo08.f90           |  2 +-
 11 files changed, 68 insertions(+), 121 deletions(-)

diff --git a/flang-rt/include/flang-rt/runtime/type-info.h b/flang-rt/include/flang-rt/runtime/type-info.h
index 89f70c1a23d51..d07a673fdbfb0 100644
--- a/flang-rt/include/flang-rt/runtime/type-info.h
+++ b/flang-rt/include/flang-rt/runtime/type-info.h
@@ -55,17 +55,19 @@ class Component {
     Data = 1,
     Pointer = 2,
     Allocatable = 3,
-    Automatic = 4,
-    PointerDevice = 5,
-    AllocatableDevice = 6,
-    PointerManaged = 7,
-    AllocatableManaged = 8,
-    PointerUnified = 9,
-    AllocatableUnified = 10
+    Automatic = 4
+  };
+
+  enum class MemorySpace : std::uint8_t {
+    Host = 0,
+    Device = 1,
+    Managed = 2,
+    Unified = 3
   };
 
   RT_API_ATTRS const Descriptor &name() const { return name_.descriptor(); }
   RT_API_ATTRS Genre genre() const { return genre_; }
+  RT_API_ATTRS MemorySpace memorySpace() const { return memorySpace_; }
   RT_API_ATTRS TypeCategory category() const {
     return static_cast<TypeCategory>(category_);
   }
@@ -111,6 +113,8 @@ class Component {
   std::uint8_t category_; // common::TypeCategory
   std::uint8_t kind_{0};
   std::uint8_t rank_{0};
+  std::uint8_t memorySpace_{0}; // memory space of the component
+  std::uint8_t padding_[3]; // 3 bytes padding
   std::uint64_t offset_{0};
   Value characterLen_; // for TypeCategory::Character
   StaticDescriptor<0, true> derivedType_; // TYPE(DERIVEDTYPE), POINTER
diff --git a/flang-rt/lib/runtime/assign.cpp b/flang-rt/lib/runtime/assign.cpp
index d3b9d565c620d..0d0710382a055 100644
--- a/flang-rt/lib/runtime/assign.cpp
+++ b/flang-rt/lib/runtime/assign.cpp
@@ -648,10 +648,7 @@ RT_API_ATTRS int DerivedAssignTicket<IS_COMPONENTWISE>::Continue(
         }
       }
       break;
-    case typeInfo::Component::Genre::Pointer:
-    case typeInfo::Component::Genre::PointerDevice:
-    case typeInfo::Component::Genre::PointerManaged:
-    case typeInfo::Component::Genre::PointerUnified: {
+    case typeInfo::Component::Genre::Pointer: {
       std::size_t componentByteSize{
           this->component_->SizeInBytes(this->instance_)};
       if (IS_COMPONENTWISE && toIsContiguous_ && fromIsContiguous_) {
@@ -683,9 +680,6 @@ RT_API_ATTRS int DerivedAssignTicket<IS_COMPONENTWISE>::Continue(
       }
     } break;
     case typeInfo::Component::Genre::Allocatable:
-    case typeInfo::Component::Genre::AllocatableDevice:
-    case typeInfo::Component::Genre::AllocatableManaged:
-    case typeInfo::Component::Genre::AllocatableUnified:
     case typeInfo::Component::Genre::Automatic: {
       auto *toDesc{reinterpret_cast<Descriptor *>(
           this->instance_.template Element<char>(this->subscripts_) +
diff --git a/flang-rt/lib/runtime/copy.cpp b/flang-rt/lib/runtime/copy.cpp
index d1d35d2bbd686..1db8962dad0d3 100644
--- a/flang-rt/lib/runtime/copy.cpp
+++ b/flang-rt/lib/runtime/copy.cpp
@@ -168,12 +168,6 @@ RT_API_ATTRS void CopyElement(const Descriptor &to, const SubscriptValue toAt[],
         std::size_t nComponents{componentDesc.Elements()};
         for (std::size_t j{0}; j < nComponents; ++j, ++component) {
           if (component->genre() == typeInfo::Component::Genre::Allocatable ||
-              component->genre() ==
-                  typeInfo::Component::Genre::AllocatableDevice ||
-              component->genre() ==
-                  typeInfo::Component::Genre::AllocatableManaged ||
-              component->genre() ==
-                  typeInfo::Component::Genre::AllocatableUnified ||
               component->genre() == typeInfo::Component::Genre::Automatic) {
             Descriptor &toDesc{
                 *reinterpret_cast<Descriptor *>(toPtr + component->offset())};
diff --git a/flang-rt/lib/runtime/derived.cpp b/flang-rt/lib/runtime/derived.cpp
index 8aa6be510a13a..0035dd9d434f8 100644
--- a/flang-rt/lib/runtime/derived.cpp
+++ b/flang-rt/lib/runtime/derived.cpp
@@ -64,10 +64,7 @@ RT_API_ATTRS int InitializeTicket::Continue(WorkQueue &workQueue) {
   char *rawInstance{instance_.OffsetElement<char>()};
   for (; !Componentwise::IsComplete(); SkipToNextComponent()) {
     char *rawComponent{rawInstance + component_->offset()};
-    if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableDevice ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableManaged ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableUnified) {
+    if (component_->genre() == typeInfo::Component::Genre::Allocatable) {
       Descriptor &allocDesc{*reinterpret_cast<Descriptor *>(rawComponent)};
       component_->EstablishDescriptor(
           allocDesc, instance_, workQueue.terminator());
@@ -80,10 +77,7 @@ RT_API_ATTRS int InitializeTicket::Continue(WorkQueue &workQueue) {
       } else {
         Fortran::runtime::memcpy(rawComponent, init, bytes);
       }
-    } else if (component_->genre() == typeInfo::Component::Genre::Pointer ||
-        component_->genre() == typeInfo::Component::Genre::PointerDevice ||
-        component_->genre() == typeInfo::Component::Genre::PointerManaged ||
-        component_->genre() == typeInfo::Component::Genre::PointerUnified) {
+    } else if (component_->genre() == typeInfo::Component::Genre::Pointer) {
       // Data pointers without explicit initialization are established
       // so that they are valid right-hand side targets of pointer
       // assignment statements.
@@ -167,10 +161,7 @@ RT_API_ATTRS int InitializeClone(const Descriptor &clone,
 
 RT_API_ATTRS int InitializeCloneTicket::Continue(WorkQueue &workQueue) {
   while (!IsComplete()) {
-    if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableDevice ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableManaged ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableUnified) {
+    if (component_->genre() == typeInfo::Component::Genre::Allocatable) {
       Descriptor &origDesc{*instance_.ElementComponent<Descriptor>(
           subscripts_, component_->offset())};
       if (origDesc.IsAllocated()) {
@@ -347,13 +338,7 @@ RT_API_ATTRS int FinalizeTicket::Begin(WorkQueue &workQueue) {
 
 RT_API_ATTRS int FinalizeTicket::Continue(WorkQueue &workQueue) {
   while (!IsComplete()) {
-    if ((component_->genre() == typeInfo::Component::Genre::Allocatable ||
-            component_->genre() ==
-                typeInfo::Component::Genre::AllocatableDevice ||
-            component_->genre() ==
-                typeInfo::Component::Genre::AllocatableManaged ||
-            component_->genre() ==
-                typeInfo::Component::Genre::AllocatableUnified) &&
+    if (component_->genre() == typeInfo::Component::Genre::Allocatable &&
         component_->category() == TypeCategory::Derived) {
       // Component may be polymorphic or unlimited polymorphic. Need to use the
       // dynamic type to check whether finalization is needed.
@@ -375,9 +360,6 @@ RT_API_ATTRS int FinalizeTicket::Continue(WorkQueue &workQueue) {
         }
       }
     } else if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableDevice ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableManaged ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableUnified ||
         component_->genre() == typeInfo::Component::Genre::Automatic) {
       if (const typeInfo::DerivedType *compType{component_->derivedType()};
           compType && !compType->noFinalizationNeeded()) {
@@ -460,10 +442,7 @@ RT_API_ATTRS int DestroyTicket::Continue(WorkQueue &workQueue) {
   // Contrary to finalization, the order of deallocation does not matter.
   while (!IsComplete()) {
     const auto *componentDerived{component_->derivedType()};
-    if (component_->genre() == typeInfo::Component::Genre::Allocatable ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableDevice ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableManaged ||
-        component_->genre() == typeInfo::Component::Genre::AllocatableUnified) {
+    if (component_->genre() == typeInfo::Component::Genre::Allocatable) {
       if (fixedStride_ &&
           (!componentDerived || componentDerived->noDestructionNeeded())) {
         // common fast path, just deallocate in every element
diff --git a/flang-rt/lib/runtime/type-info.cpp b/flang-rt/lib/runtime/type-info.cpp
index 99bf48b5def36..cb8e894bd3922 100644
--- a/flang-rt/lib/runtime/type-info.cpp
+++ b/flang-rt/lib/runtime/type-info.cpp
@@ -95,23 +95,16 @@ RT_API_ATTRS std::size_t Component::SizeInBytes(
 RT_API_ATTRS void Component::EstablishDescriptor(Descriptor &descriptor,
     const Descriptor &container, Terminator &terminator) const {
   ISO::CFI_attribute_t attribute{static_cast<ISO::CFI_attribute_t>(
-      genre_ == Genre::Allocatable || genre_ == Genre::AllocatableDevice ||
-              genre_ == Genre::AllocatableManaged ||
-              genre_ == Genre::AllocatableUnified
-          ? CFI_attribute_allocatable
-          : genre_ == Genre::Pointer || genre_ == Genre::PointerDevice ||
-              genre_ == Genre::PointerManaged || genre_ == Genre::PointerUnified
-          ? CFI_attribute_pointer
-          : CFI_attribute_other)};
+      genre_ == Genre::Allocatable   ? CFI_attribute_allocatable
+          : genre_ == Genre::Pointer ? CFI_attribute_pointer
+                                     : CFI_attribute_other)};
   TypeCategory cat{category()};
   unsigned allocatorIdx{kDefaultAllocator};
-  if (genre_ == Genre::AllocatableDevice || genre_ == Genre::PointerDevice) {
+  if (memorySpace_ == MemorySpace::Device) {
     allocatorIdx = kDeviceAllocatorPos;
-  } else if (genre_ == Genre::AllocatableManaged ||
-      genre_ == Genre::PointerManaged) {
+  } else if (memorySpace_ == MemorySpace::Managed) {
     allocatorIdx = kManagedAllocatorPos;
-  } else if (genre_ == Genre::AllocatableUnified ||
-      genre_ == Genre::PointerUnified) {
+  } else if (memorySpace_ == MemorySpace::Unified) {
     allocatorIdx = kUnifiedAllocatorPos;
   }
   if (cat == TypeCategory::Character) {
@@ -136,10 +129,7 @@ RT_API_ATTRS void Component::EstablishDescriptor(Descriptor &descriptor,
     descriptor.Establish(
         cat, kind_, nullptr, rank_, nullptr, attribute, false, allocatorIdx);
   }
-  if (rank_ && genre_ != Genre::Allocatable && genre_ != Genre::Pointer &&
-      genre_ != Genre::AllocatableDevice && genre_ != Genre::PointerDevice &&
-      genre_ != Genre::AllocatableManaged && genre_ != Genre::PointerManaged &&
-      genre_ != Genre::AllocatableUnified && genre_ != Genre::PointerUnified) {
+  if (rank_ && genre_ != Genre::Allocatable && genre_ != Genre::Pointer) {
     const typeInfo::Value *boundValues{bounds()};
     RUNTIME_CHECK(terminator, boundValues != nullptr);
     auto byteStride{static_cast<SubscriptValue>(descriptor.ElementBytes())};
@@ -290,25 +280,14 @@ FILE *Component::Dump(FILE *f) const {
     std::fputs("    Data            ", f);
   } else if (genre_ == Genre::Pointer) {
     std::fputs("    Pointer          ", f);
-  } else if (genre_ == Genre::PointerDevice) {
-    std::fputs("    PointerDevice    ", f);
-  } else if (genre_ == Genre::PointerManaged) {
-    std::fputs("    PointerManaged   ", f);
-  } else if (genre_ == Genre::PointerUnified) {
-    std::fputs("    PointerUnified   ", f);
   } else if (genre_ == Genre::Allocatable) {
     std::fputs("    Allocatable.     ", f);
-  } else if (genre_ == Genre::AllocatableDevice) {
-    std::fputs("    AllocatableDevice", f);
-  } else if (genre_ == Genre::AllocatableManaged) {
-    std::fputs("    AllocatableManaged", f);
-  } else if (genre_ == Genre::AllocatableUnified) {
-    std::fputs("    AllocatableUnified", f);
   } else if (genre_ == Genre::Automatic) {
     std::fputs("    Automatic        ", f);
   } else {
     std::fprintf(f, "    (bad genre 0x%x)", static_cast<int>(genre_));
   }
+  // TODO: valentin
   std::fprintf(f, " category %d  kind %d  rank %d  offset 0x%zx\n", category_,
       kind_, rank_, static_cast<std::size_t>(offset_));
   const auto &dtDesc{derivedType_.descriptor()};
diff --git a/flang/lib/Semantics/runtime-type-info.cpp b/flang/lib/Semantics/runtime-type-info.cpp
index b6c712ecdae20..2cee1e23646d0 100644
--- a/flang/lib/Semantics/runtime-type-info.cpp
+++ b/flang/lib/Semantics/runtime-type-info.cpp
@@ -889,31 +889,9 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
   // Default component initialization
   bool hasDataInit{false};
   if (IsAllocatable(symbol)) {
-    if (isDevice) {
-      AddValue(values, componentSchema_, "genre"s,
-          GetEnumValue("allocatabledevice"));
-    } else if (isManaged) {
-      AddValue(values, componentSchema_, "genre"s,
-          GetEnumValue("allocatablemanaged"));
-    } else if (isUnified) {
-      AddValue(values, componentSchema_, "genre"s,
-          GetEnumValue("allocatableunified"));
-    } else {
-      AddValue(values, componentSchema_, "genre"s, GetEnumValue("allocatable"));
-    }
+    AddValue(values, componentSchema_, "genre"s, GetEnumValue("allocatable"));
   } else if (IsPointer(symbol)) {
-    if (isDevice) {
-      AddValue(
-          values, componentSchema_, "genre"s, GetEnumValue("pointerdevice"));
-    } else if (isManaged) {
-      AddValue(
-          values, componentSchema_, "genre"s, GetEnumValue("pointermanaged"));
-    } else if (isUnified) {
-      AddValue(
-          values, componentSchema_, "genre"s, GetEnumValue("pointerunified"));
-    } else {
-      AddValue(values, componentSchema_, "genre"s, GetEnumValue("pointer"));
-    }
+    AddValue(values, componentSchema_, "genre"s, GetEnumValue("pointer"));
     hasDataInit = InitializeDataPointer(
         values, symbol, object, scope, dtScope, distinctName);
   } else if (IsAutomatic(symbol)) {
@@ -930,6 +908,15 @@ evaluate::StructureConstructor RuntimeTableBuilder::DescribeComponent(
               object));
     }
   }
+  if (isDevice) {
+    AddValue(values, componentSchema_, "memoryspace"s, GetEnumValue("device"));
+  } else if (isManaged) {
+    AddValue(values, componentSchema_, "memoryspace"s, GetEnumValue("managed"));
+  } else if (isUnified) {
+    AddValue(values, componentSchema_, "memoryspace"s, GetEnumValue("unified"));
+  } else {
+    AddValue(values, componentSchema_, "memoryspace"s, GetEnumValue("host"));
+  }
   if (!hasDataInit) {
     AddValue(values, componentSchema_, "initialization"s,
         SomeExpr{evaluate::NullPointer{}});
diff --git a/flang/module/__fortran_type_info.f90 b/flang/module/__fortran_type_info.f90
index a8d9959feb872..0f1c3d018d009 100644
--- a/flang/module/__fortran_type_info.f90
+++ b/flang/module/__fortran_type_info.f90
@@ -76,9 +76,10 @@
 
   enum, bind(c) ! Component::Genre
     enumerator :: Data = 1, Pointer = 2, Allocatable = 3, Automatic = 4
-    enumerator :: PointerDevice = 5, AllocatableDevice = 6
-    enumerator :: PointerManaged = 7, AllocatableManaged = 8
-    enumerator :: PointerUnified = 9, AllocatableUnified = 10
+  end enum
+
+  enum, bind(c) ! Component::MemorySpace
+    enumerator :: Host = 0, Device = 1, Managed = 2, Unified = 3
   end enum
 
   enum, bind(c) ! common::TypeCategory
@@ -93,7 +94,8 @@
     integer(1) :: category
     integer(1) :: kind
     integer(1) :: rank
-    integer(1) :: __padding0(4)
+    integer(1) :: memorySpace ! Component::MemorySpace
+    integer(1) :: __padding0(3)
     integer(kind=int64) :: offset
     type(Value) :: characterLen ! for category == Character
     type(DerivedType), pointer :: derived ! for category == Derived
diff --git a/flang/test/Lower/CUDA/cuda-allocatable-device.cuf b/flang/test/Lower/CUDA/cuda-allocatable-device.cuf
index 428aec073fbb6..9c293872d1017 100644
--- a/flang/test/Lower/CUDA/cuda-allocatable-device.cuf
+++ b/flang/test/Lower/CUDA/cuda-allocatable-device.cuf
@@ -1,37 +1,45 @@
 ! RUN: bbc -emit-hlfir -fcuda %s -o - | FileCheck %s
+! RUN: bbc --dump-symbols -fcuda %s -o - | FileCheck %s --check-prefix=SYMBOLS
+
 
 module m
+
+! SYMBOLS-LABEL: Module scope: m
+
   type device_array
     real(kind=8), allocatable, dimension(:), device :: ad
     real(kind=8), pointer, dimension(:), device :: pd
   end type
 
+! SYMBOLS: .c.device_array, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:1_8 init:[component::component(name=.n.ad,genre=3_1,category=2_1,kind=8_1,rank=1_1,memoryspace=1_1,offset=0_8
+
   type managed_array
     real(kind=8), allocatable, dimension(:), managed :: ad
     real(kind=8), pointer, dimension(:), managed :: pd
   end type
 
+! SYMBOLS: .c.managed_array, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:1_8 init:[component::component(name=.n.ad,genre=3_1,category=2_1,kind=8_1,rank=1_1,memoryspace=2_1,offset=0_8
+
   type unified_array
     real(kind=8), allocatable, dimension(:), unified :: ad
     real(kind=8), pointer, dimension(:), unified :: pd
   end type
 
+!  SYMBOLS: .c.unified_array, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:1_8 init:[component::component(name=.n.ad,genre=3_1,category=2_1,kind=8_1,rank=1_1,memoryspace=3_1
+
   type(device_array), allocatable :: da(:)
   type(managed_array), allocatable :: ma(:)
   type(unified_array), allocatable :: ua(:)
 end module
 
 ! CHECK-LABEL: fir.global linkonce_odr @_QMmE.c.device_array
-! CHECK: fir.insert_value %{{.*}}, %c6{{.*}}, ["genre"
-! CHECK: fir.insert_value %{{.*}}, %c5{{.*}}, ["genre"
+! CHECK: fir.insert_value %{{.*}}, %c1{{.*}}, ["memoryspace"
 
 ! CHECK-LABEL: fir.global linkonce_odr @_QMmE.c.managed_array
-! CHECK: fir.insert_value %{{.*}}, %c8{{.*}}, ["genre"
-! CHECK: fir.insert_value %{{.*}}, %c7{{.*}}, ["genre"
+! CHECK: fir.insert_value %{{.*}}, %c2{{.*}}, ["memoryspace"
 
 ! CHECK-LABEL: fir.global linkonce_odr @_QMmE.c.unified_array
-! CHECK: fir.insert_value %{{.*}}, %c10{{.*}}, ["genre"
-! CHECK: fir.insert_value %{{.*}}, %c9{{.*}}, ["genre"
+! CHECK: fir.insert_value %{{.*}}, %c3{{.*}}, ["memoryspace"
 
 program main
   use m
diff --git a/flang/test/Lower/volatile-openmp.f90 b/flang/test/Lower/volatile-openmp.f90
index fb6cee40c71db..67949ac6362f2 100644
--- a/flang/test/Lower/volatile-openmp.f90
+++ b/flang/test/Lower/volatile-openmp.f90
@@ -23,11 +23,11 @@
 ! CHECK:           %[[VAL_11:.*]] = fir.address_of(@_QFEcontainer) : !fir.ref<!fir.type<_QFTt{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>
 ! CHECK:           %[[VAL_12:.*]] = fir.volatile_cast %[[VAL_11]] : (!fir.ref<!fir.type<_QFTt{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.type<_QFTt{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>, volatile>
 ! CHECK:           %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_12]] {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QFEcontainer"} : (!fir.ref<!fir.type<_QFTt{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>, volatile>) -> (!fir.ref<!fir.type<_QFTt{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>, volatile>, !fir.ref<!fir.type<_QFTt{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>, volatile>)
-! CHECK:           %[[VAL_14:.*]] = fir.address_of(@_QFE.c.t) : !fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{{[<]?}}{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>
+! CHECK:           %[[VAL_14:.*]] = fir.address_of(@_QFE.c.t) : !fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>> 
 ! CHECK:           %[[VAL_15:.*]] = fir.shape_shift %[[VAL_0]], %[[VAL_1]] : (index, index) -> !fir.shapeshift<1>
-! CHECK:           %[[VAL_16:.*]]:2 = hlfir.declare %[[VAL_14]](%[[VAL_15]]) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.c.t"} : (!fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{{[<]?}}{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.shapeshift<1>) -> (!fir.box<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{{[<]?}}{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{{[<]?}}{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>)
-! CHECK:           %[[VAL_17:.*]] = fir.address_of(@_QFE.dt.t) : !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{{[<]?}}{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>
-! CHECK:           %[[VAL_18:.*]]:2 = hlfir.declare %[[VAL_17]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.dt.t"} : (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{{[<]?}}{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>) -> (!fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{{[<]?}}{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>, !fir.ref<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,__padding0:!fir.array<4xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{{[<]?}}{genre:i8,__padding0:!fir.array<7xi8>,value:i64}{{[>]?}}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{{[<]?}}{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}{{[>]?}}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>)
+! CHECK:           %[[VAL_16:.*]]:2 = hlfir.declare %[[VAL_14]](%[[VAL_15]]) {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.c.t"} : (!fir.ref<!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,genre:i8,category:i8,kind:i8,rank:i8,memoryspace:i8,__padding0:!fir.array<3xi8>,offset:i64,characterlen:!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>,derived:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTbinding{proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>}>>>>,name:!fir.box<!fir.ptr<!fir.char<1,?>>>,sizeinbytes:i64,uninstantiated:!fir.box<!fir.ptr<!fir.type<_QM__fortran_type_infoTderivedtype>>>,kindparameter:!fir.box<!fir.ptr<!fir.array<?xi64>>>,lenparameterkind:!fir.box<!fir.ptr<!fir.array<?xi8>>>,component:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTcomponent>>>>,procptr:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTprocptrcomponent{name:!fir.box<!fir.ptr<!fir.char<1,?>>>,offset:i64,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTspecialbinding{which:i8,isargdescriptorset:i8,istypebound:i8,specialcaseflag:i8,__padding0:!fir.array<4xi8>,proc:!fir.type<_QM__fortran_builtinsT__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,nodefinedassignment:i8,__padding0:!fir.array<3xi8>}>>>,lenvalue:!fir.box<!fir.ptr<!fir.array<?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,bounds:!fir.box<!fir.ptr<!fir.array<?x?x!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>>>>,initialization:!fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>}>>>, !fir.shapeshift<1>) -> (!fir.box<{{.*}}>)
+! CHECK:           %[[VAL_17:.*]] = fir.address_of(@_QFE.dt.t) : !fir.ref<{{.*}}>
+! CHECK:           %[[VAL_18:.*]]:2 = hlfir.declare %[[VAL_17]] {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFE.dt.t"}
 ! CHECK:           %[[VAL_19:.*]] = hlfir.designate %[[VAL_13]]#0{"array"}   {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QFTt{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>, volatile>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>, volatile>
 ! CHECK:           %[[VAL_20:.*]] = fir.load %[[VAL_19]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>, volatile>
 ! CHECK:           %[[VAL_21:.*]]:3 = fir.box_dims %[[VAL_20]], %[[VAL_0]] : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
diff --git a/flang/test/Semantics/typeinfo01.f90 b/flang/test/Semantics/typeinfo01.f90
index aeec336ea58ea..bc433a131695a 100644
--- a/flang/test/Semantics/typeinfo01.f90
+++ b/flang/test/Semantics/typeinfo01.f90
@@ -7,7 +7,7 @@ module m01
     integer :: n
   end type
 !CHECK: Module scope: m01
-!CHECK: .c.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.n,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
+!CHECK: .c.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.n,genre=1_1,category=0_1,kind=4_1,rank=0_1,memoryspace=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
 !CHECK: .dt.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t1,sizeinbytes=4_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t1,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1)
 !CHECK: .n.n, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: CHARACTER(1_8,1) init:"n"
 !CHECK: .n.t1, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: CHARACTER(2_8,1) init:"t1"
@@ -21,8 +21,8 @@ module m02
   type, extends(parent) :: child
     integer :: cn
   end type
-!CHECK: .c.child, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:1_8 init:[component::component(name=.n.parent,genre=1_1,category=6_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.parent,lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.cn,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=4_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
-!CHECK: .c.parent, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.pn,genre=1_1,category=0_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
+!CHECK: .c.child, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:1_8 init:[component::component(name=.n.parent,genre=1_1,category=6_1,kind=0_1,rank=0_1,memoryspace=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.parent,lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.cn,genre=1_1,category=0_1,kind=4_1,rank=0_1,memoryspace=0_1,offset=4_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
+!CHECK: .c.parent, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.pn,genre=1_1,category=0_1,kind=4_1,rank=0_1,memoryspace=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
 !CHECK: .dt.child, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.child,sizeinbytes=8_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.child,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1)
 !CHECK: .dt.parent, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.parent,sizeinbytes=4_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.parent,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1)
 end module
@@ -33,7 +33,7 @@ module m03
     real(kind=k) :: a
   end type
   type(kpdt(4)) :: x
-!CHECK: .c.kpdt.4, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.a,genre=1_1,category=2_1,kind=4_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
+!CHECK: .c.kpdt.4, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.a,genre=1_1,category=2_1,kind=4_1,rank=0_1,memoryspace=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
 !CHECK: .dt.kpdt, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(name=.n.kpdt,uninstantiated=NULL(),kindparameter=.kp.kpdt,lenparameterkind=NULL())
 !CHECK: .dt.kpdt.4, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.kpdt,sizeinbytes=4_8,uninstantiated=.dt.kpdt,kindparameter=.kp.kpdt.4,lenparameterkind=NULL(),component=.c.kpdt.4,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1)
 !CHECK: .kp.kpdt.4, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: INTEGER(8) shape: 0_8:0_8 init:[INTEGER(8)::4_8]
@@ -84,7 +84,7 @@ subroutine s2(x, y)
     class(t2), intent(out) :: x
     class(t), intent(in) :: y
   end subroutine
-!CHECK: .c.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t,genre=1_1,category=6_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.t,lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
+!CHECK: .c.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t,genre=1_1,category=6_1,kind=0_1,rank=0_1,memoryspace=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.t,lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
 !CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=2_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1)
 !CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=.s.t2,specialbitset=2_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1)
 !CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,istypebound=1_1,specialcaseflag=0_1,proc=s1)]
@@ -112,7 +112,7 @@ subroutine s2(x, y)
     class(t), intent(out) :: x
     class(t2), intent(in) :: y
   end subroutine
-!CHECK: .c.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t,genre=1_1,category=6_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.t,lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
+!CHECK: .c.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t,genre=1_1,category=6_1,kind=0_1,rank=0_1,memoryspace=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=.dt.t,lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
 !CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t,name=.n.t,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=NULL(),procptr=NULL(),special=.s.t,specialbitset=2_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1)
 !CHECK: .dt.t2, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=.v.t2,name=.n.t2,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=NULL(),component=.c.t2,procptr=NULL(),special=.s.t2,specialbitset=2_4,hasparent=1_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=0_1)
 !CHECK: .s.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(specialbinding) shape: 0_8:0_8 init:[specialbinding::specialbinding(which=1_1,isargdescriptorset=3_1,istypebound=1_1,specialcaseflag=0_1,proc=s1)]
@@ -260,7 +260,7 @@ module m11
     real :: automatic(len)
   end type
 !CHECK: .b.t.automatic, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(value) shape: 0_8:1_8,0_8:0_8 init:reshape([value::value(genre=2_1,value=1_8),value(genre=3_1,value=0_8)],shape=[2,1])
-!CHECK: .c.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:3_8 init:[component::component(name=.n.allocatable,genre=3_1,category=2_1,kind=4_1,rank=1_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.pointer,genre=2_1,category=2_1,kind=4_1,rank=0_1,offset=48_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=.di.t.pointer),component(name=.n.chauto,genre=4_1,category=4_1,kind=1_1,rank=0_1,offset=72_8,characterlen=value(genre=3_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.automatic,genre=4_1,category=2_1,kind=4_1,rank=1_1,offset=96_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=.b.t.automatic,initialization=NULL())]
+!CHECK: .c.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:3_8 init:[component::component(name=.n.allocatable,genre=3_1,category=2_1,kind=4_1,rank=1_1,memoryspace=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.pointer,genre=2_1,category=2_1,kind=4_1,rank=0_1,memoryspace=0_1,offset=48_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=.di.t.pointer),component(name=.n.chauto,genre=4_1,category=4_1,kind=1_1,rank=0_1,memoryspace=0_1,offset=72_8,characterlen=value(genre=3_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=NULL(),initialization=NULL()),component(name=.n.automatic,genre=4_1,category=2_1,kind=4_1,rank=1_1,memoryspace=0_1,offset=96_8,characterlen=value(genre=1_1,value=0_8),derived=NULL(),lenvalue=NULL(),bounds=.b.t.automatic,initialization=NULL())]
 !CHECK: .di.t.pointer, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(.dp.t.pointer) init:.dp.t.pointer(pointer=target)
 !CHECK: .dp.t.pointer (CompilerCreated): DerivedType components: pointer
 !CHECK: .dt.t, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.t,sizeinbytes=144_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=.lpk.t,component=.c.t,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=0_1,nodestructionneeded=0_1,nofinalizationneeded=1_1,nodefinedassignment=1_1)
diff --git a/flang/test/Semantics/typeinfo08.f90 b/flang/test/Semantics/typeinfo08.f90
index 391a66f3d6664..5da31ad64e55a 100644
--- a/flang/test/Semantics/typeinfo08.f90
+++ b/flang/test/Semantics/typeinfo08.f90
@@ -12,7 +12,7 @@ module m
 end module
 
 !CHECK: Module scope: m size=0 alignment=1 sourceRange=113 bytes
-!CHECK: .c.s, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t1,genre=1_1,category=6_1,kind=0_1,rank=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
+!CHECK: .c.s, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(component) shape: 0_8:0_8 init:[component::component(name=.n.t1,genre=1_1,category=6_1,kind=0_1,rank=0_1,memoryspace=0_1,offset=0_8,characterlen=value(genre=1_1,value=0_8),lenvalue=NULL(),bounds=NULL(),initialization=NULL())]
 !CHECK: .dt.s, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: TYPE(derivedtype) init:derivedtype(binding=NULL(),name=.n.s,sizeinbytes=0_8,uninstantiated=NULL(),kindparameter=NULL(),lenparameterkind=.lpk.s,component=.c.s,procptr=NULL(),special=NULL(),specialbitset=0_4,hasparent=0_1,noinitializationneeded=1_1,nodestructionneeded=1_1,nofinalizationneeded=1_1,nodefinedassignment=1_1)
 !CHECK: .lpk.s, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: INTEGER(1) shape: 0_8:0_8 init:[INTEGER(1)::4_1]
 !CHECK: .n.s, SAVE, TARGET (CompilerCreated, ReadOnly): ObjectEntity type: CHARACTER(1_8,1) init:"s"

>From 03e011528195b5201569b19caa9e85de471d3bb9 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Thu, 22 Jan 2026 12:36:57 -0800
Subject: [PATCH 3/4] Fix build issue

---
 flang-rt/include/flang-rt/runtime/type-info.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang-rt/include/flang-rt/runtime/type-info.h b/flang-rt/include/flang-rt/runtime/type-info.h
index d07a673fdbfb0..21a5dc767e7a1 100644
--- a/flang-rt/include/flang-rt/runtime/type-info.h
+++ b/flang-rt/include/flang-rt/runtime/type-info.h
@@ -113,7 +113,7 @@ class Component {
   std::uint8_t category_; // common::TypeCategory
   std::uint8_t kind_{0};
   std::uint8_t rank_{0};
-  std::uint8_t memorySpace_{0}; // memory space of the component
+  MemorySpace memorySpace_{MemorySpace::Host}; // memory space of the component
   std::uint8_t padding_[3]; // 3 bytes padding
   std::uint64_t offset_{0};
   Value characterLen_; // for TypeCategory::Character

>From ea6d88b319a8d939e07665160f52c881c3b958f4 Mon Sep 17 00:00:00 2001
From: Valentin Clement <clementval at gmail.com>
Date: Thu, 22 Jan 2026 12:51:08 -0800
Subject: [PATCH 4/4] Add [[maybe_ununsed]] for padding field

---
 flang-rt/include/flang-rt/runtime/type-info.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/flang-rt/include/flang-rt/runtime/type-info.h b/flang-rt/include/flang-rt/runtime/type-info.h
index 21a5dc767e7a1..e112ee418dcf3 100644
--- a/flang-rt/include/flang-rt/runtime/type-info.h
+++ b/flang-rt/include/flang-rt/runtime/type-info.h
@@ -114,7 +114,7 @@ class Component {
   std::uint8_t kind_{0};
   std::uint8_t rank_{0};
   MemorySpace memorySpace_{MemorySpace::Host}; // memory space of the component
-  std::uint8_t padding_[3]; // 3 bytes padding
+  [[maybe_unused]] std::uint8_t padding_[3]; // 3 bytes padding
   std::uint64_t offset_{0};
   Value characterLen_; // for TypeCategory::Character
   StaticDescriptor<0, true> derivedType_; // TYPE(DERIVEDTYPE), POINTER



More information about the llvm-commits mailing list