Files
TheRock/compiler/amd-llvm/flang/test/Analysis/AliasAnalysis/alias-analysis-acc.mlir
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

592 lines
27 KiB
MLIR

// RUN: fir-opt %s -pass-pipeline='builtin.module(func.func(test-fir-alias-analysis))' -split-input-file --mlir-disable-threading 2>&1 | FileCheck %s
// -----
// Two acc.copyin results from distinct host allocas do not alias.
// CHECK-LABEL: Testing : "testBothOutsideCopyinDistinctHosts"
// CHECK-DAG: cin_a#0 <-> cin_b#0: NoAlias
func.func @testBothOutsideCopyinDistinctHosts() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%b = fir.alloca f32 {uniq_name = "_QFEb"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%db = fir.declare %b {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a", test.ptr = "cin_a"}
%cb = acc.copyin varPtr(%db : !fir.ref<f32>) -> !fir.ref<f32> {name = "b", test.ptr = "cin_b"}
return
}
// -----
// Two acc.copyin results from dummy arguments that are Fortran TARGET variables:
// they may alias.
// CHECK-LABEL: Testing : "testBothOutsideCopyinTargetDummyArgsMayAlias"
// CHECK-DAG: arg_cp_a#0 <-> arg_cp_b#0: MayAlias
func.func @testBothOutsideCopyinTargetDummyArgsMayAlias(%arg0: !fir.ref<f32> {fir.bindc_name = "x"}, %arg1: !fir.ref<f32> {fir.bindc_name = "y"}) {
%ds = fir.dummy_scope : !fir.dscope
%dx = fir.declare %arg0 dummy_scope %ds arg 1 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFEex"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%dy = fir.declare %arg1 dummy_scope %ds arg 2 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFEey"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%cx = acc.copyin varPtr(%dx : !fir.ref<f32>) -> !fir.ref<f32> {name = "x", test.ptr = "arg_cp_a"}
%cy = acc.copyin varPtr(%dy : !fir.ref<f32>) -> !fir.ref<f32> {name = "y", test.ptr = "arg_cp_b"}
return
}
// -----
// Two acc.copyin results mapping the same host ref must alias.
// CHECK-LABEL: Testing : "testBothOutsideCopyinSameHostMustAlias"
// CHECK-DAG: out_must_a#0 <-> out_must_b#0: MustAlias
func.func @testBothOutsideCopyinSameHostMustAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca1 = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a", test.ptr = "out_must_a"}
%ca2 = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a", test.ptr = "out_must_b"}
return
}
// -----
// CHECK-LABEL: Testing : "testBothOutsideCreateDistinctHosts"
// CHECK-DAG: crt_a#0 <-> crt_b#0: NoAlias
func.func @testBothOutsideCreateDistinctHosts() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%b = fir.alloca f32 {uniq_name = "_QFEb"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%db = fir.declare %b {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ta = acc.create varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a", test.ptr = "crt_a"}
%tb = acc.create varPtr(%db : !fir.ref<f32>) -> !fir.ref<f32> {name = "b", test.ptr = "crt_b"}
return
}
// -----
// Same distinct-host copyins as above, but threaded through acc.compute_region
// block arguments.
// CHECK-LABEL: Testing : "testComputeRegionCopyinDistinctHostsInsideConvert"
// CHECK-DAG: cr_dist_a#0 <-> cr_dist_b#0: NoAlias
func.func @testComputeRegionCopyinDistinctHostsInsideConvert() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%b = fir.alloca f32 {uniq_name = "_QFEb"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%db = fir.declare %b {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%cb = acc.copyin varPtr(%db : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
acc.compute_region ins(%arg0 = %ca, %arg1 = %cb) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %arg0 {test.ptr = "cr_dist_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %arg1 {test.ptr = "cr_dist_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.kernels"}
return
}
// -----
// CHECK-LABEL: Testing : "testComputeRegionCreateDistinctHostsInsideConvert"
// CHECK-DAG: cr_crt_a#0 <-> cr_crt_b#0: NoAlias
func.func @testComputeRegionCreateDistinctHostsInsideConvert() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%b = fir.alloca f32 {uniq_name = "_QFEb"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%db = fir.declare %b {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ta = acc.create varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%tb = acc.create varPtr(%db : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
acc.compute_region ins(%arg0 = %ta, %arg1 = %tb) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %arg0 {test.ptr = "cr_crt_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %arg1 {test.ptr = "cr_crt_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.kernels"}
return
}
// -----
// Same TARGET dummy copyins as testBothOutsideCopyinTargetDummyArgsMayAlias,
// through acc.compute_region block args.
// CHECK-LABEL: Testing : "testComputeRegionCopyinTargetDummiesMayAliasInsideConvert"
// CHECK-DAG: cr_tgt_a#0 <-> cr_tgt_b#0: MayAlias
func.func @testComputeRegionCopyinTargetDummiesMayAliasInsideConvert(%arg0: !fir.ref<f32> {fir.bindc_name = "x"}, %arg1: !fir.ref<f32> {fir.bindc_name = "y"}) {
%ds = fir.dummy_scope : !fir.dscope
%dx = fir.declare %arg0 dummy_scope %ds arg 1 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFEex"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%dy = fir.declare %arg1 dummy_scope %ds arg 2 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFEey"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%cx = acc.copyin varPtr(%dx : !fir.ref<f32>) -> !fir.ref<f32> {name = "x"}
%cy = acc.copyin varPtr(%dy : !fir.ref<f32>) -> !fir.ref<f32> {name = "y"}
acc.compute_region ins(%cr0 = %cx, %cr1 = %cy) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %cr0 {test.ptr = "cr_tgt_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %cr1 {test.ptr = "cr_tgt_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.parallel"}
return
}
// -----
// Single host copyin wired twice through arguments; both block args alias the
// same mapped host variable.
// CHECK-LABEL: Testing : "testComputeRegionCopyinSameHostMustAliasInsideConvert"
// CHECK-DAG: cr_must_a#0 <-> cr_must_b#0: MustAlias
func.func @testComputeRegionCopyinSameHostMustAliasInsideConvert() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.compute_region ins(%arg0 = %ca, %arg1 = %ca) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %arg0 {test.ptr = "cr_must_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %arg1 {test.ptr = "cr_must_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.kernels"}
return
}
// -----
// Distinct-host copyins passed as acc.kernels dataOperands.
// CHECK-LABEL: Testing : "testKernelsCopyinDistinctHostsInsideConvert"
// CHECK-DAG: kern_dist_a#0 <-> kern_dist_b#0: NoAlias
func.func @testKernelsCopyinDistinctHostsInsideConvert() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%b = fir.alloca f32 {uniq_name = "_QFEb"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%db = fir.declare %b {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%cb = acc.copyin varPtr(%db : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
acc.kernels dataOperands(%ca, %cb : !fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %ca {test.ptr = "kern_dist_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %cb {test.ptr = "kern_dist_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.terminator
}
return
}
// -----
// CHECK-LABEL: Testing : "testKernelsCreateDistinctHostsInsideConvert"
// CHECK-DAG: kern_crt_a#0 <-> kern_crt_b#0: NoAlias
func.func @testKernelsCreateDistinctHostsInsideConvert() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%b = fir.alloca f32 {uniq_name = "_QFEb"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%db = fir.declare %b {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ta = acc.create varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%tb = acc.create varPtr(%db : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
acc.kernels dataOperands(%ta, %tb : !fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %ta {test.ptr = "kern_crt_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %tb {test.ptr = "kern_crt_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.terminator
}
return
}
// -----
// TARGET dummy copyins as acc.kernels dataOperands.
// CHECK-LABEL: Testing : "testKernelsCopyinTargetDummiesMayAliasInsideConvert"
// CHECK-DAG: kern_tgt_a#0 <-> kern_tgt_b#0: MayAlias
func.func @testKernelsCopyinTargetDummiesMayAliasInsideConvert(%arg0: !fir.ref<f32> {fir.bindc_name = "x"}, %arg1: !fir.ref<f32> {fir.bindc_name = "y"}) {
%ds = fir.dummy_scope : !fir.dscope
%dx = fir.declare %arg0 dummy_scope %ds arg 1 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFEex"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%dy = fir.declare %arg1 dummy_scope %ds arg 2 {fortran_attrs = #fir.var_attrs<target>, uniq_name = "_QFEey"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%cx = acc.copyin varPtr(%dx : !fir.ref<f32>) -> !fir.ref<f32> {name = "x"}
%cy = acc.copyin varPtr(%dy : !fir.ref<f32>) -> !fir.ref<f32> {name = "y"}
acc.kernels dataOperands(%cx, %cy : !fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %cx {test.ptr = "kern_tgt_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %cy {test.ptr = "kern_tgt_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.terminator
}
return
}
// -----
// Same copyin value listed twice in dataOperands; both converts must alias.
// CHECK-LABEL: Testing : "testKernelsCopyinSameHostMustAliasInsideConvert"
// CHECK-DAG: kern_must_a#0 <-> kern_must_b#0: MustAlias
func.func @testKernelsCopyinSameHostMustAliasInsideConvert() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.kernels dataOperands(%ca : !fir.ref<f32>) {
%va = fir.convert %ca {test.ptr = "kern_must_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %ca {test.ptr = "kern_must_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.terminator
}
return
}
// -----
// acc.compute_region: both queried values are inside the region; test.ptr is on
// fir.convert of each captured private (traces block operands without tagging
// the region op).
// CHECK-LABEL: Testing : "testComputeRegionPrivateInsideConvert"
// CHECK-DAG: cr_priv_a#0 <-> cr_priv_b#0: NoAlias
func.func @testComputeRegionPrivateInsideConvert() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%b = fir.alloca f32 {uniq_name = "_QFEb"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%db = fir.declare %b {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
%pa = acc.private varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%pb = acc.private varPtr(%db : !fir.ref<f32>) -> !fir.ref<f32> {name = "b"}
acc.compute_region ins(%arg0 = %pa, %arg1 = %pb) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %arg0 {test.ptr = "cr_priv_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %arg1 {test.ptr = "cr_priv_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.parallel"}
return
}
// -----
// Same host ref as both acc.copyin and acc.private operands (two copyins would
// must-alias); private-like mapping is a distinct allocation vs copyin.
// CHECK-LABEL: Testing : "testComputeRegionCopyinVsPrivateSameHostNoAlias"
// CHECK-DAG: cr_mix_cp#0 <-> cr_mix_pr#0: NoAlias
func.func @testComputeRegionCopyinVsPrivateSameHostNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%pp = acc.private varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.compute_region ins(%arg0 = %ca, %arg1 = %pp) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %arg0 {test.ptr = "cr_mix_cp"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %arg1 {test.ptr = "cr_mix_pr"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.parallel"}
return
}
// -----
// CHECK-LABEL: Testing : "testComputeRegionCreateVsPrivateSameHostNoAlias"
// CHECK-DAG: cr_mix_cr#0 <-> cr_mix_pr2#0: NoAlias
func.func @testComputeRegionCreateVsPrivateSameHostNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ta = acc.create varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%pp = acc.private varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.compute_region ins(%arg0 = %ta, %arg1 = %pp) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %arg0 {test.ptr = "cr_mix_cr"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %arg1 {test.ptr = "cr_mix_pr2"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.parallel"}
return
}
// -----
// Same host: acc.copyin vs acc.firstprivate.
// CHECK-LABEL: Testing : "testComputeRegionCopyinVsFirstprivateSameHostNoAlias"
// CHECK-DAG: cr_fp_cp#0 <-> cr_fp_pr#0: NoAlias
func.func @testComputeRegionCopyinVsFirstprivateSameHostNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%pf = acc.firstprivate varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.compute_region ins(%arg0 = %ca, %arg1 = %pf) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %arg0 {test.ptr = "cr_fp_cp"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %arg1 {test.ptr = "cr_fp_pr"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.parallel"}
return
}
// -----
// Same host: acc.copyin vs acc.firstprivate_map.
// CHECK-LABEL: Testing : "testComputeRegionCopyinVsFirstprivateMapSameHostNoAlias"
// CHECK-DAG: cr_fpm_cp#0 <-> cr_fpm_fm#0: NoAlias
func.func @testComputeRegionCopyinVsFirstprivateMapSameHostNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%fm = acc.firstprivate_map varPtr(%da : !fir.ref<f32>) varType(f32) -> !fir.ref<f32> {name = "a"}
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.compute_region ins(%arg0 = %ca, %arg1 = %fm) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %arg0 {test.ptr = "cr_fpm_cp"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %arg1 {test.ptr = "cr_fpm_fm"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.kernels"}
return
}
// -----
// acc.kernels: same host as copyin and acc.private dataOperands.
// CHECK-LABEL: Testing : "testKernelsCopyinVsPrivateSameHostNoAlias"
// CHECK-DAG: k_mix_cp#0 <-> k_mix_pr#0: NoAlias
func.func @testKernelsCopyinVsPrivateSameHostNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%pp = acc.private varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.kernels dataOperands(%ca : !fir.ref<f32>) private(%pp : !fir.ref<f32>) {
%va = fir.convert %ca {test.ptr = "k_mix_cp"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %pp {test.ptr = "k_mix_pr"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.terminator
}
return
}
// -----
// CHECK-LABEL: Testing : "testKernelsCreateVsPrivateSameHostNoAlias"
// CHECK-DAG: k_mix_cr#0 <-> k_mix_pr2#0: NoAlias
func.func @testKernelsCreateVsPrivateSameHostNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ta = acc.create varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%pp = acc.private varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.kernels dataOperands(%ta : !fir.ref<f32>) private(%pp : !fir.ref<f32>) {
%va = fir.convert %ta {test.ptr = "k_mix_cr"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %pp {test.ptr = "k_mix_pr2"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.terminator
}
return
}
// -----
// acc.kernels: acc.copyin vs acc.firstprivate.
// CHECK-LABEL: Testing : "testKernelsCopyinVsFirstprivateSameHostNoAlias"
// CHECK-DAG: k_fp_cp#0 <-> k_fp_pr#0: NoAlias
func.func @testKernelsCopyinVsFirstprivateSameHostNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%pf = acc.firstprivate varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.kernels dataOperands(%ca : !fir.ref<f32>) firstprivate(%pf : !fir.ref<f32>) {
%va = fir.convert %ca {test.ptr = "k_fp_cp"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %pf {test.ptr = "k_fp_pr"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.terminator
}
return
}
// -----
// acc.kernels: acc.copyin vs acc.firstprivate_map.
// CHECK-LABEL: Testing : "testKernelsCopyinVsFirstprivateMapSameHostNoAlias"
// CHECK-DAG: k_fpm_cp#0 <-> k_fpm_fm#0: NoAlias
func.func @testKernelsCopyinVsFirstprivateMapSameHostNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%fm = acc.firstprivate_map varPtr(%da : !fir.ref<f32>) varType(f32) -> !fir.ref<f32> {name = "a"}
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.kernels dataOperands(%ca : !fir.ref<f32>) firstprivate(%fm : !fir.ref<f32>) {
%va = fir.convert %ca {test.ptr = "k_fpm_cp"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %fm {test.ptr = "k_fpm_fm"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.terminator
}
return
}
// -----
// acc.private inside acc.compute_region; ins carries acc.create from the host ref.
// CHECK-LABEL: Testing : "testComputeRegionPrivateOpInsideVsInsCreateNoAlias"
// CHECK-DAG: cr_body_pr#0 <-> cr_body_cr#0: NoAlias
func.func @testComputeRegionPrivateOpInsideVsInsCreateNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%tc = acc.create varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.compute_region ins(%arg0 = %tc) : (!fir.ref<f32>) {
%pv = acc.private varPtr(%arg0 : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%vb = fir.convert %pv {test.ptr = "cr_body_pr"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vc = fir.convert %arg0 {test.ptr = "cr_body_cr"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.parallel"}
return
}
// -----
// acc.private inside acc.kernels on the dataOperand copyin of the host ref.
// CHECK-LABEL: Testing : "testKernelsPrivateOpInsideVsDataCopyinNoAlias"
// CHECK-DAG: k_body_pr#0 <-> k_body_cp#0: NoAlias
func.func @testKernelsPrivateOpInsideVsDataCopyinNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ca = acc.copyin varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.kernels dataOperands(%ca : !fir.ref<f32>) {
%pv = acc.private varPtr(%ca : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
%vb = fir.convert %pv {test.ptr = "k_body_pr"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vc = fir.convert %ca {test.ptr = "k_body_cp"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.terminator
}
return
}
// -----
acc.reduction.recipe @red_f32_aa : !fir.ref<f32> reduction_operator <add> init {
^bb0(%arg0: !fir.ref<f32>):
%init = fir.alloca f32
acc.yield %init : !fir.ref<f32>
} combiner {
^bb0(%lhs: !fir.ref<f32>, %rhs: !fir.ref<f32>):
%lv = fir.load %lhs : !fir.ref<f32>
%rv = fir.load %rhs : !fir.ref<f32>
%s = arith.addf %lv, %rv : f32
%out = fir.alloca f32
fir.store %s to %out : !fir.ref<f32>
acc.yield %out : !fir.ref<f32>
}
// CHECK-LABEL: Testing : "testBothOutsideReductionDistinctHosts"
// CHECK-DAG: red_a#0 <-> red_b#0: NoAlias
func.func @testBothOutsideReductionDistinctHosts() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%b = fir.alloca f32 {uniq_name = "_QFEb"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%db = fir.declare %b {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ra = acc.reduction varPtr(%da : !fir.ref<f32>) recipe(@red_f32_aa) -> !fir.ref<f32> {name = "a", test.ptr = "red_a"}
%rb = acc.reduction varPtr(%db : !fir.ref<f32>) recipe(@red_f32_aa) -> !fir.ref<f32> {name = "b", test.ptr = "red_b"}
return
}
// CHECK-LABEL: Testing : "testComputeRegionReductionDistinctHostsInsideConvert"
// CHECK-DAG: cr_red_a#0 <-> cr_red_b#0: NoAlias
func.func @testComputeRegionReductionDistinctHostsInsideConvert() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%b = fir.alloca f32 {uniq_name = "_QFEb"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%db = fir.declare %b {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ra = acc.reduction varPtr(%da : !fir.ref<f32>) recipe(@red_f32_aa) -> !fir.ref<f32> {name = "a"}
%rb = acc.reduction varPtr(%db : !fir.ref<f32>) recipe(@red_f32_aa) -> !fir.ref<f32> {name = "b"}
acc.compute_region ins(%arg0 = %ra, %arg1 = %rb) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %arg0 {test.ptr = "cr_red_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %arg1 {test.ptr = "cr_red_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.parallel"}
return
}
// CHECK-LABEL: Testing : "testKernelsReductionDistinctHostsInsideConvert"
// CHECK-DAG: kern_red_a#0 <-> kern_red_b#0: NoAlias
func.func @testKernelsReductionDistinctHostsInsideConvert() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%b = fir.alloca f32 {uniq_name = "_QFEb"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%db = fir.declare %b {uniq_name = "_QFEb"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ra = acc.reduction varPtr(%da : !fir.ref<f32>) recipe(@red_f32_aa) -> !fir.ref<f32> {name = "a"}
%rb = acc.reduction varPtr(%db : !fir.ref<f32>) recipe(@red_f32_aa) -> !fir.ref<f32> {name = "b"}
acc.kernels reduction(%ra, %rb : !fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %ra {test.ptr = "kern_red_a"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %rb {test.ptr = "kern_red_b"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.terminator
}
return
}
// CHECK-LABEL: Testing : "testComputeRegionReductionVsPrivateSameHostNoAlias"
// CHECK-DAG: cr_mix_rd#0 <-> cr_mix_pr3#0: NoAlias
func.func @testComputeRegionReductionVsPrivateSameHostNoAlias() {
%a = fir.alloca f32 {uniq_name = "_QFEa"}
%da = fir.declare %a {uniq_name = "_QFEa"} : (!fir.ref<f32>) -> !fir.ref<f32>
%ra = acc.reduction varPtr(%da : !fir.ref<f32>) recipe(@red_f32_aa) -> !fir.ref<f32> {name = "a"}
%pp = acc.private varPtr(%da : !fir.ref<f32>) -> !fir.ref<f32> {name = "a"}
acc.compute_region ins(%arg0 = %ra, %arg1 = %pp) : (!fir.ref<f32>, !fir.ref<f32>) {
%va = fir.convert %arg0 {test.ptr = "cr_mix_rd"} : (!fir.ref<f32>) -> !fir.ref<f32>
%vb = fir.convert %arg1 {test.ptr = "cr_mix_pr3"} : (!fir.ref<f32>) -> !fir.ref<f32>
acc.yield
} {origin = "acc.kernels"}
return
}
// -----
// Allocas inside acc.parallel.
// CHECK-LABEL: Testing : "testBothInsideParallel"
// CHECK-DAG: par_a#0 <-> par_b#0: NoAlias
func.func @testBothInsideParallel() {
acc.parallel {
%a = fir.alloca f32 {uniq_name = "_QFEa", test.ptr = "par_a"}
%b = fir.alloca f32 {uniq_name = "_QFEb", test.ptr = "par_b"}
acc.yield
}
return
}
// -----
// Allocas inside acc.kernels.
// CHECK-LABEL: Testing : "testBothInsideKernels"
// CHECK-DAG: kern_a#0 <-> kern_b#0: NoAlias
func.func @testBothInsideKernels() {
acc.kernels {
%a = fir.alloca f32 {uniq_name = "_QFEa", test.ptr = "kern_a"}
%b = fir.alloca f32 {uniq_name = "_QFEb", test.ptr = "kern_b"}
acc.terminator
}
return
}
// -----
// Test passing through acc.compute_region boundary inside acc routine.
// The two dummy arguments cannot alias:
// CHECK-LABEL: Testing : "test_acc_routine__0"
// CHECK-DAG: arg_a#0 <-> arg_b#0: NoAlias
func.func @test_acc_routine__0(%arg0: !fir.ref<f32> {fir.bindc_name = "a"}, %arg1: !fir.ref<f32> {fir.bindc_name = "b"}) attributes {acc.specialized_routine = #acc.specialized_routine<@acc_routine_0, <vector>, "test_acc_routine_">, fir.internal_name = "_QPtest_acc_routine"} {
%0 = acc.par_width {par_dim = #acc.par_dim<thread_x>}
acc.compute_region launch(%arg2 = %0) ins(%arg3 = %arg0, %arg4 = %arg1) : (!fir.ref<f32>, !fir.ref<f32>) {
%1 = fir.dummy_scope : !fir.dscope
%2 = fir.declare %arg3 dummy_scope %1 arg 1 {uniq_name = "_QFtest_acc_routineEa", test.ptr = "arg_a"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%3 = fir.declare %arg4 dummy_scope %1 arg 2 {uniq_name = "_QFtest_acc_routineEb", test.ptr = "arg_b"} : (!fir.ref<f32>, !fir.dscope) -> !fir.ref<f32>
%4 = fir.load %3 : !fir.ref<f32>
fir.store %4 to %2 : !fir.ref<f32>
acc.yield
} {origin = "acc.routine"}
return
}
// -----
// Test that a fir.load of a box descriptor through an acc.compute_region
// block argument still resolves to its dummy-argument source. Without the
// pass-through, the recursive getSource() on the memref of the load would
// return SourceKind::Unknown for the block argument, forcing the load itself
// to be classified as SourceKind::Indirect and pessimizing alias analysis
// to MayAlias for two unrelated allocatable dummy arguments.
// CHECK-LABEL: Testing : "test_acc_compute_region_box_load"
// CHECK-DAG: load_x#0 <-> load_y#0: NoAlias
func.func @test_acc_compute_region_box_load(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {fir.bindc_name = "x"}, %arg1: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {fir.bindc_name = "y"}) {
%0 = fir.dummy_scope : !fir.dscope
%dx = fir.declare %arg0 dummy_scope %0 arg 1 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtestEx"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
%dy = fir.declare %arg1 dummy_scope %0 arg 2 {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFtestEy"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.dscope) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
%cx = acc.copyin varPtr(%dx : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {dataClause = #acc<data_clause acc_copy>, implicit = true, name = "x"}
%cy = acc.copyin varPtr(%dy : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>> {dataClause = #acc<data_clause acc_copy>, implicit = true, name = "y"}
acc.kernel_environment dataOperands(%cx, %cy : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
acc.compute_region ins(%arg2 = %cx, %arg3 = %cy) : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) {
%lx = fir.load %arg2 {test.ptr = "load_x"} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
%ly = fir.load %arg3 {test.ptr = "load_y"} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
acc.yield
} {origin = "acc.kernels"}
}
return
}