[flang-commits] [flang] [flang] Respect record type changes in FIR alias analysis access paths (PR #231655)

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Thu Oct 15 14:49:32 PDT 2026


================
@@ -573,15 +576,90 @@ static bool noAliasBasedOnType(mlir::Value lhs, mlir::Value rhs) {
   return false;
 }
 
-/// Return true if two access paths from the same origin variable diverge at
-/// a named component step, meaning they address disjoint subobjects of the
-/// root variable. For example, paths [Component("a")] and [Component("b")]
-/// diverge immediately, while [Component("a"), Component("x")] and
-/// [Component("a"), Component("y")] share a common prefix "a" and diverge
-/// at the second step.
+/// Return true if an object of type \p ty contains, or is, an object of type
+/// \p subTy (through array elements and components, not through
+/// descriptors).
+static bool typeContains(mlir::Type ty, mlir::Type subTy) {
+  if (ty == subTy)
+    return true;
+  if (auto seqTy = mlir::dyn_cast<fir::SequenceType>(ty))
+    return typeContains(seqTy.getElementType(), subTy);
+  if (auto recTy = mlir::dyn_cast<fir::RecordType>(ty))
+    return llvm::any_of(recTy.getTypeList(), [&](const auto &field) {
+      return typeContains(field.second, subTy);
+    });
+  return false;
+}
+
+/// Return the type of the parent component of \p recTy, if any. The parent
+/// component is the first component, named after the parent type.
+static fir::RecordType getParentType(fir::RecordType recTy) {
+  if (recTy.getNumFields() == 0)
+    return {};
+  const auto &[name, fieldTy] = recTy.getTypeList().front();
+  auto parentTy = mlir::dyn_cast<fir::RecordType>(fieldTy);
+  if (!parentTy ||
+      fir::NameUniquer::deconstruct(parentTy.getName()).second.name != name)
----------------
vzakhari wrote:

Good catch! By its name, a component named after its type cannot be told apart from a parent component, and a SEQUENCE or BIND(C) type from another scope may be the same type as the type of such a component. The parent type is now taken from the `fir.type_info` of the extended type, and a type without `fir.type_info` is not treated as an extension.

As far as I can tell, this program does not fail end-to-end: `obj%other` is only accessed through a dummy of the other type after `shift` is inlined, the FIR inliner only inlines with `-mmlir -inline-all`, and even then InlineHLFIRAssign runs before inlining. But on the IR after inlining, the analysis returned NoAlias for `x%a(i)` and `x%a(j)`, and for `obj%other%a(i)` and `x%a(i)`. I added a reduced form of that IR to the tests, with the program sketched in the comments, and the same with BIND(C) types.


https://github.com/llvm/llvm-project/pull/231655


More information about the flang-commits mailing list