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

Joel E. Denny via flang-commits flang-commits at lists.llvm.org
Mon Jun 3 11:02:28 PDT 2024


================
@@ -122,13 +122,32 @@ AliasResult AliasAnalysis::alias(Value lhs, Value rhs) {
   }
 
   if (lhsSrc.kind == rhsSrc.kind) {
+    // If the kinds and origins are the same, then lhs and rhs must alias unless
+    // either source is approximate.  Approximate sources are for parts of the
+    // origin, but we don't have info here on which parts and whether they
+    // overlap, so we normally return MayAlias in that case.
+    //
+    // There is an exceptional case: The origins might compare unequal because
+    // only one has !isData().  If that source is approximate and the other is
+    // not, then the former is the source for the address *of* a pointer
+    // component in a composite, and the latter is for the address of that
+    // composite.  As for the address of any composite vs. the address of one of
+    // its components, a store to one can affect a load from the other, so the
+    // result is MayAlias.
     if (lhsSrc.origin == rhsSrc.origin) {
       LLVM_DEBUG(llvm::dbgs()
                  << "  aliasing because same source kind and origin\n");
       if (approximateSource)
         return AliasResult::MayAlias;
       return AliasResult::MustAlias;
     }
+    if (lhsSrc.origin.u == rhsSrc.origin.u &&
+        ((lhsSrc.approximateSource && !lhsSrc.isData() && !rhsSrc.approximateSource) ||
+         (rhsSrc.approximateSource && !rhsSrc.isData() && !lhsSrc.approximateSource))) {
+      LLVM_DEBUG(llvm::dbgs()
+                 << "  aliasing between composite and pointer component\n");
+      return AliasResult::MayAlias;
+    }
----------------
jdenny-ornl wrote:

> `DesignateOp` is later lowered to `coordinate_of` for instance.

Thanks.  In a simple example, I see that

```
%10 = hlfir.designate %1#0{"p"}   {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
```

becomes

```
%10 = fir.field_index p, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>}>
%11 = fir.coordinate_of %1, %10 : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
```

The latter pattern seems simple enough to detect.  I did not find a later version of that IR where `fir.coordinate_of` appeared but `!fir.field` and `fir.field_index` had been optimized away.  Is your `fir.coordinate_of %memref %c0` an example of that?

> The absence of which does not mean we are not dealing with a component.

Is it true that either `hlfir.designate` or `fir.coordinate_of` must be present when accessing a component?  If not, then, independently of this PR, we risk `approximateSource=false` and an invalid MustAlias, right?

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


More information about the flang-commits mailing list