|
| 1 | +// Check aliasing with the address passed via a pointer dummy argument. |
| 2 | + |
| 3 | +// Use --mlir-disable-threading so that the AA queries are serialized |
| 4 | +// as well as its diagnostic output. |
| 5 | +// RUN: fir-opt %s \ |
| 6 | +// RUN: -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' \ |
| 7 | +// RUN: --mlir-disable-threading 2>&1 | FileCheck %s |
| 8 | + |
| 9 | +// subroutine test(p0, p1, arr, t_arr, alloc, t_alloc) |
| 10 | +// real, pointer :: p0, p1 |
| 11 | +// real :: arr(:) |
| 12 | +// real, target :: t_arr(:) |
| 13 | +// real, allocatable :: alloc |
| 14 | +// real, allocatable, target :: t_alloc |
| 15 | +// real, target :: t |
| 16 | +// real :: v |
| 17 | +// v = p0 |
| 18 | +// v = p1 |
| 19 | +// v = arr(1) |
| 20 | +// v = t_arr(1) |
| 21 | +// v = alloc |
| 22 | +// v = t_alloc |
| 23 | +// end subroutine test |
| 24 | + |
| 25 | +// CHECK-LABEL: Testing : "_QPtest" |
| 26 | + |
| 27 | +// The address in a pointer can alias the address in another pointer or the |
| 28 | +// address of a target but not the address of other variables. |
| 29 | +// CHECK-DAG: t.addr#0 <-> p0.tgt_addr#0: MayAlias |
| 30 | +// CHECK-DAG: t.addr#0 <-> p1.tgt_addr#0: MayAlias |
| 31 | +// CHECK-DAG: v.addr#0 <-> p0.tgt_addr#0: NoAlias |
| 32 | +// CHECK-DAG: v.addr#0 <-> p1.tgt_addr#0: NoAlias |
| 33 | +// CHECK-DAG: p0.tgt_addr#0 <-> p1.tgt_addr#0: MayAlias |
| 34 | + |
| 35 | +// Determining whether the address *in* a pointer can alias the address *of* a |
| 36 | +// pointer is not yet handled. In the past, when it was the same pointer, that |
| 37 | +// relationship was mistakenly determined to be MustAlias. |
| 38 | +// CHECK-DAG: p0.tgt_addr#0 <-> func.region0#0: MayAlias |
| 39 | +// CHECK-DAG: p0.tgt_addr#0 <-> func.region0#1: MayAlias |
| 40 | +// CHECK-DAG: p1.tgt_addr#0 <-> func.region0#0: MayAlias |
| 41 | +// CHECK-DAG: p1.tgt_addr#0 <-> func.region0#1: MayAlias |
| 42 | + |
| 43 | +// For some cases, AliasAnalysis analyzes hlfir.designate like fir.box_addr, so |
| 44 | +// make sure it doesn't mistakenly see arr(1).addr as an address that was loaded |
| 45 | +// from a pointer and that could alias something. However, t_arr is a target. |
| 46 | +// CHECK-DAG: p0.tgt_addr#0 <-> arr(1).addr#0: NoAlias |
| 47 | +// CHECK-DAG: p0.tgt_addr#0 <-> t_arr(1).addr#0: MayAlias |
| 48 | + |
| 49 | +// Like a pointer, an allocatable contains an address, but an allocatable is not |
| 50 | +// a pointer and so cannot alias pointers. However, t_alloc is a target. |
| 51 | +// CHECK-DAG: p0.tgt_addr#0 <-> alloc.tgt_addr#0: NoAlias |
| 52 | +// CHECK-DAG: p0.tgt_addr#0 <-> t_alloc.tgt_addr#0: MayAlias |
| 53 | + |
| 54 | +func.func @_QPtest(%arg0: !fir.ref<!fir.box<!fir.ptr<f32>>> {fir.bindc_name = "p0"}, %arg1: !fir.ref<!fir.box<!fir.ptr<f32>>> {fir.bindc_name = "p1"}, %arg2: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "arr"}, %arg3: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "t_arr", fir.target}, %arg4: !fir.ref<!fir.box<!fir.heap<f32>>> {fir.bindc_name = "alloc"}, %arg5: !fir.ref<!fir.box<!fir.heap<f32>>> {fir.bindc_name = "t_alloc", fir.target}) attributes {test.ptr="func"} { |
| 55 | + %0:2 = hlfir.declare %arg4 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtestEalloc"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>) |
| 56 | + %1:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEarr"} : (!fir.box<!fir.array<?xf32>>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>) |
| 57 | + %2:2 = hlfir.declare %arg0 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtestEp0"} : (!fir.ref<!fir.box<!fir.ptr<f32>>>) -> (!fir.ref<!fir.box<!fir.ptr<f32>>>, !fir.ref<!fir.box<!fir.ptr<f32>>>) |
| 58 | + %3:2 = hlfir.declare %arg1 {fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFtestEp1"} : (!fir.ref<!fir.box<!fir.ptr<f32>>>) -> (!fir.ref<!fir.box<!fir.ptr<f32>>>, !fir.ref<!fir.box<!fir.ptr<f32>>>) |
| 59 | + %4 = fir.alloca f32 {bindc_name = "t", fir.target, uniq_name = "_QFtestEt"} |
| 60 | + %5:2 = hlfir.declare %4 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEt", test.ptr="t.addr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) |
| 61 | + %6:2 = hlfir.declare %arg5 {fortran_attrs = #fir.var_attrs<allocatable, target>, uniq_name = "_QFtestEt_alloc"} : (!fir.ref<!fir.box<!fir.heap<f32>>>) -> (!fir.ref<!fir.box<!fir.heap<f32>>>, !fir.ref<!fir.box<!fir.heap<f32>>>) |
| 62 | + %7:2 = hlfir.declare %arg3 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFtestEt_arr"} : (!fir.box<!fir.array<?xf32>>) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>) |
| 63 | + %8 = fir.alloca f32 {bindc_name = "v", uniq_name = "_QFtestEv"} |
| 64 | + %9:2 = hlfir.declare %8 {uniq_name = "_QFtestEv", test.ptr="v.addr"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>) |
| 65 | + %10 = fir.load %2#0 : !fir.ref<!fir.box<!fir.ptr<f32>>> |
| 66 | + %11 = fir.box_addr %10 {test.ptr="p0.tgt_addr"} : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32> |
| 67 | + %12 = fir.load %11 : !fir.ptr<f32> |
| 68 | + hlfir.assign %12 to %9#0 : f32, !fir.ref<f32> |
| 69 | + %13 = fir.load %3#0 : !fir.ref<!fir.box<!fir.ptr<f32>>> |
| 70 | + %14 = fir.box_addr %13 {test.ptr="p1.tgt_addr"} : (!fir.box<!fir.ptr<f32>>) -> !fir.ptr<f32> |
| 71 | + %15 = fir.load %14 : !fir.ptr<f32> |
| 72 | + hlfir.assign %15 to %9#0 : f32, !fir.ref<f32> |
| 73 | + %c1 = arith.constant 1 : index |
| 74 | + %16 = hlfir.designate %1#0 (%c1) {test.ptr="arr(1).addr"} : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32> |
| 75 | + %17 = fir.load %16 : !fir.ref<f32> |
| 76 | + hlfir.assign %17 to %9#0 : f32, !fir.ref<f32> |
| 77 | + %c1_0 = arith.constant 1 : index |
| 78 | + %18 = hlfir.designate %7#0 (%c1_0) {test.ptr="t_arr(1).addr"} : (!fir.box<!fir.array<?xf32>>, index) -> !fir.ref<f32> |
| 79 | + %19 = fir.load %18 : !fir.ref<f32> |
| 80 | + hlfir.assign %19 to %9#0 : f32, !fir.ref<f32> |
| 81 | + %20 = fir.load %0#0 : !fir.ref<!fir.box<!fir.heap<f32>>> |
| 82 | + %21 = fir.box_addr %20 {test.ptr="alloc.tgt_addr"} : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32> |
| 83 | + %22 = fir.load %21 : !fir.heap<f32> |
| 84 | + hlfir.assign %22 to %9#0 : f32, !fir.ref<f32> |
| 85 | + %23 = fir.load %6#0 : !fir.ref<!fir.box<!fir.heap<f32>>> |
| 86 | + %24 = fir.box_addr %23 {test.ptr="t_alloc.tgt_addr"} : (!fir.box<!fir.heap<f32>>) -> !fir.heap<f32> |
| 87 | + %25 = fir.load %24 : !fir.heap<f32> |
| 88 | + hlfir.assign %25 to %9#0 : f32, !fir.ref<f32> |
| 89 | + return |
| 90 | +} |
0 commit comments