[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