Files
TheRock/compiler/amd-llvm/flang/test/Transforms/CUF/cuf-kernel-licm.fir
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

148 lines
10 KiB
Plaintext

// RUN: fir-opt -flang-licm --split-input-file %s | FileCheck %s
// Verify that Pure fir.convert operations with !fir.ref operands
// are not hoisted by LICM out of cuf.kernel.
// CHECK-LABEL: func.func @_QPtest(
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<10xf32>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "a"},
// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<!fir.array<10xf32>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "ra"}) {
// CHECK: %[[CONSTANT_0:.*]] = arith.constant 1.000000e+00 : f32
// CHECK: %[[CONSTANT_1:.*]] = arith.constant 1 : index
// CHECK: %[[CONSTANT_2:.*]] = arith.constant 10 : index
// CHECK: %[[ALLOC_0:.*]] = cuf.alloc !fir.box<!fir.ptr<!fir.array<?xf32>>> {data_attr = #cuf.cuda<device>} -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
// CHECK: %[[DUMMY_SCOPE_0:.*]] = fir.dummy_scope : !fir.dscope
// CHECK: %[[SHAPE_0:.*]] = fir.shape %[[CONSTANT_2]] : (index) -> !fir.shape<1>
// CHECK: %[[DECLARE_0:.*]] = fir.declare %[[ARG0]](%[[SHAPE_0]]) dummy_scope %[[DUMMY_SCOPE_0]] arg 1 {data_attr = #cuf.cuda<device>, uniq_name = "_QFtestEa"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<10xf32>>
// CHECK: %[[ALLOCA_0:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtestEi"}
// CHECK: %[[DECLARE_1:.*]] = fir.declare %[[ALLOCA_0]] {uniq_name = "_QFtestEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
// CHECK: %[[ALLOCA_1:.*]] = fir.alloca i64 {bindc_name = "pa", uniq_name = "_QFtestEpa"}
// CHECK: %[[DECLARE_2:.*]] = fir.declare %[[ALLOCA_1]] {fortran_attrs = #fir.var_attrs<cray_pointer>, uniq_name = "_QFtestEpa"} : (!fir.ref<i64>) -> !fir.ref<i64>
// CHECK: %[[DECLARE_3:.*]] = fir.declare %[[ALLOC_0]] {fortran_attrs = #fir.var_attrs<pointer, cray_pointee>, uniq_name = "_QFtestEra"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
// CHECK: %[[ZERO_BITS_0:.*]] = fir.zero_bits !fir.ptr<!fir.array<?xf32>>
// CHECK: %[[EMBOX_0:.*]] = fir.embox %[[ZERO_BITS_0]](%[[SHAPE_0]]) : (!fir.ptr<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
// CHECK: fir.store %[[EMBOX_0]] to %[[DECLARE_3]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
// CHECK: %[[CONVERT_0:.*]] = fir.convert %[[DECLARE_0]] : (!fir.ref<!fir.array<10xf32>>) -> i64
// CHECK: fir.store %[[CONVERT_0]] to %[[DECLARE_2]] : !fir.ref<i64>
// CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
// CHECK: cuf.kernel<<<*, *>>> (%[[VAL_0:.*]] : index) = (%[[CONSTANT_1]] : index) to (%[[CONSTANT_2]] : index) step (%[[CONSTANT_1]] : index) {
// CHECK: %[[CONVERT_1:.*]] = fir.convert %[[VAL_0]] : (index) -> i32
// CHECK: fir.store %[[CONVERT_1]] to %[[DECLARE_1]] : !fir.ref<i32>
// CHECK: %[[CONVERT_2:.*]] = fir.convert %[[DECLARE_2]] : (!fir.ref<i64>) -> !fir.ref<!fir.ptr<i64>>
// CHECK: %[[LOAD_0:.*]] = fir.load %[[CONVERT_2]] : !fir.ref<!fir.ptr<i64>>
// CHECK: %[[CONVERT_3:.*]] = fir.convert %[[DECLARE_3]] : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
// CHECK: %[[CONVERT_4:.*]] = fir.convert %[[LOAD_0]] : (!fir.ptr<i64>) -> !fir.llvm_ptr<i8>
// CHECK: fir.call @_FortranAPointerAssociateScalar(%[[CONVERT_3]], %[[CONVERT_4]]) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.llvm_ptr<i8>) -> ()
// CHECK: %[[LOAD_1:.*]] = fir.load %[[DECLARE_3]] : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
// CHECK: %[[LOAD_2:.*]] = fir.load %[[DECLARE_1]] : !fir.ref<i32>
// CHECK: %[[CONVERT_5:.*]] = fir.convert %[[LOAD_2]] : (i32) -> i64
// CHECK: %[[BOX_DIMS_0:.*]]:3 = fir.box_dims %[[LOAD_1]], %[[CONSTANT_3]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
// CHECK: %[[SHIFT_0:.*]] = fir.shift %[[BOX_DIMS_0]]#0 : (index) -> !fir.shift<1>
// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[LOAD_1]](%[[SHIFT_0]]) %[[CONVERT_5]] : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>, i64) -> !fir.ref<f32>
// CHECK: fir.store %[[CONSTANT_0]] to %[[ARRAY_COOR_0]] : !fir.ref<f32>
// CHECK: "fir.end"() : () -> ()
// CHECK: }
// CHECK: return
// CHECK: }
func.func @_QPtest(%arg0: !fir.ref<!fir.array<10xf32>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "a"}, %arg1: !fir.ref<!fir.array<10xf32>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "ra"}) {
%cst = arith.constant 1.000000e+00 : f32
%c1 = arith.constant 1 : index
%c10 = arith.constant 10 : index
%0 = cuf.alloc !fir.box<!fir.ptr<!fir.array<?xf32>>> {data_attr = #cuf.cuda<device>} -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
%1 = fir.dummy_scope : !fir.dscope
%2 = fir.shape %c10 : (index) -> !fir.shape<1>
%3 = fir.declare %arg0(%2) dummy_scope %1 arg 1 {data_attr = #cuf.cuda<device>, uniq_name = "_QFtestEa"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>, !fir.dscope) -> !fir.ref<!fir.array<10xf32>>
%4 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFtestEi"}
%5 = fir.declare %4 {uniq_name = "_QFtestEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
%6 = fir.alloca i64 {bindc_name = "pa", uniq_name = "_QFtestEpa"}
%7 = fir.declare %6 {fortran_attrs = #fir.var_attrs<cray_pointer>, uniq_name = "_QFtestEpa"} : (!fir.ref<i64>) -> !fir.ref<i64>
%8 = fir.declare %0 {fortran_attrs = #fir.var_attrs<pointer, cray_pointee>, uniq_name = "_QFtestEra"} : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
%9 = fir.zero_bits !fir.ptr<!fir.array<?xf32>>
%10 = fir.embox %9(%2) : (!fir.ptr<!fir.array<?xf32>>, !fir.shape<1>) -> !fir.box<!fir.ptr<!fir.array<?xf32>>>
fir.store %10 to %8 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
%11 = fir.convert %3 : (!fir.ref<!fir.array<10xf32>>) -> i64
fir.store %11 to %7 : !fir.ref<i64>
cuf.kernel<<<*, *>>> (%arg2 : index) = (%c1 : index) to (%c10 : index) step (%c1 : index) {
%12 = fir.convert %arg2 : (index) -> i32
fir.store %12 to %5 : !fir.ref<i32>
%13 = fir.convert %7 : (!fir.ref<i64>) -> !fir.ref<!fir.ptr<i64>>
%14 = fir.load %13 : !fir.ref<!fir.ptr<i64>>
%15 = fir.convert %8 : (!fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>) -> !fir.ref<!fir.box<none>>
%16 = fir.convert %14 : (!fir.ptr<i64>) -> !fir.llvm_ptr<i8>
fir.call @_FortranAPointerAssociateScalar(%15, %16) fastmath<contract> : (!fir.ref<!fir.box<none>>, !fir.llvm_ptr<i8>) -> ()
%17 = fir.load %8 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf32>>>>
%18 = fir.load %5 : !fir.ref<i32>
%19 = fir.convert %18 : (i32) -> i64
%c0 = arith.constant 0 : index
%20:3 = fir.box_dims %17, %c0 : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, index) -> (index, index, index)
%21 = fir.shift %20#0 : (index) -> !fir.shift<1>
%22 = fir.array_coor %17(%21) %19 : (!fir.box<!fir.ptr<!fir.array<?xf32>>>, !fir.shift<1>, i64) -> !fir.ref<f32>
fir.store %cst to %22 : !fir.ref<f32>
"fir.end"() : () -> ()
}
return
}
// -----
// Verify that scf.if containing fir.convert with !fir.ref operand is NOT
// hoisted out of cuf.kernel as a whole. The canMoveOutOf restriction must
// be checked transitively for all nested operations of the candidate,
// not just the candidate itself. fir.convert can convert !fir.ref to i64,
// so scf.if may yield an integer result produced from a !fir.ref.
// CHECK-LABEL: func.func @transitive_canMoveOutOf(
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<10xf32>>
// CHECK-SAME: %[[COND:.*]]: i1)
// CHECK: cuf.kernel
// CHECK: %[[ADDR:.*]] = scf.if %[[COND]] -> (i64)
// CHECK: fir.convert %[[ARG0]]
// CHECK: %[[REF:.*]] = fir.convert %[[ADDR]] : (i64) -> !fir.ref<f32>
// CHECK: fir.store %{{.*}} to %[[REF]]
func.func @transitive_canMoveOutOf(%arg0: !fir.ref<!fir.array<10xf32>> {cuf.data_attr = #cuf.cuda<device>}, %cond: i1) {
%c0_i64 = arith.constant 0 : i64
%c1 = arith.constant 1 : index
%c10 = arith.constant 10 : index
%cst = arith.constant 1.000000e+00 : f32
cuf.kernel<<<*, *>>> (%arg2 : index) = (%c1 : index) to (%c10 : index) step (%c1 : index) {
%addr = scf.if %cond -> (i64) {
%ptr = fir.convert %arg0 : (!fir.ref<!fir.array<10xf32>>) -> i64
scf.yield %ptr : i64
} else {
scf.yield %c0_i64 : i64
}
%ref = fir.convert %addr : (i64) -> !fir.ref<f32>
fir.store %cst to %ref : !fir.ref<f32>
"fir.end"() : () -> ()
}
return
}
// -----
// Verify that Pure fir.address_of operation is not hoisted by LICM
// out of cuf.kernel.
// CHECK-LABEL: func.func @_QQmain() {
// CHECK-NOT: fir.address_of
// CHECK: cuf.kernel
func.func @_QQmain() {
%c100 = arith.constant 100 : index
%c4_i32 = arith.constant 4 : i32
%c6_i32 = arith.constant 6 : i32
%c1 = arith.constant 1 : index
%0 = fir.dummy_scope : !fir.dscope
%1 = cuf.alloc i32 {bindc_name = "a", data_attr = #cuf.cuda<device>, uniq_name = "_QFEa"} -> !fir.ref<i32>
%2 = fir.declare %1 {data_attr = #cuf.cuda<device>, uniq_name = "_QFEa"} : (!fir.ref<i32>) -> !fir.ref<i32>
%3 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"}
%4 = fir.declare %3 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
cuf.kernel<<<*, *>>> (%arg0 : index) = (%c1 : index) to (%c100 : index) step (%c1 : index) {
%5 = fir.convert %arg0 : (index) -> i32
fir.store %5 to %4 : !fir.ref<i32>
%6 = fir.address_of(@_QQclXb12241cc4e2d1775ec743d7d1b7d73f7) : !fir.ref<!fir.char<1,38>>
%7 = fir.convert %6 : (!fir.ref<!fir.char<1,38>>) -> !fir.ref<i8>
%8 = fir.call @_FortranAioBeginExternalListOutput(%c6_i32, %7, %c4_i32) fastmath<contract> : (i32, !fir.ref<i8>, i32) -> !fir.ref<i8>
%9 = fir.load %2 : !fir.ref<i32>
%10 = fir.call @_FortranAioOutputInteger32(%8, %9) fastmath<contract> : (!fir.ref<i8>, i32) -> i1
%11 = fir.call @_FortranAioEndIoStatement(%8) fastmath<contract> : (!fir.ref<i8>) -> i32
"fir.end"() : () -> ()
}
return
}