Files
TheRock/compiler/amd-llvm/flang/test/HLFIR/order_assignments/where-equivalent-subscripts.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

144 lines
8.6 KiB
Plaintext

// Test scheduling of WHERE assignments where the LHS and RHS subscript
// indices are loads of the same scalar variable that is declared outside
// the WHERE construct. The two loads have different SSA values (CSE cannot
// merge them across the LHS and RHS regions), but the scheduling analysis
// recognizes them as equivalent values via the ArraySectionAnalyzer
// ValueEquivalenceCallback, so the conflict between the LHS and RHS array
// sections is "aligned" and no temporary needs to be saved for the RHS.
//
// RUN: fir-opt %s --lower-hlfir-ordered-assignments \
// RUN: --debug-only=flang-ordered-assignment \
// RUN: -flang-dbg-order-assignment-schedule-only 2>&1 | FileCheck %s
//
// REQUIRES: asserts
// Positive case: same scalar `i` loaded in the LHS and RHS yield regions of
// the same hlfir.region_assign. The hlfir.declare for `i` is outside the
// hlfir.where, so the analysis can prove that the two fir.load operations
// produce the same value.
func.func @test_same_index(%arg_var: !fir.box<!fir.array<?x?xf32>>,
%arg_i: !fir.ref<i32>,
%arg_mask: !fir.box<!fir.array<?x!fir.logical<4>>>) {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%dscope = fir.dummy_scope : !fir.dscope
%var:2 = hlfir.declare %arg_var dummy_scope %dscope {uniq_name = "_QFtest_same_indexEvar"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?x?xf32>>, !fir.box<!fir.array<?x?xf32>>)
%i:2 = hlfir.declare %arg_i dummy_scope %dscope {uniq_name = "_QFtest_same_indexEi"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
%mask:2 = hlfir.declare %arg_mask dummy_scope %dscope {uniq_name = "_QFtest_same_indexEmask"} : (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.dscope) -> (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.box<!fir.array<?x!fir.logical<4>>>)
hlfir.where {
hlfir.yield %mask#0 : !fir.box<!fir.array<?x!fir.logical<4>>>
} do {
hlfir.region_assign {
%dims:3 = fir.box_dims %var#1, %c0 : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
%shape = fir.shape %dims#1 : (index) -> !fir.shape<1>
%i_val = fir.load %i#0 : !fir.ref<i32>
%i_idx = fir.convert %i_val : (i32) -> i64
%slice = hlfir.designate %var#0 (%c1:%dims#1:%c1, %i_idx) shape %shape : (!fir.box<!fir.array<?x?xf32>>, index, index, index, i64, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
hlfir.yield %slice : !fir.box<!fir.array<?xf32>>
} to {
%dims:3 = fir.box_dims %var#1, %c0 : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
%shape = fir.shape %dims#1 : (index) -> !fir.shape<1>
%i_val = fir.load %i#0 : !fir.ref<i32>
%i_idx = fir.convert %i_val : (i32) -> i64
%slice = hlfir.designate %var#0 (%c1:%dims#1:%c1, %i_idx) shape %shape : (!fir.box<!fir.array<?x?xf32>>, index, index, index, i64, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
hlfir.yield %slice : !fir.box<!fir.array<?xf32>>
}
}
return
}
// CHECK-LABEL: scheduling where in test_same_index ------------
// CHECK: conflict (aligned)
// CHECK: run 1 evaluate: where/region_assign1
// CHECK-NOT: save
// CHECK-NOT: run {{[2-9]}}
// Positive case with an arith expression on the index. The recursion through
// mlir::OperationEquivalence::isEquivalentTo matches the two arith.addi ops
// (one in the LHS region, one in the RHS region), then their %i_val operands
// via the ValueEquivalenceCallback's load-equivalence rule.
func.func @test_same_index_expr(%arg_var: !fir.box<!fir.array<?x?xf32>>,
%arg_i: !fir.ref<i32>,
%arg_mask: !fir.box<!fir.array<?x!fir.logical<4>>>) {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%c1_i32 = arith.constant 1 : i32
%dscope = fir.dummy_scope : !fir.dscope
%var:2 = hlfir.declare %arg_var dummy_scope %dscope {uniq_name = "_QFtest_same_index_exprEvar"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?x?xf32>>, !fir.box<!fir.array<?x?xf32>>)
%i:2 = hlfir.declare %arg_i dummy_scope %dscope {uniq_name = "_QFtest_same_index_exprEi"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
%mask:2 = hlfir.declare %arg_mask dummy_scope %dscope {uniq_name = "_QFtest_same_index_exprEmask"} : (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.dscope) -> (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.box<!fir.array<?x!fir.logical<4>>>)
hlfir.where {
hlfir.yield %mask#0 : !fir.box<!fir.array<?x!fir.logical<4>>>
} do {
hlfir.region_assign {
%dims:3 = fir.box_dims %var#1, %c0 : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
%shape = fir.shape %dims#1 : (index) -> !fir.shape<1>
%i_val = fir.load %i#0 : !fir.ref<i32>
%i_plus = arith.addi %i_val, %c1_i32 : i32
%i_idx = fir.convert %i_plus : (i32) -> i64
%slice = hlfir.designate %var#0 (%c1:%dims#1:%c1, %i_idx) shape %shape : (!fir.box<!fir.array<?x?xf32>>, index, index, index, i64, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
hlfir.yield %slice : !fir.box<!fir.array<?xf32>>
} to {
%dims:3 = fir.box_dims %var#1, %c0 : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
%shape = fir.shape %dims#1 : (index) -> !fir.shape<1>
%i_val = fir.load %i#0 : !fir.ref<i32>
%i_plus = arith.addi %i_val, %c1_i32 : i32
%i_idx = fir.convert %i_plus : (i32) -> i64
%slice = hlfir.designate %var#0 (%c1:%dims#1:%c1, %i_idx) shape %shape : (!fir.box<!fir.array<?x?xf32>>, index, index, index, i64, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
hlfir.yield %slice : !fir.box<!fir.array<?xf32>>
}
}
return
}
// CHECK-LABEL: scheduling where in test_same_index_expr ------------
// CHECK: conflict (aligned)
// CHECK: run 1 evaluate: where/region_assign1
// CHECK-NOT: save
// CHECK-NOT: run {{[2-9]}}
// Negative case: the triplets actually differ between the LHS and the RHS
// (the RHS reads from a shifted lower bound). The ValueEquivalenceCallback
// can match the loads of `i`, but the section triplets are not identical
// (different `lb`), so the analysis still has to fall back to "Unknown"
// overlap, which forces saving the RHS to a temporary. This confirms the
// callback only relaxes equality, never strengthens it.
func.func @test_disjoint_section(%arg_var: !fir.box<!fir.array<?x?xf32>>,
%arg_i: !fir.ref<i32>,
%arg_mask: !fir.box<!fir.array<?x!fir.logical<4>>>) {
%c0 = arith.constant 0 : index
%c1 = arith.constant 1 : index
%c2 = arith.constant 2 : index
%dscope = fir.dummy_scope : !fir.dscope
%var:2 = hlfir.declare %arg_var dummy_scope %dscope {uniq_name = "_QFtest_disjoint_sectionEvar"} : (!fir.box<!fir.array<?x?xf32>>, !fir.dscope) -> (!fir.box<!fir.array<?x?xf32>>, !fir.box<!fir.array<?x?xf32>>)
%i:2 = hlfir.declare %arg_i dummy_scope %dscope {uniq_name = "_QFtest_disjoint_sectionEi"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
%mask:2 = hlfir.declare %arg_mask dummy_scope %dscope {uniq_name = "_QFtest_disjoint_sectionEmask"} : (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.dscope) -> (!fir.box<!fir.array<?x!fir.logical<4>>>, !fir.box<!fir.array<?x!fir.logical<4>>>)
hlfir.where {
hlfir.yield %mask#0 : !fir.box<!fir.array<?x!fir.logical<4>>>
} do {
hlfir.region_assign {
%dims:3 = fir.box_dims %var#1, %c0 : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
%shape = fir.shape %dims#1 : (index) -> !fir.shape<1>
%i_val = fir.load %i#0 : !fir.ref<i32>
%i_idx = fir.convert %i_val : (i32) -> i64
// RHS section: var(2:dims, i) - lower bound differs from LHS.
%slice = hlfir.designate %var#0 (%c2:%dims#1:%c1, %i_idx) shape %shape : (!fir.box<!fir.array<?x?xf32>>, index, index, index, i64, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
hlfir.yield %slice : !fir.box<!fir.array<?xf32>>
} to {
%dims:3 = fir.box_dims %var#1, %c0 : (!fir.box<!fir.array<?x?xf32>>, index) -> (index, index, index)
%shape = fir.shape %dims#1 : (index) -> !fir.shape<1>
%i_val = fir.load %i#0 : !fir.ref<i32>
%i_idx = fir.convert %i_val : (i32) -> i64
// LHS section: var(1:dims, i).
%slice = hlfir.designate %var#0 (%c1:%dims#1:%c1, %i_idx) shape %shape : (!fir.box<!fir.array<?x?xf32>>, index, index, index, i64, !fir.shape<1>) -> !fir.box<!fir.array<?xf32>>
hlfir.yield %slice : !fir.box<!fir.array<?xf32>>
}
}
return
}
// CHECK-LABEL: scheduling where in test_disjoint_section ------------
// CHECK: conflicting arrays:
// CHECK: run {{[0-9]+}} save {{.*}}: where/region_assign1/rhs
// CHECK: run {{[0-9]+}} evaluate: where/region_assign1