[flang-commits] [flang] [flang] Disambiguate derived component accesses in AliasAnalysis. (PR #189516)

Tom Eccles via flang-commits flang-commits at lists.llvm.org
Tue Mar 31 05:00:32 PDT 2026


https://github.com/tblah commented:

Thanks for the changes. I think this can report NoAlias when components do alias due to POINTER/TARGET.

Reproducer (assisted-by codex)
```
// module m
// type :: slot
//   integer, pointer :: q
// end type slot
// contains
// subroutine local_ptr_component_slot_bug()
//   type(slot), target :: u
//   type(slot), pointer :: p
//   p => u
//   ! Query the descriptor slot, not q's pointee data.
// end subroutine
// end module

// CHECK-LABEL: Testing : "_QMmPlocal_ptr_component_slot_bug"
// Current behavior on this branch: the loaded-box path traces p%q back to p,
// so AA reports NoAlias against the direct slot u%q even though p => u makes
// them the same descriptor.
// CHECK-DAG: p%q#0 <-> u%q#0: NoAlias
// CHECK-LABEL: Testing : "_QMmPlocal_ptr_component_slot_bug.fir"
// CHECK-DAG: p%q.fir#0 <-> u%q.fir#0: NoAlias

func.func @_QMmPlocal_ptr_component_slot_bug() {
  %0 = fir.alloca !fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}> {bindc_name = "u", uniq_name = "_QMmFlocal_ptr_component_slot_bugEu"}
  %1:2 = hlfir.declare %0 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMmFlocal_ptr_component_slot_bugEu"} : (!fir.ref<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>) -> (!fir.ref<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>, !fir.ref<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>)
  %2 = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>> {bindc_name = "p", uniq_name = "_QMmFlocal_ptr_component_slot_bugEp"}
  %3:2 = hlfir.declare %2 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMmFlocal_ptr_component_slot_bugEp"} : (!fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>>) -> (!fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>>, !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>>)
  %4 = fir.embox %1#0 : (!fir.ref<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>) -> !fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>
  fir.store %4 to %3#0 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>>
  %5 = fir.load %3#0 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>>
  %6 = fir.box_addr %5 : (!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>) -> !fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>
  %7 = hlfir.designate %6{"q"} {fortran_attrs = #fir.var_attrs<pointer>, test.ptr = "p%q"} : (!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>
  %8 = hlfir.designate %1#0{"q"} {fortran_attrs = #fir.var_attrs<pointer>, test.ptr = "u%q"} : (!fir.ref<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>
  return
}

func.func @_QMmPlocal_ptr_component_slot_bug.fir() {
  %0 = fir.alloca !fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}> {bindc_name = "u", uniq_name = "_QMmFlocal_ptr_component_slot_bugEu"}
  %1 = fir.declare %0 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMmFlocal_ptr_component_slot_bugEu"} : (!fir.ref<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>) -> !fir.ref<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>
  %2 = fir.alloca !fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>> {bindc_name = "p", uniq_name = "_QMmFlocal_ptr_component_slot_bugEp"}
  %3 = fir.declare %2 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMmFlocal_ptr_component_slot_bugEp"} : (!fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>>
  %4 = fir.embox %1 : (!fir.ref<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>) -> !fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>
  fir.store %4 to %3 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>>
  %5 = fir.load %3 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>>
  %6 = fir.box_addr %5 : (!fir.box<!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>>) -> !fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>
  %7 = fir.coordinate_of %6, q {test.ptr = "p%q.fir"} : (!fir.ptr<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>
  %8 = fir.coordinate_of %1, q {test.ptr = "u%q.fir"} : (!fir.ref<!fir.type<_QMmTslot{q:!fir.box<!fir.ptr<i32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>
  return
}
```

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


More information about the flang-commits mailing list