Skip to content

Commit a61be3a

Browse files
committed
Fix handling of dummy arg with target attribute
That is, the address of a dummy arg may alias the address of a global or another dummy arg when both have target attributes. If either is a composite, components may alias as well. However, this PR broke handling of that case in two previous changes: 1. Initial commits in this PR replaced the conservative handling of pointer components. As a result, they stopped reporting MayAlias for, e.g., the address of a pointer component of a dummy arg composite with a target attribute vs. the address of another composite with a target attribute. This problem was discussed in the PR: <#94242 (comment)> 2. The previous commit in this PR changed the conservative targets/pointers handling not to handle the case where both values have `!isData()`. As a result, it stopped reporting MayAlias for, e.g., the address of an allocatable dummy arg with a target attribute vs. another allocatable with a target attribute. This commit fixes such cases.
1 parent ee248f5 commit a61be3a

File tree

2 files changed

+230
-0
lines changed

2 files changed

+230
-0
lines changed

flang/lib/Optimizer/Analysis/AliasAnalysis.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,28 @@ AliasResult AliasAnalysis::alias(mlir::Value lhs, mlir::Value rhs) {
235235
return AliasResult::MayAlias;
236236
}
237237

238+
// Aliasing for dummy arg with target attribute.
239+
//
240+
// The address of a dummy arg (or HostAssoc) may alias the address of a
241+
// non-local (global or another dummy arg) when both have target attributes.
242+
// If either is a composite, addresses of components may alias as well.
243+
//
244+
// The previous "if" calling isTargetOrPointer casts a very wide net and so
245+
// reports MayAlias for many such cases that would otherwise be reported here.
246+
// It specifically skips such cases where one or both values have !isData()
247+
// (e.g., address *of* pointer/allocatable component vs. address of
248+
// composite), so this "if" catches those cases.
249+
if (src1->attributes.test(Attribute::Target) &&
250+
src2->attributes.test(Attribute::Target) &&
251+
((src1->aliasesLikeDummyArg() && src2->canBeActualArg()) ||
252+
(src2->aliasesLikeDummyArg() && src1->canBeActualArg()))) {
253+
LLVM_DEBUG(llvm::dbgs()
254+
<< " aliasing between targets where one is a dummy arg\n");
255+
return AliasResult::MayAlias;
256+
}
257+
258+
// Aliasing for dummy arg that is a pointer.
259+
//
238260
// The address of a pointer dummy arg (but not a pointer component of a dummy
239261
// arg) may alias the address of either (1) a non-local pointer or (2) thus a
240262
// non-local composite with a pointer component. A non-local might be a

flang/test/Analysis/AliasAnalysis/alias-analysis-9.fir

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,3 +632,211 @@ func.func private @_QMmFparentPtest.fir(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.
632632

633633
return
634634
}
635+
636+
// -----
637+
638+
// Dummy arg with target attribute and pointer component.
639+
640+
// The address of a dummy arg (arg0) may alias the address of a global (glob0)
641+
// or another dummy arg (arg1) when both have target attributes. If either is a
642+
// composite, the addresses of components (whether data like r, or non-data like
643+
// p and a) may also alias the composite or the same component. However, target
644+
// attributes do not permit two globals (glob0 and glob1) to alias.
645+
646+
// module m
647+
// type t
648+
// real, pointer :: p
649+
// real, allocatable :: a
650+
// real :: r
651+
// end type
652+
// type(t), target :: glob0
653+
// type(t), target :: glob1
654+
// contains
655+
// subroutine test(arg0, arg1)
656+
// type(t), target :: arg0
657+
// type(t), target :: arg1
658+
// end subroutine
659+
// end module
660+
661+
// TODO: All glob0 vs. glob1 cases can be NoAlias. However, AliasAnalysis
662+
// currently indiscriminately treats all targets that are data (addresses of
663+
// glob[01] and glob[01]%r but not glob[01]%p and glob[01]%a) as aliasing.
664+
665+
// Check composite vs. composite.
666+
//
667+
// CHECK-DAG: arg0#0 <-> arg1#0: MayAlias
668+
// CHECK-DAG: arg0.fir#0 <-> arg1.fir#0: MayAlias
669+
//
670+
// CHECK-DAG: arg0#0 <-> glob0#0: MayAlias
671+
// CHECK-DAG: arg0.fir#0 <-> glob0.fir#0: MayAlias
672+
//
673+
// CHECK-DAG: glob0#0 <-> glob1#0: MayAlias
674+
// CHECK-DAG: glob0.fir#0 <-> glob1.fir#0: MayAlias
675+
676+
// Check component vs. composite.
677+
//
678+
// CHECK-DAG: arg0%p#0 <-> arg1#0: MayAlias
679+
// CHECK-DAG: arg0%a#0 <-> arg1#0: MayAlias
680+
// CHECK-DAG: arg0%r#0 <-> arg1#0: MayAlias
681+
// CHECK-DAG: arg0%p.fir#0 <-> arg1.fir#0: MayAlias
682+
// CHECK-DAG: arg0%a.fir#0 <-> arg1.fir#0: MayAlias
683+
// CHECK-DAG: arg0%r.fir#0 <-> arg1.fir#0: MayAlias
684+
//
685+
// CHECK-DAG: arg0%p#0 <-> glob0#0: MayAlias
686+
// CHECK-DAG: arg0%a#0 <-> glob0#0: MayAlias
687+
// CHECK-DAG: arg0%r#0 <-> glob0#0: MayAlias
688+
// CHECK-DAG: arg0%p.fir#0 <-> glob0.fir#0: MayAlias
689+
// CHECK-DAG: arg0%a.fir#0 <-> glob0.fir#0: MayAlias
690+
// CHECK-DAG: arg0%r.fir#0 <-> glob0.fir#0: MayAlias
691+
//
692+
// CHECK-DAG: glob0%p#0 <-> glob1#0: NoAlias
693+
// CHECK-DAG: glob0%a#0 <-> glob1#0: NoAlias
694+
// CHECK-DAG: glob0%r#0 <-> glob1#0: MayAlias
695+
// CHECK-DAG: glob0%p.fir#0 <-> glob1.fir#0: NoAlias
696+
// CHECK-DAG: glob0%a.fir#0 <-> glob1.fir#0: NoAlias
697+
// CHECK-DAG: glob0%r.fir#0 <-> glob1.fir#0: MayAlias
698+
699+
// Check composite vs. component.
700+
//
701+
// CHECK-DAG: arg0#0 <-> arg1%p#0: MayAlias
702+
// CHECK-DAG: arg0#0 <-> arg1%a#0: MayAlias
703+
// CHECK-DAG: arg0#0 <-> arg1%r#0: MayAlias
704+
// CHECK-DAG: arg0.fir#0 <-> arg1%p.fir#0: MayAlias
705+
// CHECK-DAG: arg0.fir#0 <-> arg1%a.fir#0: MayAlias
706+
// CHECK-DAG: arg0.fir#0 <-> arg1%r.fir#0: MayAlias
707+
//
708+
// CHECK-DAG: arg0#0 <-> glob0%p#0: MayAlias
709+
// CHECK-DAG: arg0#0 <-> glob0%a#0: MayAlias
710+
// CHECK-DAG: arg0#0 <-> glob0%r#0: MayAlias
711+
// CHECK-DAG: arg0.fir#0 <-> glob0%p.fir#0: MayAlias
712+
// CHECK-DAG: arg0.fir#0 <-> glob0%a.fir#0: MayAlias
713+
// CHECK-DAG: arg0.fir#0 <-> glob0%r.fir#0: MayAlias
714+
//
715+
// CHECK-DAG: glob0#0 <-> glob1%p#0: NoAlias
716+
// CHECK-DAG: glob0#0 <-> glob1%a#0: NoAlias
717+
// CHECK-DAG: glob0#0 <-> glob1%r#0: MayAlias
718+
// CHECK-DAG: glob0.fir#0 <-> glob1%p.fir#0: NoAlias
719+
// CHECK-DAG: glob0.fir#0 <-> glob1%a.fir#0: NoAlias
720+
// CHECK-DAG: glob0.fir#0 <-> glob1%r.fir#0: MayAlias
721+
722+
// Check component vs. component.
723+
//
724+
// CHECK-DAG: arg0%p#0 <-> arg1%p#0: MayAlias
725+
// CHECK-DAG: arg0%a#0 <-> arg1%a#0: MayAlias
726+
// CHECK-DAG: arg0%r#0 <-> arg1%r#0: MayAlias
727+
// CHECK-DAG: arg0%p.fir#0 <-> arg1%p.fir#0: MayAlias
728+
// CHECK-DAG: arg0%a.fir#0 <-> arg1%a.fir#0: MayAlias
729+
// CHECK-DAG: arg0%r.fir#0 <-> arg1%r.fir#0: MayAlias
730+
//
731+
// CHECK-DAG: arg0%p.fir#0 <-> glob0%p.fir#0: MayAlias
732+
// CHECK-DAG: arg0%a.fir#0 <-> glob0%a.fir#0: MayAlias
733+
// CHECK-DAG: arg0%r.fir#0 <-> glob0%r.fir#0: MayAlias
734+
//
735+
// CHECK-DAG: glob0%p.fir#0 <-> glob1%p.fir#0: NoAlias
736+
// CHECK-DAG: glob0%a.fir#0 <-> glob1%a.fir#0: NoAlias
737+
// CHECK-DAG: glob0%r.fir#0 <-> glob1%r.fir#0: MayAlias
738+
739+
func.func @_QMmPtest(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>> {fir.bindc_name = "arg0", fir.target}, %arg1: !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>> {fir.bindc_name = "arg1", fir.target}) {
740+
%0 = fir.dummy_scope : !fir.dscope
741+
742+
%10:2 = hlfir.declare %arg0 dummy_scope %0 {test.ptr="arg0", fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMmFtestEarg0"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.dscope) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>)
743+
%11 = hlfir.designate %10#0{"p"} {test.ptr="arg0%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
744+
%12 = hlfir.designate %10#0{"a"} {test.ptr="arg0%a", fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
745+
%13 = hlfir.designate %10#0{"r"} {test.ptr="arg0%r"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<f32>
746+
747+
%20:2 = hlfir.declare %arg1 dummy_scope %0 {test.ptr="arg1", fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMmFtestEarg1"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.dscope) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>)
748+
%21 = hlfir.designate %20#0{"p"} {test.ptr="arg1%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
749+
%22 = hlfir.designate %20#0{"a"} {test.ptr="arg1%a", fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
750+
%23 = hlfir.designate %20#0{"r"} {test.ptr="arg1%r"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<f32>
751+
752+
%30 = fir.address_of(@_QMmEglob0) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
753+
%31:2 = hlfir.declare %30 {test.ptr="glob0", fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMmEglob0"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>)
754+
%32 = hlfir.designate %31#0{"p"} {test.ptr="glob0%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
755+
%33 = hlfir.designate %31#0{"a"} {test.ptr="glob0%a", fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
756+
%34 = hlfir.designate %31#0{"r"} {test.ptr="glob0%r"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<f32>
757+
758+
%40 = fir.address_of(@_QMmEglob1) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
759+
%41:2 = hlfir.declare %40 {test.ptr="glob1", fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMmEglob1"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>)
760+
%42 = hlfir.designate %41#0{"p"} {test.ptr="glob1%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
761+
%43 = hlfir.designate %41#0{"a"} {test.ptr="glob1%a", fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>
762+
%44 = hlfir.designate %41#0{"r"} {test.ptr="glob1%r"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<f32>
763+
764+
return
765+
}
766+
767+
func.func @_QMmPtest.fir(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>> {fir.bindc_name = "arg0", fir.target}, %arg1: !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>> {fir.bindc_name = "arg1", fir.target}) {
768+
%0 = fir.dummy_scope : !fir.dscope
769+
770+
%1 = fir.declare %arg0 dummy_scope %0 {test.ptr="arg0.fir", fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMmFtestEarg0"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.dscope) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
771+
%2 = fir.field_index p, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
772+
%3 = fir.coordinate_of %1, %2 {test.ptr="arg0%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
773+
%4 = fir.field_index a, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
774+
%5 = fir.coordinate_of %1, %4 {test.ptr="arg0%a.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<f32>>>
775+
%6 = fir.field_index r, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
776+
%7 = fir.coordinate_of %1, %6 {test.ptr="arg0%r.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<f32>
777+
778+
%8 = fir.declare %arg1 dummy_scope %0 {test.ptr="arg1.fir", fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMmFtestEarg1"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.dscope) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
779+
%9 = fir.field_index p, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
780+
%10 = fir.coordinate_of %8, %9 {test.ptr="arg1%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
781+
%11 = fir.field_index a, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
782+
%12 = fir.coordinate_of %8, %11 {test.ptr="arg1%a.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<f32>>>
783+
%13 = fir.field_index r, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
784+
%14 = fir.coordinate_of %8, %13 {test.ptr="arg1%r.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<f32>
785+
786+
%15 = fir.address_of(@_QMmEglob0) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
787+
%16 = fir.declare %15 {test.ptr="glob0.fir", fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMmEglob0"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
788+
%17 = fir.field_index p, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
789+
%18 = fir.coordinate_of %16, %17 {test.ptr="glob0%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
790+
%19 = fir.field_index a, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
791+
%20 = fir.coordinate_of %16, %19 {test.ptr="glob0%a.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<f32>>>
792+
%21 = fir.field_index r, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
793+
%22 = fir.coordinate_of %16, %21 {test.ptr="glob0%r.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<f32>
794+
795+
%23 = fir.address_of(@_QMmEglob1) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
796+
%24 = fir.declare %23 {test.ptr="glob1.fir", fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QMmEglob1"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
797+
%25 = fir.field_index p, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
798+
%26 = fir.coordinate_of %24, %25 {test.ptr="glob1%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<!fir.box<!fir.ptr<f32>>>
799+
%27 = fir.field_index a, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
800+
%28 = fir.coordinate_of %24, %27 {test.ptr="glob1%a.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<!fir.box<!fir.heap<f32>>>
801+
%29 = fir.field_index r, !fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>
802+
%30 = fir.coordinate_of %24, %29 {test.ptr="glob1%r.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>, !fir.field) -> !fir.ref<f32>
803+
804+
return
805+
}
806+
807+
// -----
808+
809+
// Allocatable dummy arg with target attribute.
810+
811+
// This case is like the previous one except that the non-data is the address
812+
// of the dummy arg itself rather than of a pointer component of the dummy arg.
813+
// The goal is to check that logic introduced into AliasAnalysis to handle the
814+
// pointer component case doesn't break this related one.
815+
816+
// module m
817+
// real, allocatable, target :: glob0
818+
// real, allocatable, target :: glob1
819+
// contains
820+
// subroutine test(arg0, arg1)
821+
// real, allocatable, target :: arg0
822+
// real, allocatable, target :: arg1
823+
// end subroutine
824+
// end module
825+
826+
// CHECK-DAG: arg0#0 <-> arg1#0: MayAlias
827+
// CHECK-DAG: arg0#0 <-> glob0#0: MayAlias
828+
// CHECK-DAG: glob0#0 <-> glob1#0: NoAlias
829+
830+
func.func @_QMmPtest(%arg0: !fir.ref<!fir.box<!fir.heap<f32>>> {fir.bindc_name = "arg0", fir.target}, %arg1: !fir.ref<!fir.box<!fir.heap<f32>>> {fir.bindc_name = "arg1", fir.target}) {
831+
%0 = fir.dummy_scope : !fir.dscope
832+
833+
%10:2 = hlfir.declare %arg0 dummy_scope %0 {test.ptr="arg0", fortran_attrs = #fir.var_attrs<allocatable, target>, uniq_name = "_QMmFtestEarg0"} : (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
834+
%11:2 = hlfir.declare %arg1 dummy_scope %0 {test.ptr="arg1", fortran_attrs = #fir.var_attrs<allocatable, target>, uniq_name = "_QMmFtestEarg1"} : (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
835+
836+
%20 = fir.address_of(@_QMmEglob0) : !fir.ref<!fir.box<!fir.heap<f32>>>
837+
%21:2 = hlfir.declare %20 {test.ptr="glob0", fortran_attrs = #fir.var_attrs<allocatable, target>, uniq_name = "_QMmEglob0"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
838+
%22 = fir.address_of(@_QMmEglob1) : !fir.ref<!fir.box<!fir.heap<f32>>>
839+
%23:2 = hlfir.declare %22 {test.ptr="glob1", fortran_attrs = #fir.var_attrs<allocatable, target>, uniq_name = "_QMmEglob1"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>)
840+
841+
return
842+
}

0 commit comments

Comments
 (0)