blob: 50c3ca715ea8803c2652c23d87afc4e44b3b437c [file] [edit]
// Test that values connected through zero-offset FortranObjectViewOpInterface
// operations (embox, declare, convert) are recognized as MustAlias, even when
// getSource() would set approximateSource due to upstream sliced operations.
// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s
// Test: embox(ref) vs ref => MustAlias
// CHECK-LABEL: Testing : "_QPtest_embox_ref"
// CHECK-DAG: ref#0 <-> box#0: MustAlias
func.func @_QPtest_embox_ref(%arg0: !fir.ref<!fir.array<10xf32>> {fir.bindc_name = "b"}) {
%c10 = arith.constant 10 : index
%shape = fir.shape %c10 : (index) -> !fir.shape<1>
%ref = fir.declare %arg0(%shape) {test.ptr = "ref", uniq_name = "b"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
%box = fir.embox %ref(%shape) {test.ptr = "box"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xf32>>
return
}
// -----
// Test: declare(ref) vs ref => MustAlias
// CHECK-LABEL: Testing : "_QPtest_declare_ref"
// CHECK-DAG: ref#0 <-> decl#0: MustAlias
func.func @_QPtest_declare_ref() {
%ref = fir.alloca !fir.array<10xf32> {test.ptr = "ref"}
%c10 = arith.constant 10 : index
%shape = fir.shape %c10 : (index) -> !fir.shape<1>
%decl = fir.declare %ref(%shape) {test.ptr = "decl", uniq_name = "arr"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
return
}
// -----
// Test: embox(declare(ref)) vs ref => MustAlias (two-hop chain)
// CHECK-LABEL: Testing : "_QPtest_embox_declare_ref"
// CHECK-DAG: ref#0 <-> box#0: MustAlias
func.func @_QPtest_embox_declare_ref() {
%ref = fir.alloca !fir.array<10xf32> {test.ptr = "ref"}
%c10 = arith.constant 10 : index
%shape = fir.shape %c10 : (index) -> !fir.shape<1>
%decl = fir.declare %ref(%shape) {uniq_name = "arr"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.ref<!fir.array<10xf32>>
%box = fir.embox %decl(%shape) {test.ptr = "box"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> !fir.box<!fir.array<10xf32>>
return
}
// -----
// Test: two box_addr from the same source => MustAlias (sibling case)
// CHECK-LABEL: Testing : "_QPtest_sibling_box_addr"
// CHECK-DAG: addr1#0 <-> addr2#0: MustAlias
func.func @_QPtest_sibling_box_addr(%arg0: !fir.box<!fir.array<?xf32>> {fir.bindc_name = "x"}) {
%0 = fir.dummy_scope : !fir.dscope
%1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QPtestEx"} : (!fir.box<!fir.array<?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.box<!fir.array<?xf32>>)
%addr1 = fir.box_addr %1#0 {test.ptr = "addr1"} : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<f32>
%addr2 = fir.box_addr %1#0 {test.ptr = "addr2"} : (!fir.box<!fir.array<?xf32>>) -> !fir.ref<f32>
return
}
// -----
// Test: embox with slice does NOT chain-walk to the ref (non-zero offset)
// CHECK-LABEL: Testing : "_QPtest_embox_slice_ref"
// CHECK-DAG: ref#0 <-> sliced_box#0: MayAlias
func.func @_QPtest_embox_slice_ref() {
%ref = fir.alloca !fir.array<10xf32> {test.ptr = "ref"}
%c10 = arith.constant 10 : index
%c1 = arith.constant 1 : index
%c5 = arith.constant 5 : index
%shape = fir.shape %c10 : (index) -> !fir.shape<1>
%slice = fir.slice %c1, %c5, %c1 : (index, index, index) -> !fir.slice<1>
%sliced_box = fir.embox %ref(%shape) [%slice] {test.ptr = "sliced_box"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.slice<1>) -> !fir.box<!fir.array<?xf32>>
return
}