150 lines · plain
1// Use --mlir-disable-threading so that the AA queries are serialized2// as well as its diagnostic output.3// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s4 5// module m6// type t7// real, pointer :: pointer_component8// end type t9// type(t) :: a10// contains11// subroutine test(pointer_dummy, x)12// real, pointer :: pointer_dummy13// real, target :: x14// pointer_dummy => x15// call test2(a%pointer_component)16// end subroutine test17// end module m18 19// A composite with a pointer component may alias with a dummy pointer20// CHECK-LABEL: Testing : "_QMmPtest21// CHECK: a#0 <-> func.region0#0: MayAlias22 23// a's box cannot alias with raw reference to f32 (x)24// CHECK: a#0 <-> func.region0#1: NoAlias25 26// pointer_dummy's box cannot alias with raw reference to f32 (x)27// CHECK: func.region0#0 <-> func.region0#1: NoAlias28 29fir.global @_QMmEa : !fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}> {30 %0 = fir.undefined !fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>31 fir.has_value %0 : !fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>32}33func.func @_QMmPtest(%arg0: !fir.ref<!fir.box<!fir.ptr<f32>>> {fir.bindc_name = "pointer_dummy"}, %arg1: !fir.ref<f32> {fir.bindc_name = "x", fir.target}) attributes {test.ptr = "func"} {34 %0 = fir.address_of(@_QMmEa) {test.ptr = "a"} : !fir.ref<!fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>>35 %1 = fir.embox %arg1 : (!fir.ref<f32>) -> !fir.box<!fir.ptr<f32>>36 fir.store %1 to %arg0 : !fir.ref<!fir.box<!fir.ptr<f32>>>37 %3 = fir.coordinate_of %0, pointer_component : (!fir.ref<!fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>38 %4 = fir.load %3 : !fir.ref<!fir.box<!fir.ptr<f32>>>39 %5 = fir.box_addr %4 : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>40 %6 = fir.convert %5 : (!fir.ptr<f32>) -> !fir.ref<f32>41 fir.call @_QPtest2(%6) fastmath<contract> : (!fir.ref<f32>) -> ()42 return43}44func.func private @_QPtest2(!fir.ref<f32>)45 46// -----47 48// A composite with a pointer component does not alias with a dummy49// argument of composite type with a pointer component:50// module m51// type t52// real, pointer :: pointer_component53// end type t54// type(t) :: a55// contains56// subroutine test(b, x)57// type(t) :: b58// real, target :: x59// a%pointer_component => x60// call test2(b%pointer_component)61// end subroutine test62// end module m63 64// CHECK-LABEL: Testing : "_QMmPtest"65// CHECK: a#0 <-> func.region0#0: NoAlias66 67fir.global @_QMmEa : !fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}> {68 %0 = fir.undefined !fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>69 fir.has_value %0 : !fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>70}71func.func @_QMmPtest(%arg0: !fir.ref<!fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>> {fir.bindc_name = "b"}, %arg1: !fir.ref<f32> {fir.bindc_name = "x", fir.target}) attributes {test.ptr = "func"} {72 %0 = fir.address_of(@_QMmEa) {test.ptr = "a"} : !fir.ref<!fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>>73 %2 = fir.coordinate_of %0, pointer_component : (!fir.ref<!fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>74 %3 = fir.embox %arg1 : (!fir.ref<f32>) -> !fir.box<!fir.ptr<f32>>75 fir.store %3 to %2 : !fir.ref<!fir.box<!fir.ptr<f32>>>76 %5 = fir.coordinate_of %arg0, pointer_component : (!fir.ref<!fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>77 %6 = fir.load %5 : !fir.ref<!fir.box<!fir.ptr<f32>>>78 %7 = fir.box_addr %6 : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>79 %8 = fir.convert %7 : (!fir.ptr<f32>) -> !fir.ref<f32>80 fir.call @_QPtest2(%8) fastmath<contract> : (!fir.ref<f32>) -> ()81 return82}83func.func private @_QPtest2(!fir.ref<f32>)84 85// -----86 87// Two dummy arguments of composite type with a pointer component88// do not alias each other:89// module m90// type t91// real, pointer :: pointer_component92// end type t93// contains94// subroutine test(a, b, x)95// type(t) :: a, b96// real, target :: x97// a%pointer_component => x98// call test2(b%pointer_component)99// end subroutine test100// end module m101 102// CHECK-LABEL: Testing : "_QMmPtest"103// CHECK: func.region0#0 <-> func.region0#1: NoAlias104 105func.func @_QMmPtest(%arg0: !fir.ref<!fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>> {fir.bindc_name = "a"}, %arg1: !fir.ref<!fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>> {fir.bindc_name = "b"}, %arg2: !fir.ref<f32> {fir.bindc_name = "x", fir.target}) attributes {test.ptr = "func"} {106 %1 = fir.coordinate_of %arg0, pointer_component : (!fir.ref<!fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>107 %2 = fir.embox %arg2 : (!fir.ref<f32>) -> !fir.box<!fir.ptr<f32>>108 fir.store %2 to %1 : !fir.ref<!fir.box<!fir.ptr<f32>>>109 %4 = fir.coordinate_of %arg1, pointer_component : (!fir.ref<!fir.type<_QMmTt{pointer_component:!fir.box<!fir.ptr<f32>>}>>) -> !fir.ref<!fir.box<!fir.ptr<f32>>>110 %5 = fir.load %4 : !fir.ref<!fir.box<!fir.ptr<f32>>>111 %6 = fir.box_addr %5 : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32>112 %7 = fir.convert %6 : (!fir.ptr<f32>) -> !fir.ref<f32>113 fir.call @_QPtest2(%7) fastmath<contract> : (!fir.ref<f32>) -> ()114 return115}116func.func private @_QPtest2(!fir.ref<f32>)117 118// -----119 120// Two dummy arguments of composite type consisting of an allocatable121// component cannot alias:122// module m123// type t124// real, allocatable :: allocatable_component125// end type t126// contains127// subroutine test(a, b)128// type(t) :: a, b129// allocate(a%allocatable_component)130// call test2(b%allocatable_component)131// end subroutine test132// end module m133 134// CHECK-LABEL: Testing : "_QMmPtest"135// CHECK: func.region0#0 <-> func.region0#1: NoAlias136 137func.func @_QMmPtest(%arg0: !fir.ref<!fir.type<_QMmTt{allocatable_component:!fir.box<!fir.heap<f32>>}>> {fir.bindc_name = "a"}, %arg1: !fir.ref<!fir.type<_QMmTt{allocatable_component:!fir.box<!fir.heap<f32>>}>> {fir.bindc_name = "b"}) attributes {test.ptr = "func"} {138 %1 = fir.coordinate_of %arg0, allocatable_component : (!fir.ref<!fir.type<_QMmTt{allocatable_component:!fir.box<!fir.heap<f32>>}>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>139 %2 = fir.allocmem f32 {uniq_name = "_QMmEallocatable_component.alloc"}140 %3 = fir.embox %2 : (!fir.heap<f32>) -> !fir.box<!fir.heap<f32>>141 fir.store %3 to %1 : !fir.ref<!fir.box<!fir.heap<f32>>>142 %5 = fir.coordinate_of %arg1, allocatable_component : (!fir.ref<!fir.type<_QMmTt{allocatable_component:!fir.box<!fir.heap<f32>>}>>) -> !fir.ref<!fir.box<!fir.heap<f32>>>143 %6 = fir.load %5 : !fir.ref<!fir.box<!fir.heap<f32>>>144 %7 = fir.box_addr %6 : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32>145 %8 = fir.convert %7 : (!fir.heap<f32>) -> !fir.ref<f32>146 fir.call @_QPtest2(%8) fastmath<contract> : (!fir.ref<f32>) -> ()147 return148}149func.func private @_QPtest2(!fir.ref<f32>)150