[flang-commits] [flang] [flang] AliasAnalysis: Fix pointer component logic (PR #94242)

via flang-commits flang-commits at lists.llvm.org
Wed Jun 19 03:31:43 PDT 2024


================
@@ -159,21 +193,56 @@ AliasResult AliasAnalysis::alias(Value lhs, Value rhs) {
     src2->attributes.set(Attribute::Target);
   }
 
-  // Dummy TARGET/POINTER argument may alias with a global TARGET/POINTER.
+  // Two TARGET/POINTERs may alias.
   if (src1->isTargetOrPointer() && src2->isTargetOrPointer() &&
       src1->isData() == src2->isData()) {
     LLVM_DEBUG(llvm::dbgs() << "  aliasing because of target or pointer\n");
     return AliasResult::MayAlias;
   }
 
-  // Box for POINTER component inside an object of a derived type
-  // may alias box of a POINTER object, as well as boxes for POINTER
-  // components inside two objects of derived types may alias.
-  if ((src1->isRecordWithPointerComponent() && src2->isTargetOrPointer()) ||
-      (src2->isRecordWithPointerComponent() && src1->isTargetOrPointer()) ||
-      (src1->isRecordWithPointerComponent() &&
-       src2->isRecordWithPointerComponent())) {
-    LLVM_DEBUG(llvm::dbgs() << "  aliasing because of pointer components\n");
+  // A pointer dummy arg (but not a pointer component of a dummy arg) may alias
+  // a pointer component and thus the associated composite.  That composite
+  // might be a global or another dummy arg.  This is an example of the global
+  // composite case:
+  //
+  // module m
+  //   type t
+  //      real, pointer :: p
+  //   end type
+  //   type(t) :: a
+  //   type(t) :: b
+  // contains
+  //   subroutine test(p)
+  //     real, pointer :: p
+  //     p = 42
+  //     a = b
+  //     print *, p
+  //   end subroutine
+  // end module
+  // program
+  //   use m
+  //   real, target :: x1 = 1
+  //   real, target :: x2 = 2
+  //   a%p => x1
+  //   b%p => x2
+  //   call test(a%p)
+  // end
+  //
+  // The dummy argument p is an alias for a%p, even for the purposes of pointer
+  // association during the assignment a = b.  Thus, the program should print 2.
+  if ((isRecordWithPointerComponent(val1->getType()) &&
+       src1->kind != SourceKind::Allocate &&
+       src2->kind == SourceKind::Argument &&
+       src2->attributes.test(Attribute::Pointer) && !src2->isData() &&
+       !isRecordWithPointerComponent(src2->valueType)) ||
----------------
jeanPerier wrote:

Thanks for the explanation, while I understand the goal, the condition is still wrong in my opinion.

> the result above would become MayAlias

That would be a valid if the dummies had the TARGET attribute as per 15.5.2.14 (3) (b).

Here is an illustration where "a" and "c%p" should be considered to potentially alias (which is not enforced properly because of this condition). :
```
module m
  type t 
     real, pointer :: p
  end type
  type(t) :: a
  type(t) :: b
contains
subroutine test(c)
  type(t), target :: c
  c%p = 42
  a = b
  print *, c%p
end subroutine 
end module
    
  use m
  real, target :: x1 = 1
  real, target :: x2 = 2
  a%p => x1
  b%p => x2
  call test(a)
end 
```

To pass this at the FIR level, the `src2->attributes.test(Attribute::Pointer)` should also be removed because the attributes where not gathered on the hlfir.designate which does not exist anymore in FIR (replaced by fir.coordinate). This makes some sense anyway since the source (the dummy) in itself does not really has that attribute anyway.

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


More information about the flang-commits mailing list