802 lines · plain
1// Check AliasAnalysis for pointer components.2//3// Throughout this test, The ".fir" suffix on symbols indicates a version of the4// MLIR after convert-hlfir-to-fir. A key difference is that component access5// is via fir.coordinate_of instead of hlfir.designate. We would like alias6// analysis results to be the same in both versions.7 8// RUN: fir-opt %s -split-input-file -o /dev/null --mlir-disable-threading \9// RUN: -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' \10// RUN: 2>&1 | FileCheck -match-full-lines %s11 12// module m13// type t14// type(t), pointer :: next15// integer :: i16// end type17// contains18// subroutine foo(x, y)19// type(t) :: x, y20// integer :: i1, i221// i1 = x%next%i22// x = y23// i2 = x%next%i24// end subroutine25// end module26 27// CHECK-LABEL: Testing : "_QMmPfoo"28// x and y are non pointer, non target argument and therefore do not alias.29// CHECK-DAG: x#0 <-> y#0: NoAlias30// CHECK-DAG: x.fir#0 <-> y.fir#0: NoAlias31 32// y is not a pointer object and therefore does not alias with the x%next33// component. Also assigning x to y would not modify x.next34// CHECK-DAG: y#0 <-> xnext1#0: NoAlias35// CHECK-DAG: y#0 <-> xnext2#0: NoAlias36// CHECK-DAG: y.fir#0 <-> xnext1.fir#0: NoAlias37// CHECK-DAG: y.fir#0 <-> xnext2.fir#0: NoAlias38 39// We need to catch the fact that assigning y to x will modify xnext. 40// The only side-effect between the 2 loads of x.next is the assignment to x, 41// therefore x needs to alias with x.next to prevent the loads from being merged.42// CHECK-DAG: x#0 <-> xnext1#0: MayAlias43// CHECK-DAG: x#0 <-> xnext2#0: MayAlias44// CHECK-DAG: x.fir#0 <-> xnext1.fir#0: MayAlias45// CHECK-DAG: x.fir#0 <-> xnext2.fir#0: MayAlias46 47// TODO: xnext1#0 <-> xnext2#0 are the same and therefore MustAlias but 48// we are currently not comparing operands involved in offset computations49// CHECK-DAG: xnext1#0 <-> xnext2#0: MayAlias50// CHECK-DAG: xnext1.fir#0 <-> xnext2.fir#0: MayAlias51 52// CHECK-DAG: xnext1#0 <-> ynext#0: NoAlias53// CHECK-DAG: xnext1.fir#0 <-> ynext.fir#0: NoAlias54 55func.func @_QMmPfoo(%arg0: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>> {fir.bindc_name = "y"}) {56 %0 = fir.alloca i32 {bindc_name = "i1", uniq_name = "_QMmFfooEi1"}57 %1:2 = hlfir.declare %0 {uniq_name = "_QMmFfooEi1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)58 %2 = fir.alloca i32 {bindc_name = "i2", uniq_name = "_QMmFfooEi2"}59 %3:2 = hlfir.declare %2 {uniq_name = "_QMmFfooEi2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)60 %4:2 = hlfir.declare %arg0 {uniq_name = "_QMmFfooEx", test.ptr = "x"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>)61 %5:2 = hlfir.declare %arg1 {uniq_name = "_QMmFfooEy", test.ptr = "y"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>)62 %6 = hlfir.designate %4#0{"next"} {fortran_attrs = #fir.var_attrs<pointer>, test.ptr = "xnext1"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>63 %7 = fir.load %6 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>64 %8 = fir.box_addr %7 : (!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>65 %9 = hlfir.designate %8{"i"} : (!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<i32>66 %10 = fir.load %9 : !fir.ref<i32>67 hlfir.assign %10 to %1#0 : i32, !fir.ref<i32>68 hlfir.assign %5#0 to %4#0 : !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>69 %11 = hlfir.designate %4#0{"next"} {fortran_attrs = #fir.var_attrs<pointer>, test.ptr = "xnext2"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>70 %12 = fir.load %11 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>71 %13 = fir.box_addr %12 : (!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>72 %14 = hlfir.designate %13{"i"} : (!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<i32>73 %15 = fir.load %14 : !fir.ref<i32>74 hlfir.assign %15 to %3#0 : i32, !fir.ref<i32>75 %16 = hlfir.designate %5#0{"next"} {fortran_attrs = #fir.var_attrs<pointer>, test.ptr = "ynext"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>76 return77}78 79func.func @_QMmPfoo.fir(%arg0: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>> {fir.bindc_name = "y"}) {80 %0 = fir.alloca !fir.box<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>81 %1 = fir.alloca i32 {bindc_name = "i1", uniq_name = "_QMmFfooEi1"}82 %2 = fir.declare %1 {uniq_name = "_QMmFfooEi1"} : (!fir.ref<i32>) -> !fir.ref<i32>83 %3 = fir.alloca i32 {bindc_name = "i2", uniq_name = "_QMmFfooEi2"}84 %4 = fir.declare %3 {uniq_name = "_QMmFfooEi2"} : (!fir.ref<i32>) -> !fir.ref<i32>85 %5 = fir.declare %arg0 {test.ptr = "x.fir", uniq_name = "_QMmFfooEx"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>86 %6 = fir.declare %arg1 {test.ptr = "y.fir", uniq_name = "_QMmFfooEy"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>87 %8 = fir.coordinate_of %5, next {test.ptr="xnext1.fir"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>88 %9 = fir.load %8 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>89 %10 = fir.box_addr %9 : (!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>90 %12 = fir.coordinate_of %10, i : (!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<i32>91 %13 = fir.load %12 : !fir.ref<i32>92 fir.store %13 to %2 : !fir.ref<i32>93 %14 = fir.embox %5 : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.box<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>94 %15 = fir.embox %6 : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.box<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>95 fir.store %14 to %0 : !fir.ref<!fir.box<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>96 %16 = fir.address_of(@_QQclX746D70332E66697200) : !fir.ref<!fir.char<1,9>>97 %c9 = arith.constant 9 : index98 %c14_i32 = arith.constant 14 : i3299 %17 = fir.convert %0 : (!fir.ref<!fir.box<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ref<!fir.box<none>>100 %18 = fir.convert %15 : (!fir.box<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.box<none>101 %19 = fir.convert %16 : (!fir.ref<!fir.char<1,9>>) -> !fir.ref<i8>102 fir.call @_FortranAAssign(%17, %18, %19, %c14_i32) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()103 %22 = fir.coordinate_of %5, next {test.ptr="xnext2.fir"}: (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>104 %23 = fir.load %22 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>105 %24 = fir.box_addr %23 : (!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>106 %26 = fir.coordinate_of %24, i : (!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<i32>107 %27 = fir.load %26 : !fir.ref<i32>108 fir.store %27 to %4 : !fir.ref<i32>109 %29 = fir.coordinate_of %6, next {test.ptr="ynext.fir"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>110 return111}112 113// -----114 115// Same test as above focusing on aliasing between x%next and y%next data116// CHECK-LABEL: Testing : "_QMmPfoo2"117// CHECK-DAG: xnext#0 <-> ynext#0: MayAlias118// CHECK-DAG: xnext.fir#0 <-> ynext.fir#0: MayAlias119 120func.func @_QMmPfoo2(%arg0: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>> {fir.bindc_name = "y"}) {121 %4:2 = hlfir.declare %arg0 {uniq_name = "_QMmFfooEx"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>)122 %5:2 = hlfir.declare %arg1 {uniq_name = "_QMmFfooEy"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>)123 %6 = hlfir.designate %4#0{"next"} {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>124 %7 = fir.load %6 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>125 %8 = fir.box_addr %7 {test.ptr = "xnext"} : (!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>126 127 %9 = hlfir.designate %5#0{"next"} {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>128 %10 = fir.load %9 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>129 %11 = fir.box_addr %10 {test.ptr = "ynext"} : (!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>130 return131}132 133func.func @_QMmPfoo2.fir(%arg0: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>> {fir.bindc_name = "y"}) {134 %0 = fir.declare %arg0 {uniq_name = "_QMmFfooEx"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>135 %1 = fir.declare %arg1 {uniq_name = "_QMmFfooEy"} : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>136 %3 = fir.coordinate_of %0, next : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>137 %4 = fir.load %3 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>138 %5 = fir.box_addr %4 {test.ptr = "xnext.fir"} : (!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>139 %7 = fir.coordinate_of %1, next : (!fir.ref<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>140 %8 = fir.load %7 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>141 %9 = fir.box_addr %8 {test.ptr = "ynext.fir"} : (!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>) -> !fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>142 return143}144 145// -----146 147// module m148// type ta149// integer, pointer :: array(:)150// end type151// contains152// subroutine foo3(x, y)153// type(t) :: x, y154// x%array(1) = y%array(1)155// end subroutine156// end module157 158// CHECK-LABEL: Testing : "_QMmPfoo3"159// CHECK-DAG: yarray#0 <-> xarray#0: MayAlias160// CHECK-DAG: yarray.fir#0 <-> xarray.fir#0: MayAlias161 162func.func @_QMmPfoo3(%arg0: !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> {fir.bindc_name = "y"}) {163 %0:2 = hlfir.declare %arg0 {uniq_name = "_QMmFfooEx"} : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>)164 %1:2 = hlfir.declare %arg1 {uniq_name = "_QMmFfooEy"} : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>, !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>)165 %2 = hlfir.designate %1#0{"array"} {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>166 %3 = fir.load %2 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>167 %c1 = arith.constant 1 : index168 %4 = hlfir.designate %3 (%c1) {test.ptr = "yarray"} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> !fir.ref<i32>169 %5 = fir.load %4 : !fir.ref<i32>170 %6 = hlfir.designate %0#0{"array"} {fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>171 %7 = fir.load %6 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>172 %c1_0 = arith.constant 1 : index173 %8 = hlfir.designate %7 (%c1_0) {test.ptr = "xarray"} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> !fir.ref<i32>174 hlfir.assign %5 to %8 : i32, !fir.ref<i32>175 return176}177 178func.func @_QMmPfoo3.fir(%arg0: !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>> {fir.bindc_name = "y"}) {179 %0 = fir.declare %arg0 {uniq_name = "_QMmFfooEx"} : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>180 %1 = fir.declare %arg1 {uniq_name = "_QMmFfooEy"} : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>181 %3 = fir.coordinate_of %1, array : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>182 %4 = fir.load %3 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>183 %c1 = arith.constant 1 : index184 %c0 = arith.constant 0 : index185 %5:3 = fir.box_dims %4, %c0 : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)186 %6 = fir.shift %5#0 : (index) -> !fir.shift<1>187 %7 = fir.array_coor %4(%6) %c1 {test.ptr="yarray.fir"} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shift<1>, index) -> !fir.ref<i32>188 %8 = fir.load %7 : !fir.ref<i32>189 %10 = fir.coordinate_of %0, array : (!fir.ref<!fir.type<_QMmTta{array:!fir.box<!fir.ptr<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>190 %11 = fir.load %10 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>191 %c1_0 = arith.constant 1 : index192 %c0_1 = arith.constant 0 : index193 %12:3 = fir.box_dims %11, %c0_1 : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)194 %13 = fir.shift %12#0 : (index) -> !fir.shift<1>195 %14 = fir.array_coor %11(%13) %c1_0 {test.ptr="xarray.fir"} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, !fir.shift<1>, index) -> !fir.ref<i32>196 fir.store %8 to %14 : !fir.ref<i32>197 return198}199 200// -----201 202// The address of a composite aliases the address of any component, including an203// allocatable component. Like the address of a pointer, the address of an204// allocatable is considered non-data, so AliasAnalysis has special handling to205// detect the aliasing.206 207// module m208// type t209// integer, allocatable :: p210// end type211// type(t) :: x212// contains213// subroutine test()214// ! access x%p215// end subroutine216// end module217 218// CHECK-LABEL: Testing : "_QMmPtest"219// CHECK-DAG: x#0 <-> x%p#0: MayAlias220// CHECK-DAG: x.fir#0 <-> x%p.fir#0: MayAlias221 222func.func @_QMmPtest() {223 %0 = fir.address_of(@_QMmEx) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>224 %1:2 = hlfir.declare %0 {test.ptr="x", uniq_name = "_QMmEx"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>)225 %2 = hlfir.designate %1#0{"p"} {test.ptr="x%p", fortran_attrs = #fir.var_attrs<allocatable>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>) -> !fir.ref<!fir.box<!fir.heap<i32>>>226 return227}228 229func.func @_QMmPtest.fir() {230 %0 = fir.address_of(@_QMmEx) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>231 %1 = fir.declare %0 {test.ptr = "x.fir", uniq_name = "_QMmEx"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>232 %3 = fir.coordinate_of %1, p {test.ptr="x%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>) -> !fir.ref<!fir.box<!fir.heap<i32>>>233 return234}235 236// -----237 238// Nested composites.239 240// module m241// type t1242// integer, pointer :: p243// end type244// type t2245// type(t1) :: x246// integer, pointer :: p247// integer :: i248// end type249// contains250// subroutine test()251// type(t2) :: x252// end subroutine253// end module254 255// CHECK-LABEL: Testing : "_QMmPtest"256 257// The addresses of a composite and its pointer component alias even if the258// composite is nested within another composite.259// CHECK-DAG: x#0 <-> x%p#0: MayAlias260// CHECK-DAG: x%x#0 <-> x%x%p#0: MayAlias261// CHECK-DAG: x.fir#0 <-> x%p.fir#0: MayAlias262// CHECK-DAG: x%x.fir#0 <-> x%x%p.fir#0: MayAlias263 264// The addresses of different components of the same composite do not alias.265//266// TODO: Thus, all results below should be NoAlias. However, AliasAnalysis267// normally does not recognize when two values (x%x vs. x%i) are distinct268// components of the same composite (x) as opposed to being potentially269// overlapping parts of something, so it returns MayAlias. There is special270// handling for a pointer component (x%p) that does recognize it as separate271// from other components (x%i). But it does not yet distinguish the composite272// (x) from a component (x%x) that is also a composite with a pointer component273// (x%x%p). Thus, because x and x%p can alias, it assumes x%x and x%p can too.274// CHECK-DAG: x%x#0 <-> x%i#0: MayAlias275// CHECK-DAG: x%p#0 <-> x%i#0: NoAlias276// CHECK-DAG: x%x#0 <-> x%p#0: MayAlias277// CHECK-DAG: x%x.fir#0 <-> x%i.fir#0: MayAlias278// CHECK-DAG: x%p.fir#0 <-> x%i.fir#0: NoAlias279// CHECK-DAG: x%x.fir#0 <-> x%p.fir#0: MayAlias280 281func.func @_QMmPtest() {282 %0 = fir.alloca !fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}> {bindc_name = "x", uniq_name = "_QMmFtestEx"}283 %1:2 = hlfir.declare %0 {test.ptr="x", uniq_name = "_QMmFtestEx"} : (!fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>)284 %2 = hlfir.designate %1#0{"x"} {test.ptr="x%x"} : (!fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>>285 %3 = hlfir.designate %1#0{"p"} {test.ptr="x%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>286 %4 = hlfir.designate %1#0{"i"} {test.ptr="x%i"} : (!fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>287 %5 = hlfir.designate %2{"p"} {test.ptr="x%x%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>288 return289}290 291func.func @_QMmPtest.fir() {292 %0 = fir.alloca !fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}> {bindc_name = "x", uniq_name = "_QMmFtestEx"}293 %1 = fir.declare %0 {test.ptr = "x.fir", uniq_name = "_QMmFtestEx"} : (!fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>294 %3 = fir.coordinate_of %1, x {test.ptr="x%x.fir"} : (!fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>>295 %5 = fir.coordinate_of %1, p {test.ptr="x%p.fir"} : (!fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>296 %7 = fir.coordinate_of %1, i {test.ptr="x%i.fir"} : (!fir.ref<!fir.type<_QMmTt2{x:!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>,p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>297 %9 = fir.coordinate_of %3, p {test.ptr="x%x%p.fir"} : (!fir.ref<!fir.type<_QMmTt1{p:!fir.box<!fir.ptr<i32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>298 return299}300 301// -----302 303// Pointer that might dynamically be a component.304 305// The address of a pointer dummy arg (argp) might alias the address of a306// pointer component (x%p) and thus the address of the associated composite (x),307// but it does not alias the addresses of other components (x%i) of the308// composite. Moreover, the address *in* argp does not alias any of those.309// Finally, an allocatable dummy arg (arga) should not be mistaken for a pointer310// dummy arg and cannot have such aliasing.311 312// module m313// type t314// integer, pointer :: p315// integer i316// end type317// type(t) :: glob318// contains319// subroutine test(argp, arga, arg)320// integer, pointer :: argp321// integer, allocatable :: arga322// type(t) :: arg323// type(t) :: loc324// end subroutine325// end module326 327// CHECK-LABEL: Testing : "_QMmPtest"328 329// Check when composite is a dummy arg.330//331// CHECK-DAG: argp#0 <-> arg#0: MayAlias332// CHECK-DAG: argp#0 <-> arg%p#0: MayAlias333// CHECK-DAG: argp#0 <-> arg%i#0: NoAlias334// CHECK-DAG: argp.fir#0 <-> arg.fir#0: MayAlias335// CHECK-DAG: argp.fir#0 <-> arg%p.fir#0: MayAlias336// CHECK-DAG: argp.fir#0 <-> arg%i.fir#0: NoAlias337//338// CHECK-DAG: argp.tgt#0 <-> arg#0: NoAlias339// CHECK-DAG: argp.tgt#0 <-> arg%p#0: NoAlias340// CHECK-DAG: argp.tgt#0 <-> arg%i#0: NoAlias341// CHECK-DAG: argp.tgt.fir#0 <-> arg.fir#0: NoAlias342// CHECK-DAG: argp.tgt.fir#0 <-> arg%p.fir#0: NoAlias343// CHECK-DAG: argp.tgt.fir#0 <-> arg%i.fir#0: NoAlias344//345// CHECK-DAG: arga#0 <-> arg#0: NoAlias346// CHECK-DAG: arga#0 <-> arg%p#0: NoAlias347// CHECK-DAG: arga.fir#0 <-> arg.fir#0: NoAlias348// CHECK-DAG: arga.fir#0 <-> arg%p.fir#0: NoAlias349 350// Check when composite is a global.351//352// CHECK-DAG: argp#0 <-> glob#0: MayAlias353// CHECK-DAG: argp#0 <-> glob%p#0: MayAlias354// CHECK-DAG: argp#0 <-> glob%i#0: NoAlias355// CHECK-DAG: argp.fir#0 <-> glob.fir#0: MayAlias356// CHECK-DAG: argp.fir#0 <-> glob%p.fir#0: MayAlias357// CHECK-DAG: argp.fir#0 <-> glob%i.fir#0: NoAlias358//359// CHECK-DAG: argp.tgt#0 <-> glob#0: NoAlias360// CHECK-DAG: argp.tgt#0 <-> glob%p#0: NoAlias361// CHECK-DAG: argp.tgt#0 <-> glob%i#0: NoAlias362// CHECK-DAG: argp.tgt.fir#0 <-> glob.fir#0: NoAlias363// CHECK-DAG: argp.tgt.fir#0 <-> glob%p.fir#0: NoAlias364// CHECK-DAG: argp.tgt.fir#0 <-> glob%i.fir#0: NoAlias365//366// CHECK-DAG: arga#0 <-> glob#0: NoAlias367// CHECK-DAG: arga#0 <-> glob%p#0: NoAlias368// CHECK-DAG: arga.fir#0 <-> glob.fir#0: NoAlias369// CHECK-DAG: arga.fir#0 <-> glob%p.fir#0: NoAlias370 371// Check when composite is a local and thus cannot alias a dummy arg.372//373// CHECK-DAG: argp#0 <-> loc#0: NoAlias374// CHECK-DAG: argp#0 <-> loc%p#0: NoAlias375// CHECK-DAG: argp#0 <-> loc%i#0: NoAlias376// CHECK-DAG: argp.fir#0 <-> loc.fir#0: NoAlias377// CHECK-DAG: argp.fir#0 <-> loc%p.fir#0: NoAlias378// CHECK-DAG: argp.fir#0 <-> loc%i.fir#0: NoAlias379//380// CHECK-DAG: argp.tgt#0 <-> loc#0: NoAlias381// CHECK-DAG: argp.tgt#0 <-> loc%p#0: NoAlias382// CHECK-DAG: argp.tgt#0 <-> loc%i#0: NoAlias383// CHECK-DAG: argp.tgt.fir#0 <-> loc.fir#0: NoAlias384// CHECK-DAG: argp.tgt.fir#0 <-> loc%p.fir#0: NoAlias385// CHECK-DAG: argp.tgt.fir#0 <-> loc%i.fir#0: NoAlias386//387// CHECK-DAG: arga#0 <-> loc#0: NoAlias388// CHECK-DAG: arga#0 <-> loc%p#0: NoAlias389// CHECK-DAG: arga.fir#0 <-> loc.fir#0: NoAlias390// CHECK-DAG: arga.fir#0 <-> loc%p.fir#0: NoAlias391 392fir.global @_QMmEglob : !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>393 394func.func @_QMmPtest(%arg0: !fir.ref<!fir.box<!fir.ptr<i32>>> {fir.bindc_name = "argp"}, %arg1: !fir.ref<!fir.box<!fir.heap<i32>>> {fir.bindc_name = "arga"}, %arg2: !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>> {fir.bindc_name = "arg"}) {395 %0 = fir.dummy_scope : !fir.dscope396 397 %1:2 = hlfir.declare %arg0 dummy_scope %0 {test.ptr="argp", fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QMmFtestEargp"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)398 %2 = fir.load %1#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>399 %3 = fir.box_addr %2 {test.ptr="argp.tgt"} : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>400 401 %4:2 = hlfir.declare %arg1 dummy_scope %0 {test.ptr="arga", fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QMmFtestEarga"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)402 403 %5:2 = hlfir.declare %arg2 dummy_scope %0 {test.ptr="arg", uniq_name = "_QMmFtestEarg"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.dscope) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>)404 %6 = hlfir.designate %5#0{"p"} {test.ptr="arg%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>405 %7 = hlfir.designate %5#0{"i"} {test.ptr="arg%i"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>406 407 %8 = fir.address_of(@_QMmEglob) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>408 %9:2 = hlfir.declare %8 {test.ptr="glob", uniq_name = "_QMmEglob"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>)409 %10 = hlfir.designate %9#0{"p"} {test.ptr="glob%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>410 %11 = hlfir.designate %9#0{"i"} {test.ptr="glob%i"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>411 412 %12 = fir.alloca !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}> {bindc_name = "loc", uniq_name = "_QMmFtestEloc"}413 %13:2 = hlfir.declare %12 {test.ptr="loc", uniq_name = "_QMmFtestEloc"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>)414 %14 = hlfir.designate %13#0{"p"} {test.ptr="loc%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>415 %15 = hlfir.designate %13#0{"i"} {test.ptr="loc%i"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>416 417 return418}419 420func.func @_QMmPtest.fir(%arg0: !fir.ref<!fir.box<!fir.ptr<i32>>> {fir.bindc_name = "argp"}, %arg1: !fir.ref<!fir.box<!fir.heap<i32>>> {fir.bindc_name = "arga"}, %arg2: !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>> {fir.bindc_name = "arg"}) {421 %0 = fir.dummy_scope : !fir.dscope422 423 %1 = fir.declare %arg0 dummy_scope %0 {fortran_attrs = #fir.var_attrs<pointer>, test.ptr = "argp.fir", uniq_name = "_QMmFtestEargp"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.ptr<i32>>>424 %2 = fir.load %1 : !fir.ref<!fir.box<!fir.ptr<i32>>>425 %3 = fir.box_addr %2 {test.ptr = "argp.tgt.fir"} : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>426 427 %4 = fir.declare %arg1 dummy_scope %0 {fortran_attrs = #fir.var_attrs<allocatable>, test.ptr = "arga.fir", uniq_name = "_QMmFtestEarga"} : (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<i32>>>428 429 %5 = fir.declare %arg2 dummy_scope %0 {test.ptr = "arg.fir", uniq_name = "_QMmFtestEarg"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.dscope) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>430 %7 = fir.coordinate_of %5, p {test.ptr="arg%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>431 %9 = fir.coordinate_of %5, i {test.ptr="arg%i.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>432 433 %10 = fir.address_of(@_QMmEglob) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>434 %11 = fir.declare %10 {test.ptr = "glob.fir", uniq_name = "_QMmEglob"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>435 %13 = fir.coordinate_of %11, p {test.ptr="glob%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>436 %15 = fir.coordinate_of %11, i {test.ptr="glob%i.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>437 438 %16 = fir.alloca !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}> {bindc_name = "loc", uniq_name = "_QMmFtestEloc"}439 %17 = fir.declare %16 {test.ptr = "loc.fir", uniq_name = "_QMmFtestEloc"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>440 %19 = fir.coordinate_of %17, p {test.ptr="loc%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>441 %21 = fir.coordinate_of %17, i {test.ptr="loc%i.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>442 443 return444}445 446// -----447 448// Same as previous case but argp and arga are HostAssoc.449 450// module m451// type t452// integer, pointer :: p453// integer i454// end type455// type(t) :: glob456// contains457// subroutine parent(argp, arga)458// integer, pointer :: argp459// integer, allocatable :: arga460// type(t) :: arg461// call test(arg)462// contains463// subroutine test(arg)464// type(t) :: arg465// type(t) :: loc466// end subroutine467// end subroutine468// end module469 470// CHECK-LABEL: Testing : "_QMmFparentPtest"471 472// Check when composite is a dummy arg.473//474// CHECK-DAG: argp#0 <-> arg#0: MayAlias475// CHECK-DAG: argp#0 <-> arg%p#0: MayAlias476// CHECK-DAG: argp#0 <-> arg%i#0: NoAlias477// CHECK-DAG: argp.fir#0 <-> arg.fir#0: MayAlias478// CHECK-DAG: argp.fir#0 <-> arg%p.fir#0: MayAlias479// CHECK-DAG: argp.fir#0 <-> arg%i.fir#0: NoAlias480//481// TODO: Shouldn't these be NoAlias? However, argp.tgt is currently handled as482// Indirect.483// CHECK-DAG: argp.tgt#0 <-> arg#0: MayAlias484// CHECK-DAG: argp.tgt#0 <-> arg%p#0: MayAlias485// CHECK-DAG: argp.tgt#0 <-> arg%i#0: MayAlias486// CHECK-DAG: argp.tgt.fir#0 <-> arg.fir#0: MayAlias487// CHECK-DAG: argp.tgt.fir#0 <-> arg%p.fir#0: MayAlias488// CHECK-DAG: argp.tgt.fir#0 <-> arg%i.fir#0: MayAlias489//490// CHECK-DAG: arga#0 <-> arg#0: NoAlias491// CHECK-DAG: arga#0 <-> arg%p#0: NoAlias492// CHECK-DAG: arga.fir#0 <-> arg.fir#0: NoAlias493// CHECK-DAG: arga.fir#0 <-> arg%p.fir#0: NoAlias494 495// Check when composite is a global.496//497// CHECK-DAG: argp#0 <-> glob#0: MayAlias498// CHECK-DAG: argp#0 <-> glob%p#0: MayAlias499// CHECK-DAG: argp#0 <-> glob%i#0: NoAlias500// CHECK-DAG: argp.fir#0 <-> glob.fir#0: MayAlias501// CHECK-DAG: argp.fir#0 <-> glob%p.fir#0: MayAlias502// CHECK-DAG: argp.fir#0 <-> glob%i.fir#0: NoAlias503//504// TODO: Shouldn't these be NoAlias? However, argp.tgt is currently handled as505// Indirect.506// CHECK-DAG: argp.tgt#0 <-> glob#0: MayAlias507// CHECK-DAG: argp.tgt#0 <-> glob%p#0: MayAlias508// CHECK-DAG: argp.tgt#0 <-> glob%i#0: MayAlias509// CHECK-DAG: argp.tgt.fir#0 <-> glob.fir#0: MayAlias510// CHECK-DAG: argp.tgt.fir#0 <-> glob%p.fir#0: MayAlias511// CHECK-DAG: argp.tgt.fir#0 <-> glob%i.fir#0: MayAlias512//513// CHECK-DAG: arga#0 <-> glob#0: NoAlias514// CHECK-DAG: arga#0 <-> glob%p#0: NoAlias515// CHECK-DAG: arga.fir#0 <-> glob.fir#0: NoAlias516// CHECK-DAG: arga.fir#0 <-> glob%p.fir#0: NoAlias517 518// Check when composite is a local and thus cannot alias a dummy arg.519//520// CHECK-DAG: argp#0 <-> loc#0: NoAlias521// CHECK-DAG: argp#0 <-> loc%p#0: NoAlias522// CHECK-DAG: argp#0 <-> loc%i#0: NoAlias523// CHECK-DAG: argp.fir#0 <-> loc.fir#0: NoAlias524// CHECK-DAG: argp.fir#0 <-> loc%p.fir#0: NoAlias525// CHECK-DAG: argp.fir#0 <-> loc%i.fir#0: NoAlias526//527// TODO: Shouldn't these be NoAlias? However, argp.tgt is currently handled as528// Indirect.529// CHECK-DAG: argp.tgt#0 <-> loc#0: MayAlias530// CHECK-DAG: argp.tgt#0 <-> loc%p#0: MayAlias531// CHECK-DAG: argp.tgt#0 <-> loc%i#0: MayAlias532// CHECK-DAG: argp.tgt.fir#0 <-> loc.fir#0: MayAlias533// CHECK-DAG: argp.tgt.fir#0 <-> loc%p.fir#0: MayAlias534// CHECK-DAG: argp.tgt.fir#0 <-> loc%i.fir#0: MayAlias535//536// CHECK-DAG: arga#0 <-> loc#0: NoAlias537// CHECK-DAG: arga#0 <-> loc%p#0: NoAlias538// CHECK-DAG: arga.fir#0 <-> loc.fir#0: NoAlias539// CHECK-DAG: arga.fir#0 <-> loc%p.fir#0: NoAlias540 541fir.global @_QMmEglob : !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>542 543func.func private @_QMmFparentPtest(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>> {fir.bindc_name = "arg"}, %arg1: !fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>>> {fir.host_assoc}) attributes {fir.host_symbol = @_QMmPparent, llvm.linkage = #llvm.linkage<internal>} {544 %0 = fir.dummy_scope : !fir.dscope545 546 %c0_i32 = arith.constant 0 : i32547 %1 = fir.coordinate_of %arg1, %c0_i32 : (!fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<i32>>>>548 %2 = fir.load %1 : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<i32>>>>549 %3:2 = hlfir.declare %2 {test.ptr="argp", fortran_attrs = #fir.var_attrs<pointer, host_assoc>, uniq_name = "_QMmFparentEargp"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)550 %4 = fir.load %3#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>551 %5 = fir.box_addr %4 {test.ptr="argp.tgt"} : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>552 553 %c1_i32 = arith.constant 1 : i32554 %10 = fir.coordinate_of %arg1, %c1_i32 : (!fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.box<!fir.heap<i32>>>>555 %11 = fir.load %10 : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.heap<i32>>>>556 %12:2 = hlfir.declare %11 {test.ptr="arga", fortran_attrs = #fir.var_attrs<allocatable, host_assoc>, uniq_name = "_QMmFparentEarga"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> (!fir.ref<!fir.box<!fir.heap<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>)557 558 %20 = fir.address_of(@_QMmEglob) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>559 %21:2 = hlfir.declare %20 {test.ptr="glob", uniq_name = "_QMmEglob"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>)560 %22 = hlfir.designate %21#0{"p"} {test.ptr="glob%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>561 %23 = hlfir.designate %21#0{"i"} {test.ptr="glob%i"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>562 563 %30:2 = hlfir.declare %arg0 dummy_scope %0 {test.ptr="arg", uniq_name = "_QMmFparentFtestEarg"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.dscope) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>)564 %31 = hlfir.designate %30#0{"p"} {test.ptr="arg%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>565 %32 = hlfir.designate %30#0{"i"} {test.ptr="arg%i"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>566 567 %40 = fir.alloca !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}> {bindc_name = "loc", uniq_name = "_QMmFparentFtestEloc"}568 %41:2 = hlfir.declare %40 {test.ptr="loc", uniq_name = "_QMmFparentFtestEloc"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>)569 %42 = hlfir.designate %41#0{"p"} {test.ptr="loc%p", fortran_attrs = #fir.var_attrs<pointer>} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>570 %43 = hlfir.designate %41#0{"i"} {test.ptr="loc%i"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>571 572 return573}574 575func.func private @_QMmFparentPtest.fir(%arg0: !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>> {fir.bindc_name = "arg"}, %arg1: !fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>>> {fir.host_assoc}) attributes {fir.host_symbol = @_QMmPparent, llvm.linkage = #llvm.linkage<internal>} {576 %0 = fir.dummy_scope : !fir.dscope577 578 %c0_i32 = arith.constant 0 : i32579 %1 = fir.coordinate_of %arg1, %c0_i32 : (!fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<i32>>>>580 %2 = fir.load %1 : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<i32>>>>581 %3 = fir.declare %2 {fortran_attrs = #fir.var_attrs<pointer, host_assoc>, test.ptr = "argp.fir", uniq_name = "_QMmFparentEargp"} : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>582 %4 = fir.load %3 : !fir.ref<!fir.box<!fir.ptr<i32>>>583 %5 = fir.box_addr %4 {test.ptr = "argp.tgt.fir"} : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>584 585 %c1_i32 = arith.constant 1 : i32586 %6 = fir.coordinate_of %arg1, %c1_i32 : (!fir.ref<tuple<!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.heap<i32>>>>>, i32) -> !fir.llvm_ptr<!fir.ref<!fir.box<!fir.heap<i32>>>>587 %7 = fir.load %6 : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.heap<i32>>>>588 %8 = fir.declare %7 {fortran_attrs = #fir.var_attrs<allocatable, host_assoc>, test.ptr = "arga.fir", uniq_name = "_QMmFparentEarga"} : (!fir.ref<!fir.box<!fir.heap<i32>>>) -> !fir.ref<!fir.box<!fir.heap<i32>>>589 590 %9 = fir.address_of(@_QMmEglob) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>591 %10 = fir.declare %9 {test.ptr = "glob.fir", uniq_name = "_QMmEglob"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>592 %12 = fir.coordinate_of %10, p {test.ptr="glob%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>593 %14 = fir.coordinate_of %10, i {test.ptr="glob%i.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>594 595 %15 = fir.declare %arg0 dummy_scope %0 {test.ptr = "arg.fir", uniq_name = "_QMmFparentFtestEarg"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>, !fir.dscope) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>596 %17 = fir.coordinate_of %15, p {test.ptr="arg%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>597 %19 = fir.coordinate_of %15, i {test.ptr="arg%i.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>598 599 %20 = fir.alloca !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}> {bindc_name = "loc", uniq_name = "_QMmFparentFtestEloc"}600 %21 = fir.declare %20 {test.ptr = "loc.fir", uniq_name = "_QMmFparentFtestEloc"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>601 %23 = fir.coordinate_of %21, p {test.ptr="loc%p.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>602 %25 = fir.coordinate_of %21, i {test.ptr="loc%i.fir"} : (!fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>) -> !fir.ref<i32>603 604 return605}606 607// -----608 609// Dummy arg with target attribute and pointer component.610 611// The address of a dummy arg (arg0) may alias the address of a global (glob0)612// or another dummy arg (arg1) when both have target attributes. If either is a613// composite, the addresses of components (whether data like r, or non-data like614// p and a) may also alias the composite or the same component. However, target615// attributes do not permit two globals (glob0 and glob1) to alias.616 617// module m618// type t619// real, pointer :: p620// real, allocatable :: a621// real :: r622// end type623// type(t), target :: glob0624// type(t), target :: glob1625// contains626// subroutine test(arg0, arg1)627// type(t), target :: arg0628// type(t), target :: arg1629// end subroutine630// end module631 632// TODO: All glob0 vs. glob1 cases can be NoAlias. However, AliasAnalysis633// currently indiscriminately treats all targets that are data (addresses of634// glob[01] and glob[01]%r but not glob[01]%p and glob[01]%a) as aliasing.635 636// Check composite vs. composite.637//638// CHECK-DAG: arg0#0 <-> arg1#0: MayAlias639// CHECK-DAG: arg0.fir#0 <-> arg1.fir#0: MayAlias640//641// CHECK-DAG: arg0#0 <-> glob0#0: MayAlias642// CHECK-DAG: arg0.fir#0 <-> glob0.fir#0: MayAlias643//644// CHECK-DAG: glob0#0 <-> glob1#0: MayAlias645// CHECK-DAG: glob0.fir#0 <-> glob1.fir#0: MayAlias646 647// Check component vs. composite.648//649// CHECK-DAG: arg0%p#0 <-> arg1#0: MayAlias650// CHECK-DAG: arg0%a#0 <-> arg1#0: MayAlias651// CHECK-DAG: arg0%r#0 <-> arg1#0: MayAlias652// CHECK-DAG: arg0%p.fir#0 <-> arg1.fir#0: MayAlias653// CHECK-DAG: arg0%a.fir#0 <-> arg1.fir#0: MayAlias654// CHECK-DAG: arg0%r.fir#0 <-> arg1.fir#0: MayAlias655//656// CHECK-DAG: arg0%p#0 <-> glob0#0: MayAlias657// CHECK-DAG: arg0%a#0 <-> glob0#0: MayAlias658// CHECK-DAG: arg0%r#0 <-> glob0#0: MayAlias659// CHECK-DAG: arg0%p.fir#0 <-> glob0.fir#0: MayAlias660// CHECK-DAG: arg0%a.fir#0 <-> glob0.fir#0: MayAlias661// CHECK-DAG: arg0%r.fir#0 <-> glob0.fir#0: MayAlias662//663// CHECK-DAG: glob0%p#0 <-> glob1#0: NoAlias664// CHECK-DAG: glob0%a#0 <-> glob1#0: NoAlias665// CHECK-DAG: glob0%r#0 <-> glob1#0: MayAlias666// CHECK-DAG: glob0%p.fir#0 <-> glob1.fir#0: NoAlias667// CHECK-DAG: glob0%a.fir#0 <-> glob1.fir#0: NoAlias668// CHECK-DAG: glob0%r.fir#0 <-> glob1.fir#0: MayAlias669 670// Check composite vs. component.671//672// CHECK-DAG: arg0#0 <-> arg1%p#0: MayAlias673// CHECK-DAG: arg0#0 <-> arg1%a#0: MayAlias674// CHECK-DAG: arg0#0 <-> arg1%r#0: MayAlias675// CHECK-DAG: arg0.fir#0 <-> arg1%p.fir#0: MayAlias676// CHECK-DAG: arg0.fir#0 <-> arg1%a.fir#0: MayAlias677// CHECK-DAG: arg0.fir#0 <-> arg1%r.fir#0: MayAlias678//679// CHECK-DAG: arg0#0 <-> glob0%p#0: MayAlias680// CHECK-DAG: arg0#0 <-> glob0%a#0: MayAlias681// CHECK-DAG: arg0#0 <-> glob0%r#0: MayAlias682// CHECK-DAG: arg0.fir#0 <-> glob0%p.fir#0: MayAlias683// CHECK-DAG: arg0.fir#0 <-> glob0%a.fir#0: MayAlias684// CHECK-DAG: arg0.fir#0 <-> glob0%r.fir#0: MayAlias685//686// CHECK-DAG: glob0#0 <-> glob1%p#0: NoAlias687// CHECK-DAG: glob0#0 <-> glob1%a#0: NoAlias688// CHECK-DAG: glob0#0 <-> glob1%r#0: MayAlias689// CHECK-DAG: glob0.fir#0 <-> glob1%p.fir#0: NoAlias690// CHECK-DAG: glob0.fir#0 <-> glob1%a.fir#0: NoAlias691// CHECK-DAG: glob0.fir#0 <-> glob1%r.fir#0: MayAlias692 693// Check component vs. component.694//695// CHECK-DAG: arg0%p#0 <-> arg1%p#0: MayAlias696// CHECK-DAG: arg0%a#0 <-> arg1%a#0: MayAlias697// CHECK-DAG: arg0%r#0 <-> arg1%r#0: MayAlias698// CHECK-DAG: arg0%p.fir#0 <-> arg1%p.fir#0: MayAlias699// CHECK-DAG: arg0%a.fir#0 <-> arg1%a.fir#0: MayAlias700// CHECK-DAG: arg0%r.fir#0 <-> arg1%r.fir#0: MayAlias701//702// CHECK-DAG: arg0%p.fir#0 <-> glob0%p.fir#0: MayAlias703// CHECK-DAG: arg0%a.fir#0 <-> glob0%a.fir#0: MayAlias704// CHECK-DAG: arg0%r.fir#0 <-> glob0%r.fir#0: MayAlias705//706// CHECK-DAG: glob0%p.fir#0 <-> glob1%p.fir#0: NoAlias707// CHECK-DAG: glob0%a.fir#0 <-> glob1%a.fir#0: NoAlias708// CHECK-DAG: glob0%r.fir#0 <-> glob1%r.fir#0: MayAlias709 710func.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}) {711 %0 = fir.dummy_scope : !fir.dscope712 713 %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}>>)714 %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>>>715 %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>>>716 %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>717 718 %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}>>)719 %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>>>720 %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>>>721 %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>722 723 %30 = fir.address_of(@_QMmEglob0) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>724 %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}>>)725 %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>>>726 %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>>>727 %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>728 729 %40 = fir.address_of(@_QMmEglob1) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>730 %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}>>)731 %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>>>732 %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>>>733 %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>734 735 return736}737 738func.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}) {739 %0 = fir.dummy_scope : !fir.dscope740 741 %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}>>742 %3 = fir.coordinate_of %1, p {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.ref<!fir.box<!fir.ptr<f32>>>743 %5 = fir.coordinate_of %1, a {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.ref<!fir.box<!fir.heap<f32>>>744 %7 = fir.coordinate_of %1, r {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.ref<f32>745 746 %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}>>747 %10 = fir.coordinate_of %8, p {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.ref<!fir.box<!fir.ptr<f32>>>748 %12 = fir.coordinate_of %8, a {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.ref<!fir.box<!fir.heap<f32>>>749 %14 = fir.coordinate_of %8, r {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.ref<f32>750 751 %15 = fir.address_of(@_QMmEglob0) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>752 %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}>>753 %18 = fir.coordinate_of %16, p {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.ref<!fir.box<!fir.ptr<f32>>>754 %20 = fir.coordinate_of %16, a {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.ref<!fir.box<!fir.heap<f32>>>755 %22 = fir.coordinate_of %16, r {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.ref<f32>756 757 %23 = fir.address_of(@_QMmEglob1) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>758 %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}>>759 %26 = fir.coordinate_of %24, p {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.ref<!fir.box<!fir.ptr<f32>>>760 %28 = fir.coordinate_of %24, a {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.ref<!fir.box<!fir.heap<f32>>>761 %30 = fir.coordinate_of %24, r {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.ref<f32>762 763 return764}765 766// -----767 768// Allocatable dummy arg with target attribute.769 770// This case is like the previous one except that the non-data is the address771// of the dummy arg itself rather than of a pointer component of the dummy arg.772// The goal is to check that logic introduced into AliasAnalysis to handle the773// pointer component case doesn't break this related one.774 775// module m776// real, allocatable, target :: glob0777// real, allocatable, target :: glob1778// contains779// subroutine test(arg0, arg1)780// real, allocatable, target :: arg0781// real, allocatable, target :: arg1782// end subroutine783// end module784 785// CHECK-DAG: arg0#0 <-> arg1#0: MayAlias786// CHECK-DAG: arg0#0 <-> glob0#0: MayAlias787// CHECK-DAG: glob0#0 <-> glob1#0: NoAlias788 789func.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}) {790 %0 = fir.dummy_scope : !fir.dscope791 792 %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>>>)793 %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>>>)794 795 %20 = fir.address_of(@_QMmEglob0) : !fir.ref<!fir.box<!fir.heap<f32>>>796 %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>>>)797 %22 = fir.address_of(@_QMmEglob1) : !fir.ref<!fir.box<!fir.heap<f32>>>798 %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>>>)799 800 return801}802