[flang-commits] [flang] [flang] Extend LICM cheap nested hoisting to scalar loads (PR #217616)
Slava Zakharin via flang-commits
flang-commits at lists.llvm.org
Thu Aug 20 10:31:01 PDT 2026
================
@@ -2689,3 +2689,211 @@ func.func @test_hoist_hlfir_null(%arg0: !fir.ref<i64>) {
}
return
}
+
+// -----
+// Test that a scalar load inside scf.if is hoisted in the default "cheap"
+// nested hoisting mode, along with the fir.convert chain depending on it.
+// CHECK-LABEL: func.func @test_cheap_nested_scalar_load(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<10xf32>>,
+// CHECK-SAME: %[[ARG1:.*]]: !fir.ref<i32>
+// CHECK: %[[DECL:.*]] = fir.declare %[[ARG1]]
+// CHECK: %[[CVT:.*]] = fir.convert %[[ARG0]]
+// CHECK: %[[LOAD:.*]] = fir.load %[[DECL]]
+// CHECK: %[[IDX:.*]] = fir.convert %[[LOAD]] : (i32) -> index
+// CHECK: scf.for
+// CHECK: scf.if
+// CHECK-NOT: fir.load
+// CHECK: memref.store %{{.*}}, %[[CVT]]{{\[}}%[[IDX]]{{\]}}
+func.func @test_cheap_nested_scalar_load(%arg0: !fir.ref<!fir.array<10xf32>>, %arg1: !fir.ref<i32>) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c5 = arith.constant 5 : index
+ %c10 = arith.constant 10 : index
+ %cst = arith.constant 1.000000e+00 : f32
+ %0 = fir.dummy_scope : !fir.dscope
+ %1 = fir.declare %arg1 dummy_scope %0 arg 2 {uniq_name = "_QFtestEn"} : (!fir.ref<i32>, !fir.dscope) -> !fir.ref<i32>
+ scf.for %i = %c0 to %c10 step %c1 {
+ %cond = arith.cmpi slt, %i, %c5 : index
+ scf.if %cond {
+ %cvt = fir.convert %arg0 : (!fir.ref<!fir.array<10xf32>>) -> memref<10xf32>
+ %val = fir.load %1 : !fir.ref<i32>
+ %idx = fir.convert %val : (i32) -> index
+ memref.store %cst, %cvt[%idx] : memref<10xf32>
+ }
+ }
+ return
+}
+
+// -----
+// Test that a load of a global scalar inside scf.if is hoisted in the default
+// "cheap" nested hoisting mode.
+// CHECK-LABEL: func.func @test_cheap_nested_global_scalar_load(
+// CHECK: %[[ADDR:.*]] = fir.address_of(@global_scalar)
+// CHECK: %[[LOAD:.*]] = fir.load %[[ADDR]]
+// CHECK: scf.for
+// CHECK: scf.if
+// CHECK-NOT: fir.load
+// CHECK: fir.store %[[LOAD]]
+fir.global @global_scalar : f32
+
+func.func @test_cheap_nested_global_scalar_load(%arg0: !fir.ref<f32>) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c5 = arith.constant 5 : index
+ %c10 = arith.constant 10 : index
+ scf.for %i = %c0 to %c10 step %c1 {
+ %cond = arith.cmpi slt, %i, %c5 : index
+ scf.if %cond {
+ %addr = fir.address_of(@global_scalar) : !fir.ref<f32>
+ %val = fir.load %addr : !fir.ref<f32>
+ fir.store %val to %arg0 : !fir.ref<f32>
+ }
+ }
+ return
+}
+
+// -----
+// Test that a descriptor load inside scf.if is hoisted in the default "cheap"
+// nested hoisting mode. A descriptor load is a fixed-size copy.
+// CHECK-LABEL: func.func @test_cheap_nested_descriptor_load(
+// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+// CHECK: %[[BOX:.*]] = fir.load %[[ARG0]]
+// CHECK: scf.for
+// CHECK: scf.if
+// CHECK-NOT: fir.load %[[ARG0]]
+func.func @test_cheap_nested_descriptor_load(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>, %arg1: !fir.ref<f32>) {
+ %c0 = arith.constant 0 : index
+ %c1 = arith.constant 1 : index
+ %c5 = arith.constant 5 : index
+ %c10 = arith.constant 10 : index
+ scf.for %i = %c0 to %c10 step %c1 {
+ %cond = arith.cmpi slt, %i, %c5 : index
+ scf.if %cond {
+ %box = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
+ %addr = fir.box_addr %box : (!fir.box<!fir.heap<!fir.array<?xf32>>>) -> !fir.heap<!fir.array<?xf32>>
+ %elt = fir.coordinate_of %addr, %c0 : (!fir.heap<!fir.array<?xf32>>, index) -> !fir.ref<f32>
+ %val = fir.load %elt : !fir.ref<f32>
----------------
vzakhari wrote:
Please add a check that this load is not hoisted.
https://github.com/llvm/llvm-project/pull/217616
More information about the flang-commits
mailing list