mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 12:36:40 +00:00

After #127231, fir.coordinate_of should directly carry the field. I updated the lowering and codegen tests in #12731, but not the FIR to FIR tests, which is what this patch is cleaning up.
802 lines
56 KiB
Plaintext
802 lines
56 KiB
Plaintext
// Check AliasAnalysis for pointer components.
|
|
//
|
|
// Throughout this test, The ".fir" suffix on symbols indicates a version of the
|
|
// MLIR after convert-hlfir-to-fir. A key difference is that component access
|
|
// is via fir.coordinate_of instead of hlfir.designate. We would like alias
|
|
// analysis results to be the same in both versions.
|
|
|
|
// RUN: fir-opt %s -split-input-file -o /dev/null --mlir-disable-threading \
|
|
// RUN: -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' \
|
|
// RUN: 2>&1 | FileCheck -match-full-lines %s
|
|
|
|
// module m
|
|
// type t
|
|
// type(t), pointer :: next
|
|
// integer :: i
|
|
// end type
|
|
// contains
|
|
// subroutine foo(x, y)
|
|
// type(t) :: x, y
|
|
// integer :: i1, i2
|
|
// i1 = x%next%i
|
|
// x = y
|
|
// i2 = x%next%i
|
|
// end subroutine
|
|
// end module
|
|
|
|
// CHECK-LABEL: Testing : "_QMmPfoo"
|
|
// x and y are non pointer, non target argument and therefore do not alias.
|
|
// CHECK-DAG: x#0 <-> y#0: NoAlias
|
|
// CHECK-DAG: x.fir#0 <-> y.fir#0: NoAlias
|
|
|
|
// y is not a pointer object and therefore does not alias with the x%next
|
|
// component. Also assigning x to y would not modify x.next
|
|
// CHECK-DAG: y#0 <-> xnext1#0: NoAlias
|
|
// CHECK-DAG: y#0 <-> xnext2#0: NoAlias
|
|
// CHECK-DAG: y.fir#0 <-> xnext1.fir#0: NoAlias
|
|
// CHECK-DAG: y.fir#0 <-> xnext2.fir#0: NoAlias
|
|
|
|
// We need to catch the fact that assigning y to x will modify xnext.
|
|
// The only side-effect between the 2 loads of x.next is the assignment to x,
|
|
// therefore x needs to alias with x.next to prevent the loads from being merged.
|
|
// CHECK-DAG: x#0 <-> xnext1#0: MayAlias
|
|
// CHECK-DAG: x#0 <-> xnext2#0: MayAlias
|
|
// CHECK-DAG: x.fir#0 <-> xnext1.fir#0: MayAlias
|
|
// CHECK-DAG: x.fir#0 <-> xnext2.fir#0: MayAlias
|
|
|
|
// TODO: xnext1#0 <-> xnext2#0 are the same and therefore MustAlias but
|
|
// we are currently not comparing operands involved in offset computations
|
|
// CHECK-DAG: xnext1#0 <-> xnext2#0: MayAlias
|
|
// CHECK-DAG: xnext1.fir#0 <-> xnext2.fir#0: MayAlias
|
|
|
|
// CHECK-DAG: xnext1#0 <-> ynext#0: NoAlias
|
|
// CHECK-DAG: xnext1.fir#0 <-> ynext.fir#0: NoAlias
|
|
|
|
func.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"}) {
|
|
%0 = fir.alloca i32 {bindc_name = "i1", uniq_name = "_QMmFfooEi1"}
|
|
%1:2 = hlfir.declare %0 {uniq_name = "_QMmFfooEi1"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
|
%2 = fir.alloca i32 {bindc_name = "i2", uniq_name = "_QMmFfooEi2"}
|
|
%3:2 = hlfir.declare %2 {uniq_name = "_QMmFfooEi2"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
|
|
%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}>>)
|
|
%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}>>)
|
|
%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}>>>>
|
|
%7 = fir.load %6 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
|
|
%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}>>
|
|
%9 = hlfir.designate %8{"i"} : (!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<i32>
|
|
%10 = fir.load %9 : !fir.ref<i32>
|
|
hlfir.assign %10 to %1#0 : i32, !fir.ref<i32>
|
|
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}>>
|
|
%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}>>>>
|
|
%12 = fir.load %11 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
|
|
%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}>>
|
|
%14 = hlfir.designate %13{"i"} : (!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<i32>
|
|
%15 = fir.load %14 : !fir.ref<i32>
|
|
hlfir.assign %15 to %3#0 : i32, !fir.ref<i32>
|
|
%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}>>>>
|
|
return
|
|
}
|
|
|
|
func.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"}) {
|
|
%0 = fir.alloca !fir.box<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>
|
|
%1 = fir.alloca i32 {bindc_name = "i1", uniq_name = "_QMmFfooEi1"}
|
|
%2 = fir.declare %1 {uniq_name = "_QMmFfooEi1"} : (!fir.ref<i32>) -> !fir.ref<i32>
|
|
%3 = fir.alloca i32 {bindc_name = "i2", uniq_name = "_QMmFfooEi2"}
|
|
%4 = fir.declare %3 {uniq_name = "_QMmFfooEi2"} : (!fir.ref<i32>) -> !fir.ref<i32>
|
|
%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}>>
|
|
%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}>>
|
|
%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}>>>>
|
|
%9 = fir.load %8 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
|
|
%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}>>
|
|
%12 = fir.coordinate_of %10, i : (!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<i32>
|
|
%13 = fir.load %12 : !fir.ref<i32>
|
|
fir.store %13 to %2 : !fir.ref<i32>
|
|
%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}>>
|
|
%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}>>
|
|
fir.store %14 to %0 : !fir.ref<!fir.box<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>
|
|
%16 = fir.address_of(@_QQclX746D70332E66697200) : !fir.ref<!fir.char<1,9>>
|
|
%c9 = arith.constant 9 : index
|
|
%c14_i32 = arith.constant 14 : i32
|
|
%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>>
|
|
%18 = fir.convert %15 : (!fir.box<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.box<none>
|
|
%19 = fir.convert %16 : (!fir.ref<!fir.char<1,9>>) -> !fir.ref<i8>
|
|
fir.call @_FortranAAssign(%17, %18, %19, %c14_i32) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> ()
|
|
%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}>>>>
|
|
%23 = fir.load %22 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
|
|
%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}>>
|
|
%26 = fir.coordinate_of %24, i : (!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>) -> !fir.ref<i32>
|
|
%27 = fir.load %26 : !fir.ref<i32>
|
|
fir.store %27 to %4 : !fir.ref<i32>
|
|
%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}>>>>
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
// Same test as above focusing on aliasing between x%next and y%next data
|
|
// CHECK-LABEL: Testing : "_QMmPfoo2"
|
|
// CHECK-DAG: xnext#0 <-> ynext#0: MayAlias
|
|
// CHECK-DAG: xnext.fir#0 <-> ynext.fir#0: MayAlias
|
|
|
|
func.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"}) {
|
|
%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}>>)
|
|
%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}>>)
|
|
%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}>>>>
|
|
%7 = fir.load %6 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
|
|
%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}>>
|
|
|
|
%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}>>>>
|
|
%10 = fir.load %9 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
|
|
%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}>>
|
|
return
|
|
}
|
|
|
|
func.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"}) {
|
|
%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}>>
|
|
%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}>>
|
|
%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}>>>>
|
|
%4 = fir.load %3 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
|
|
%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}>>
|
|
%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}>>>>
|
|
%8 = fir.load %7 : !fir.ref<!fir.box<!fir.ptr<!fir.type<_QMmTt{next:!fir.box<!fir.ptr<!fir.type<_QMmTt>>>,i:i32}>>>>
|
|
%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}>>
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
// module m
|
|
// type ta
|
|
// integer, pointer :: array(:)
|
|
// end type
|
|
// contains
|
|
// subroutine foo3(x, y)
|
|
// type(t) :: x, y
|
|
// x%array(1) = y%array(1)
|
|
// end subroutine
|
|
// end module
|
|
|
|
// CHECK-LABEL: Testing : "_QMmPfoo3"
|
|
// CHECK-DAG: yarray#0 <-> xarray#0: MayAlias
|
|
// CHECK-DAG: yarray.fir#0 <-> xarray.fir#0: MayAlias
|
|
|
|
func.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"}) {
|
|
%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>>>}>>)
|
|
%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>>>}>>)
|
|
%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>>>>
|
|
%3 = fir.load %2 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
|
|
%c1 = arith.constant 1 : index
|
|
%4 = hlfir.designate %3 (%c1) {test.ptr = "yarray"} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
|
|
%5 = fir.load %4 : !fir.ref<i32>
|
|
%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>>>>
|
|
%7 = fir.load %6 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
|
|
%c1_0 = arith.constant 1 : index
|
|
%8 = hlfir.designate %7 (%c1_0) {test.ptr = "xarray"} : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> !fir.ref<i32>
|
|
hlfir.assign %5 to %8 : i32, !fir.ref<i32>
|
|
return
|
|
}
|
|
|
|
func.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"}) {
|
|
%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>>>}>>
|
|
%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>>>}>>
|
|
%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>>>>
|
|
%4 = fir.load %3 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
|
|
%c1 = arith.constant 1 : index
|
|
%c0 = arith.constant 0 : index
|
|
%5:3 = fir.box_dims %4, %c0 : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
|
|
%6 = fir.shift %5#0 : (index) -> !fir.shift<1>
|
|
%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>
|
|
%8 = fir.load %7 : !fir.ref<i32>
|
|
%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>>>>
|
|
%11 = fir.load %10 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>
|
|
%c1_0 = arith.constant 1 : index
|
|
%c0_1 = arith.constant 0 : index
|
|
%12:3 = fir.box_dims %11, %c0_1 : (!fir.box<!fir.ptr<!fir.array<?xi32>>>, index) -> (index, index, index)
|
|
%13 = fir.shift %12#0 : (index) -> !fir.shift<1>
|
|
%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>
|
|
fir.store %8 to %14 : !fir.ref<i32>
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
// The address of a composite aliases the address of any component, including an
|
|
// allocatable component. Like the address of a pointer, the address of an
|
|
// allocatable is considered non-data, so AliasAnalysis has special handling to
|
|
// detect the aliasing.
|
|
|
|
// module m
|
|
// type t
|
|
// integer, allocatable :: p
|
|
// end type
|
|
// type(t) :: x
|
|
// contains
|
|
// subroutine test()
|
|
// ! access x%p
|
|
// end subroutine
|
|
// end module
|
|
|
|
// CHECK-LABEL: Testing : "_QMmPtest"
|
|
// CHECK-DAG: x#0 <-> x%p#0: MayAlias
|
|
// CHECK-DAG: x.fir#0 <-> x%p.fir#0: MayAlias
|
|
|
|
func.func @_QMmPtest() {
|
|
%0 = fir.address_of(@_QMmEx) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>
|
|
%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>>}>>)
|
|
%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>>>
|
|
return
|
|
}
|
|
|
|
func.func @_QMmPtest.fir() {
|
|
%0 = fir.address_of(@_QMmEx) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.heap<i32>>}>>
|
|
%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>>}>>
|
|
%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>>>
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
// Nested composites.
|
|
|
|
// module m
|
|
// type t1
|
|
// integer, pointer :: p
|
|
// end type
|
|
// type t2
|
|
// type(t1) :: x
|
|
// integer, pointer :: p
|
|
// integer :: i
|
|
// end type
|
|
// contains
|
|
// subroutine test()
|
|
// type(t2) :: x
|
|
// end subroutine
|
|
// end module
|
|
|
|
// CHECK-LABEL: Testing : "_QMmPtest"
|
|
|
|
// The addresses of a composite and its pointer component alias even if the
|
|
// composite is nested within another composite.
|
|
// CHECK-DAG: x#0 <-> x%p#0: MayAlias
|
|
// CHECK-DAG: x%x#0 <-> x%x%p#0: MayAlias
|
|
// CHECK-DAG: x.fir#0 <-> x%p.fir#0: MayAlias
|
|
// CHECK-DAG: x%x.fir#0 <-> x%x%p.fir#0: MayAlias
|
|
|
|
// The addresses of different components of the same composite do not alias.
|
|
//
|
|
// TODO: Thus, all results below should be NoAlias. However, AliasAnalysis
|
|
// normally does not recognize when two values (x%x vs. x%i) are distinct
|
|
// components of the same composite (x) as opposed to being potentially
|
|
// overlapping parts of something, so it returns MayAlias. There is special
|
|
// handling for a pointer component (x%p) that does recognize it as separate
|
|
// from other components (x%i). But it does not yet distinguish the composite
|
|
// (x) from a component (x%x) that is also a composite with a pointer component
|
|
// (x%x%p). Thus, because x and x%p can alias, it assumes x%x and x%p can too.
|
|
// CHECK-DAG: x%x#0 <-> x%i#0: MayAlias
|
|
// CHECK-DAG: x%p#0 <-> x%i#0: NoAlias
|
|
// CHECK-DAG: x%x#0 <-> x%p#0: MayAlias
|
|
// CHECK-DAG: x%x.fir#0 <-> x%i.fir#0: MayAlias
|
|
// CHECK-DAG: x%p.fir#0 <-> x%i.fir#0: NoAlias
|
|
// CHECK-DAG: x%x.fir#0 <-> x%p.fir#0: MayAlias
|
|
|
|
func.func @_QMmPtest() {
|
|
%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"}
|
|
%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}>>)
|
|
%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>>}>>
|
|
%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>>>
|
|
%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>
|
|
%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>>>
|
|
return
|
|
}
|
|
|
|
func.func @_QMmPtest.fir() {
|
|
%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"}
|
|
%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}>>
|
|
%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>>}>>
|
|
%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>>>
|
|
%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>
|
|
%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>>>
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
// Pointer that might dynamically be a component.
|
|
|
|
// The address of a pointer dummy arg (argp) might alias the address of a
|
|
// pointer component (x%p) and thus the address of the associated composite (x),
|
|
// but it does not alias the addresses of other components (x%i) of the
|
|
// composite. Moreover, the address *in* argp does not alias any of those.
|
|
// Finally, an allocatable dummy arg (arga) should not be mistaken for a pointer
|
|
// dummy arg and cannot have such aliasing.
|
|
|
|
// module m
|
|
// type t
|
|
// integer, pointer :: p
|
|
// integer i
|
|
// end type
|
|
// type(t) :: glob
|
|
// contains
|
|
// subroutine test(argp, arga, arg)
|
|
// integer, pointer :: argp
|
|
// integer, allocatable :: arga
|
|
// type(t) :: arg
|
|
// type(t) :: loc
|
|
// end subroutine
|
|
// end module
|
|
|
|
// CHECK-LABEL: Testing : "_QMmPtest"
|
|
|
|
// Check when composite is a dummy arg.
|
|
//
|
|
// CHECK-DAG: argp#0 <-> arg#0: MayAlias
|
|
// CHECK-DAG: argp#0 <-> arg%p#0: MayAlias
|
|
// CHECK-DAG: argp#0 <-> arg%i#0: NoAlias
|
|
// CHECK-DAG: argp.fir#0 <-> arg.fir#0: MayAlias
|
|
// CHECK-DAG: argp.fir#0 <-> arg%p.fir#0: MayAlias
|
|
// CHECK-DAG: argp.fir#0 <-> arg%i.fir#0: NoAlias
|
|
//
|
|
// CHECK-DAG: argp.tgt#0 <-> arg#0: NoAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> arg%p#0: NoAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> arg%i#0: NoAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> arg.fir#0: NoAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> arg%p.fir#0: NoAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> arg%i.fir#0: NoAlias
|
|
//
|
|
// CHECK-DAG: arga#0 <-> arg#0: NoAlias
|
|
// CHECK-DAG: arga#0 <-> arg%p#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> arg.fir#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> arg%p.fir#0: NoAlias
|
|
|
|
// Check when composite is a global.
|
|
//
|
|
// CHECK-DAG: argp#0 <-> glob#0: MayAlias
|
|
// CHECK-DAG: argp#0 <-> glob%p#0: MayAlias
|
|
// CHECK-DAG: argp#0 <-> glob%i#0: NoAlias
|
|
// CHECK-DAG: argp.fir#0 <-> glob.fir#0: MayAlias
|
|
// CHECK-DAG: argp.fir#0 <-> glob%p.fir#0: MayAlias
|
|
// CHECK-DAG: argp.fir#0 <-> glob%i.fir#0: NoAlias
|
|
//
|
|
// CHECK-DAG: argp.tgt#0 <-> glob#0: NoAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> glob%p#0: NoAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> glob%i#0: NoAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> glob.fir#0: NoAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> glob%p.fir#0: NoAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> glob%i.fir#0: NoAlias
|
|
//
|
|
// CHECK-DAG: arga#0 <-> glob#0: NoAlias
|
|
// CHECK-DAG: arga#0 <-> glob%p#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> glob.fir#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> glob%p.fir#0: NoAlias
|
|
|
|
// Check when composite is a local and thus cannot alias a dummy arg.
|
|
//
|
|
// CHECK-DAG: argp#0 <-> loc#0: NoAlias
|
|
// CHECK-DAG: argp#0 <-> loc%p#0: NoAlias
|
|
// CHECK-DAG: argp#0 <-> loc%i#0: NoAlias
|
|
// CHECK-DAG: argp.fir#0 <-> loc.fir#0: NoAlias
|
|
// CHECK-DAG: argp.fir#0 <-> loc%p.fir#0: NoAlias
|
|
// CHECK-DAG: argp.fir#0 <-> loc%i.fir#0: NoAlias
|
|
//
|
|
// CHECK-DAG: argp.tgt#0 <-> loc#0: NoAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> loc%p#0: NoAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> loc%i#0: NoAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> loc.fir#0: NoAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> loc%p.fir#0: NoAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> loc%i.fir#0: NoAlias
|
|
//
|
|
// CHECK-DAG: arga#0 <-> loc#0: NoAlias
|
|
// CHECK-DAG: arga#0 <-> loc%p#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> loc.fir#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> loc%p.fir#0: NoAlias
|
|
|
|
fir.global @_QMmEglob : !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>
|
|
|
|
func.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"}) {
|
|
%0 = fir.dummy_scope : !fir.dscope
|
|
|
|
%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>>>)
|
|
%2 = fir.load %1#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
|
|
%3 = fir.box_addr %2 {test.ptr="argp.tgt"} : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
|
|
|
|
%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>>>)
|
|
|
|
%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}>>)
|
|
%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>>>
|
|
%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>
|
|
|
|
%8 = fir.address_of(@_QMmEglob) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>
|
|
%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}>>)
|
|
%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>>>
|
|
%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>
|
|
|
|
%12 = fir.alloca !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}> {bindc_name = "loc", uniq_name = "_QMmFtestEloc"}
|
|
%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}>>)
|
|
%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>>>
|
|
%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>
|
|
|
|
return
|
|
}
|
|
|
|
func.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"}) {
|
|
%0 = fir.dummy_scope : !fir.dscope
|
|
|
|
%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>>>
|
|
%2 = fir.load %1 : !fir.ref<!fir.box<!fir.ptr<i32>>>
|
|
%3 = fir.box_addr %2 {test.ptr = "argp.tgt.fir"} : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
|
|
|
|
%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>>>
|
|
|
|
%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}>>
|
|
%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>>>
|
|
%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>
|
|
|
|
%10 = fir.address_of(@_QMmEglob) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>
|
|
%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}>>
|
|
%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>>>
|
|
%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>
|
|
|
|
%16 = fir.alloca !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}> {bindc_name = "loc", uniq_name = "_QMmFtestEloc"}
|
|
%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}>>
|
|
%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>>>
|
|
%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>
|
|
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
// Same as previous case but argp and arga are HostAssoc.
|
|
|
|
// module m
|
|
// type t
|
|
// integer, pointer :: p
|
|
// integer i
|
|
// end type
|
|
// type(t) :: glob
|
|
// contains
|
|
// subroutine parent(argp, arga)
|
|
// integer, pointer :: argp
|
|
// integer, allocatable :: arga
|
|
// type(t) :: arg
|
|
// call test(arg)
|
|
// contains
|
|
// subroutine test(arg)
|
|
// type(t) :: arg
|
|
// type(t) :: loc
|
|
// end subroutine
|
|
// end subroutine
|
|
// end module
|
|
|
|
// CHECK-LABEL: Testing : "_QMmFparentPtest"
|
|
|
|
// Check when composite is a dummy arg.
|
|
//
|
|
// CHECK-DAG: argp#0 <-> arg#0: MayAlias
|
|
// CHECK-DAG: argp#0 <-> arg%p#0: MayAlias
|
|
// CHECK-DAG: argp#0 <-> arg%i#0: NoAlias
|
|
// CHECK-DAG: argp.fir#0 <-> arg.fir#0: MayAlias
|
|
// CHECK-DAG: argp.fir#0 <-> arg%p.fir#0: MayAlias
|
|
// CHECK-DAG: argp.fir#0 <-> arg%i.fir#0: NoAlias
|
|
//
|
|
// TODO: Shouldn't these be NoAlias? However, argp.tgt is currently handled as
|
|
// Indirect.
|
|
// CHECK-DAG: argp.tgt#0 <-> arg#0: MayAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> arg%p#0: MayAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> arg%i#0: MayAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> arg.fir#0: MayAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> arg%p.fir#0: MayAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> arg%i.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: arga#0 <-> arg#0: NoAlias
|
|
// CHECK-DAG: arga#0 <-> arg%p#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> arg.fir#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> arg%p.fir#0: NoAlias
|
|
|
|
// Check when composite is a global.
|
|
//
|
|
// CHECK-DAG: argp#0 <-> glob#0: MayAlias
|
|
// CHECK-DAG: argp#0 <-> glob%p#0: MayAlias
|
|
// CHECK-DAG: argp#0 <-> glob%i#0: NoAlias
|
|
// CHECK-DAG: argp.fir#0 <-> glob.fir#0: MayAlias
|
|
// CHECK-DAG: argp.fir#0 <-> glob%p.fir#0: MayAlias
|
|
// CHECK-DAG: argp.fir#0 <-> glob%i.fir#0: NoAlias
|
|
//
|
|
// TODO: Shouldn't these be NoAlias? However, argp.tgt is currently handled as
|
|
// Indirect.
|
|
// CHECK-DAG: argp.tgt#0 <-> glob#0: MayAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> glob%p#0: MayAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> glob%i#0: MayAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> glob.fir#0: MayAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> glob%p.fir#0: MayAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> glob%i.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: arga#0 <-> glob#0: NoAlias
|
|
// CHECK-DAG: arga#0 <-> glob%p#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> glob.fir#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> glob%p.fir#0: NoAlias
|
|
|
|
// Check when composite is a local and thus cannot alias a dummy arg.
|
|
//
|
|
// CHECK-DAG: argp#0 <-> loc#0: NoAlias
|
|
// CHECK-DAG: argp#0 <-> loc%p#0: NoAlias
|
|
// CHECK-DAG: argp#0 <-> loc%i#0: NoAlias
|
|
// CHECK-DAG: argp.fir#0 <-> loc.fir#0: NoAlias
|
|
// CHECK-DAG: argp.fir#0 <-> loc%p.fir#0: NoAlias
|
|
// CHECK-DAG: argp.fir#0 <-> loc%i.fir#0: NoAlias
|
|
//
|
|
// TODO: Shouldn't these be NoAlias? However, argp.tgt is currently handled as
|
|
// Indirect.
|
|
// CHECK-DAG: argp.tgt#0 <-> loc#0: MayAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> loc%p#0: MayAlias
|
|
// CHECK-DAG: argp.tgt#0 <-> loc%i#0: MayAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> loc.fir#0: MayAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> loc%p.fir#0: MayAlias
|
|
// CHECK-DAG: argp.tgt.fir#0 <-> loc%i.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: arga#0 <-> loc#0: NoAlias
|
|
// CHECK-DAG: arga#0 <-> loc%p#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> loc.fir#0: NoAlias
|
|
// CHECK-DAG: arga.fir#0 <-> loc%p.fir#0: NoAlias
|
|
|
|
fir.global @_QMmEglob : !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>
|
|
|
|
func.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>} {
|
|
%0 = fir.dummy_scope : !fir.dscope
|
|
|
|
%c0_i32 = arith.constant 0 : i32
|
|
%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>>>>
|
|
%2 = fir.load %1 : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<i32>>>>
|
|
%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>>>)
|
|
%4 = fir.load %3#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
|
|
%5 = fir.box_addr %4 {test.ptr="argp.tgt"} : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
|
|
|
|
%c1_i32 = arith.constant 1 : i32
|
|
%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>>>>
|
|
%11 = fir.load %10 : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.heap<i32>>>>
|
|
%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>>>)
|
|
|
|
%20 = fir.address_of(@_QMmEglob) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>
|
|
%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}>>)
|
|
%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>>>
|
|
%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>
|
|
|
|
%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}>>)
|
|
%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>>>
|
|
%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>
|
|
|
|
%40 = fir.alloca !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}> {bindc_name = "loc", uniq_name = "_QMmFparentFtestEloc"}
|
|
%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}>>)
|
|
%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>>>
|
|
%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>
|
|
|
|
return
|
|
}
|
|
|
|
func.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>} {
|
|
%0 = fir.dummy_scope : !fir.dscope
|
|
|
|
%c0_i32 = arith.constant 0 : i32
|
|
%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>>>>
|
|
%2 = fir.load %1 : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.ptr<i32>>>>
|
|
%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>>>
|
|
%4 = fir.load %3 : !fir.ref<!fir.box<!fir.ptr<i32>>>
|
|
%5 = fir.box_addr %4 {test.ptr = "argp.tgt.fir"} : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
|
|
|
|
%c1_i32 = arith.constant 1 : i32
|
|
%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>>>>
|
|
%7 = fir.load %6 : !fir.llvm_ptr<!fir.ref<!fir.box<!fir.heap<i32>>>>
|
|
%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>>>
|
|
|
|
%9 = fir.address_of(@_QMmEglob) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}>>
|
|
%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}>>
|
|
%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>>>
|
|
%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>
|
|
|
|
%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}>>
|
|
%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>>>
|
|
%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>
|
|
|
|
%20 = fir.alloca !fir.type<_QMmTt{p:!fir.box<!fir.ptr<i32>>,i:i32}> {bindc_name = "loc", uniq_name = "_QMmFparentFtestEloc"}
|
|
%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}>>
|
|
%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>>>
|
|
%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>
|
|
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
// Dummy arg with target attribute and pointer component.
|
|
|
|
// The address of a dummy arg (arg0) may alias the address of a global (glob0)
|
|
// or another dummy arg (arg1) when both have target attributes. If either is a
|
|
// composite, the addresses of components (whether data like r, or non-data like
|
|
// p and a) may also alias the composite or the same component. However, target
|
|
// attributes do not permit two globals (glob0 and glob1) to alias.
|
|
|
|
// module m
|
|
// type t
|
|
// real, pointer :: p
|
|
// real, allocatable :: a
|
|
// real :: r
|
|
// end type
|
|
// type(t), target :: glob0
|
|
// type(t), target :: glob1
|
|
// contains
|
|
// subroutine test(arg0, arg1)
|
|
// type(t), target :: arg0
|
|
// type(t), target :: arg1
|
|
// end subroutine
|
|
// end module
|
|
|
|
// TODO: All glob0 vs. glob1 cases can be NoAlias. However, AliasAnalysis
|
|
// currently indiscriminately treats all targets that are data (addresses of
|
|
// glob[01] and glob[01]%r but not glob[01]%p and glob[01]%a) as aliasing.
|
|
|
|
// Check composite vs. composite.
|
|
//
|
|
// CHECK-DAG: arg0#0 <-> arg1#0: MayAlias
|
|
// CHECK-DAG: arg0.fir#0 <-> arg1.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: arg0#0 <-> glob0#0: MayAlias
|
|
// CHECK-DAG: arg0.fir#0 <-> glob0.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: glob0#0 <-> glob1#0: MayAlias
|
|
// CHECK-DAG: glob0.fir#0 <-> glob1.fir#0: MayAlias
|
|
|
|
// Check component vs. composite.
|
|
//
|
|
// CHECK-DAG: arg0%p#0 <-> arg1#0: MayAlias
|
|
// CHECK-DAG: arg0%a#0 <-> arg1#0: MayAlias
|
|
// CHECK-DAG: arg0%r#0 <-> arg1#0: MayAlias
|
|
// CHECK-DAG: arg0%p.fir#0 <-> arg1.fir#0: MayAlias
|
|
// CHECK-DAG: arg0%a.fir#0 <-> arg1.fir#0: MayAlias
|
|
// CHECK-DAG: arg0%r.fir#0 <-> arg1.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: arg0%p#0 <-> glob0#0: MayAlias
|
|
// CHECK-DAG: arg0%a#0 <-> glob0#0: MayAlias
|
|
// CHECK-DAG: arg0%r#0 <-> glob0#0: MayAlias
|
|
// CHECK-DAG: arg0%p.fir#0 <-> glob0.fir#0: MayAlias
|
|
// CHECK-DAG: arg0%a.fir#0 <-> glob0.fir#0: MayAlias
|
|
// CHECK-DAG: arg0%r.fir#0 <-> glob0.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: glob0%p#0 <-> glob1#0: NoAlias
|
|
// CHECK-DAG: glob0%a#0 <-> glob1#0: NoAlias
|
|
// CHECK-DAG: glob0%r#0 <-> glob1#0: MayAlias
|
|
// CHECK-DAG: glob0%p.fir#0 <-> glob1.fir#0: NoAlias
|
|
// CHECK-DAG: glob0%a.fir#0 <-> glob1.fir#0: NoAlias
|
|
// CHECK-DAG: glob0%r.fir#0 <-> glob1.fir#0: MayAlias
|
|
|
|
// Check composite vs. component.
|
|
//
|
|
// CHECK-DAG: arg0#0 <-> arg1%p#0: MayAlias
|
|
// CHECK-DAG: arg0#0 <-> arg1%a#0: MayAlias
|
|
// CHECK-DAG: arg0#0 <-> arg1%r#0: MayAlias
|
|
// CHECK-DAG: arg0.fir#0 <-> arg1%p.fir#0: MayAlias
|
|
// CHECK-DAG: arg0.fir#0 <-> arg1%a.fir#0: MayAlias
|
|
// CHECK-DAG: arg0.fir#0 <-> arg1%r.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: arg0#0 <-> glob0%p#0: MayAlias
|
|
// CHECK-DAG: arg0#0 <-> glob0%a#0: MayAlias
|
|
// CHECK-DAG: arg0#0 <-> glob0%r#0: MayAlias
|
|
// CHECK-DAG: arg0.fir#0 <-> glob0%p.fir#0: MayAlias
|
|
// CHECK-DAG: arg0.fir#0 <-> glob0%a.fir#0: MayAlias
|
|
// CHECK-DAG: arg0.fir#0 <-> glob0%r.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: glob0#0 <-> glob1%p#0: NoAlias
|
|
// CHECK-DAG: glob0#0 <-> glob1%a#0: NoAlias
|
|
// CHECK-DAG: glob0#0 <-> glob1%r#0: MayAlias
|
|
// CHECK-DAG: glob0.fir#0 <-> glob1%p.fir#0: NoAlias
|
|
// CHECK-DAG: glob0.fir#0 <-> glob1%a.fir#0: NoAlias
|
|
// CHECK-DAG: glob0.fir#0 <-> glob1%r.fir#0: MayAlias
|
|
|
|
// Check component vs. component.
|
|
//
|
|
// CHECK-DAG: arg0%p#0 <-> arg1%p#0: MayAlias
|
|
// CHECK-DAG: arg0%a#0 <-> arg1%a#0: MayAlias
|
|
// CHECK-DAG: arg0%r#0 <-> arg1%r#0: MayAlias
|
|
// CHECK-DAG: arg0%p.fir#0 <-> arg1%p.fir#0: MayAlias
|
|
// CHECK-DAG: arg0%a.fir#0 <-> arg1%a.fir#0: MayAlias
|
|
// CHECK-DAG: arg0%r.fir#0 <-> arg1%r.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: arg0%p.fir#0 <-> glob0%p.fir#0: MayAlias
|
|
// CHECK-DAG: arg0%a.fir#0 <-> glob0%a.fir#0: MayAlias
|
|
// CHECK-DAG: arg0%r.fir#0 <-> glob0%r.fir#0: MayAlias
|
|
//
|
|
// CHECK-DAG: glob0%p.fir#0 <-> glob1%p.fir#0: NoAlias
|
|
// CHECK-DAG: glob0%a.fir#0 <-> glob1%a.fir#0: NoAlias
|
|
// CHECK-DAG: glob0%r.fir#0 <-> glob1%r.fir#0: MayAlias
|
|
|
|
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}) {
|
|
%0 = fir.dummy_scope : !fir.dscope
|
|
|
|
%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}>>)
|
|
%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>>>
|
|
%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>>>
|
|
%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>
|
|
|
|
%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}>>)
|
|
%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>>>
|
|
%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>>>
|
|
%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>
|
|
|
|
%30 = fir.address_of(@_QMmEglob0) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
|
|
%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}>>)
|
|
%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>>>
|
|
%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>>>
|
|
%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>
|
|
|
|
%40 = fir.address_of(@_QMmEglob1) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
|
|
%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}>>)
|
|
%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>>>
|
|
%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>>>
|
|
%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>
|
|
|
|
return
|
|
}
|
|
|
|
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}) {
|
|
%0 = fir.dummy_scope : !fir.dscope
|
|
|
|
%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}>>
|
|
%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>>>
|
|
%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>>>
|
|
%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>
|
|
|
|
%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}>>
|
|
%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>>>
|
|
%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>>>
|
|
%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>
|
|
|
|
%15 = fir.address_of(@_QMmEglob0) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
|
|
%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}>>
|
|
%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>>>
|
|
%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>>>
|
|
%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>
|
|
|
|
%23 = fir.address_of(@_QMmEglob1) : !fir.ref<!fir.type<_QMmTt{p:!fir.box<!fir.ptr<f32>>,a:!fir.box<!fir.heap<f32>>,r:f32}>>
|
|
%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}>>
|
|
%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>>>
|
|
%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>>>
|
|
%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>
|
|
|
|
return
|
|
}
|
|
|
|
// -----
|
|
|
|
// Allocatable dummy arg with target attribute.
|
|
|
|
// This case is like the previous one except that the non-data is the address
|
|
// of the dummy arg itself rather than of a pointer component of the dummy arg.
|
|
// The goal is to check that logic introduced into AliasAnalysis to handle the
|
|
// pointer component case doesn't break this related one.
|
|
|
|
// module m
|
|
// real, allocatable, target :: glob0
|
|
// real, allocatable, target :: glob1
|
|
// contains
|
|
// subroutine test(arg0, arg1)
|
|
// real, allocatable, target :: arg0
|
|
// real, allocatable, target :: arg1
|
|
// end subroutine
|
|
// end module
|
|
|
|
// CHECK-DAG: arg0#0 <-> arg1#0: MayAlias
|
|
// CHECK-DAG: arg0#0 <-> glob0#0: MayAlias
|
|
// CHECK-DAG: glob0#0 <-> glob1#0: NoAlias
|
|
|
|
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}) {
|
|
%0 = fir.dummy_scope : !fir.dscope
|
|
|
|
%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>>>)
|
|
%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>>>)
|
|
|
|
%20 = fir.address_of(@_QMmEglob0) : !fir.ref<!fir.box<!fir.heap<f32>>>
|
|
%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>>>)
|
|
%22 = fir.address_of(@_QMmEglob1) : !fir.ref<!fir.box<!fir.heap<f32>>>
|
|
%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>>>)
|
|
|
|
return
|
|
}
|