[flang-commits] [flang] [flang] AliasAnalysis: Fix pointer component logic (PR #94242)
via flang-commits
flang-commits at lists.llvm.org
Thu Jun 20 01:10:26 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:
`a` in my example does not need target because it is not a dummy argument, so `15.5.2.14` does not restrict the effects on it. `15.5.2.14` restrict the effects on `c`, so it only matters that `c` has this attribute to allow `c` to be effected by changes on `a`.
I agree this is not a very well known aspect, but it is what is, and other compiler respect it (if you do A= B with two TARGET assumed-shape, you should observe that all compiler will cope with the case where A an B alias, even f not POINTERs are involved).
https://github.com/llvm/llvm-project/pull/94242
More information about the flang-commits
mailing list