[flang-commits] [flang] 898df4b - [flang] Skip opt-bufferization when memory effect does not have an associated value (#140781)
via flang-commits
flang-commits at lists.llvm.org
Thu May 22 06:50:29 PDT 2025
Author: Asher Mancinelli
Date: 2025-05-22T06:50:25-07:00
New Revision: 898df4b8ed86f6590e8496c2108c1611dca710ab
URL: https://github.com/llvm/llvm-project/commit/898df4b8ed86f6590e8496c2108c1611dca710ab
DIFF: https://github.com/llvm/llvm-project/commit/898df4b8ed86f6590e8496c2108c1611dca710ab.diff
LOG: [flang] Skip opt-bufferization when memory effect does not have an associated value (#140781)
Memory effects on the volatile memory resource may not be attached to a
particular source, in which case the value of an effect will be null.
This caused this test case to crash in the optimized bufferization
pass's safety analysis because it assumes it can get the SSA value
modified by the memory effect. This is because memory effects on the
volatile resource indicate that the operation must not be reordered with
respect to other volatile operations, but there is not a material ssa
value that can be pointed to.
This patch changes the safety checks such that memory effects which do
not have associated values are not safe for optimized bufferization.
Added:
flang/test/HLFIR/opt-bufferization-skip-volatile.fir
Modified:
flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
Removed:
################################################################################
diff --git a/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp b/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
index 2f6ee2592a84f..e2ca754a1817a 100644
--- a/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
+++ b/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp
@@ -608,6 +608,12 @@ ElementalAssignBufferization::findMatch(hlfir::ElementalOp elemental) {
return std::nullopt;
}
+ if (effect.getValue() == nullptr) {
+ LLVM_DEBUG(llvm::dbgs()
+ << "side-effect with no value, cannot analyze further\n");
+ return std::nullopt;
+ }
+
// allow if and only if the reads are from the elemental indices, in order
// => each iteration doesn't read values written by other iterations
// don't allow reads from a
diff erent value which may alias: fir alias
diff --git a/flang/test/HLFIR/opt-bufferization-skip-volatile.fir b/flang/test/HLFIR/opt-bufferization-skip-volatile.fir
new file mode 100644
index 0000000000000..158f92bf207d2
--- /dev/null
+++ b/flang/test/HLFIR/opt-bufferization-skip-volatile.fir
@@ -0,0 +1,49 @@
+// RUN: fir-opt --pass-pipeline="builtin.module(func.func(opt-bufferization))" %s | FileCheck %s
+
+// Ensure optimized bufferization preserves the semantics of volatile arrays
+func.func @minimal_volatile_test() {
+ %c1 = arith.constant 1 : index
+ %c200 = arith.constant 200 : index
+
+ // Create a volatile array
+ %1 = fir.address_of(@_QMtestEarray) : !fir.ref<!fir.array<200xf32>>
+ %2 = fir.shape %c200 : (index) -> !fir.shape<1>
+ %3 = fir.volatile_cast %1 : (!fir.ref<!fir.array<200xf32>>) -> !fir.ref<!fir.array<200xf32>, volatile>
+ %4:2 = hlfir.declare %3(%2) {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QMtestEarray"} : (!fir.ref<!fir.array<200xf32>, volatile>, !fir.shape<1>) -> (!fir.ref<!fir.array<200xf32>, volatile>, !fir.ref<!fir.array<200xf32>, volatile>)
+
+ // Create an elemental operation that negates each element
+ %5 = hlfir.elemental %2 unordered : (!fir.shape<1>) -> !hlfir.expr<200xf32> {
+ ^bb0(%arg1: index):
+ %6 = hlfir.designate %4#0 (%arg1) : (!fir.ref<!fir.array<200xf32>, volatile>, index) -> !fir.ref<f32, volatile>
+ %7 = fir.load %6 : !fir.ref<f32, volatile>
+ %8 = arith.negf %7 : f32
+ hlfir.yield_element %8 : f32
+ }
+
+ // Assign the result back to the volatile array
+ hlfir.assign %5 to %4#0 : !hlfir.expr<200xf32>, !fir.ref<!fir.array<200xf32>, volatile>
+ hlfir.destroy %5 : !hlfir.expr<200xf32>
+
+ return
+}
+
+fir.global @_QMtestEarray : !fir.array<200xf32>
+
+// CHECK-LABEL: func.func @minimal_volatile_test() {
+// CHECK: %[[VAL_0:.*]] = arith.constant 200 : index
+// CHECK: %[[VAL_1:.*]] = fir.address_of(@_QMtestEarray) : !fir.ref<!fir.array<200xf32>>
+// CHECK: %[[VAL_2:.*]] = fir.shape %[[VAL_0]] : (index) -> !fir.shape<1>
+// CHECK: %[[VAL_3:.*]] = fir.volatile_cast %[[VAL_1]] : (!fir.ref<!fir.array<200xf32>>) -> !fir.ref<!fir.array<200xf32>, volatile>
+// CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_3]](%[[VAL_2]]) {fortran_attrs = #fir.var_attrs<volatile>, uniq_name = "_QMtestEarray"} : (!fir.ref<!fir.array<200xf32>, volatile>, !fir.shape<1>) -> (!fir.ref<!fir.array<200xf32>, volatile>, !fir.ref<!fir.array<200xf32>, volatile>)
+// CHECK: %[[VAL_5:.*]] = hlfir.elemental %[[VAL_2]] unordered : (!fir.shape<1>) -> !hlfir.expr<200xf32> {
+// CHECK: ^bb0(%[[VAL_6:.*]]: index):
+// CHECK: %[[VAL_7:.*]] = hlfir.designate %[[VAL_4]]#0 (%[[VAL_6]]) : (!fir.ref<!fir.array<200xf32>, volatile>, index) -> !fir.ref<f32, volatile>
+// CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_7]] : !fir.ref<f32, volatile>
+// CHECK: %[[VAL_9:.*]] = arith.negf %[[VAL_8]] : f32
+// CHECK: hlfir.yield_element %[[VAL_9]] : f32
+// CHECK: }
+// CHECK: hlfir.assign %[[VAL_5]] to %[[VAL_4]]#0 : !hlfir.expr<200xf32>, !fir.ref<!fir.array<200xf32>, volatile>
+// CHECK: hlfir.destroy %[[VAL_5]] : !hlfir.expr<200xf32>
+// CHECK: return
+// CHECK: }
+// CHECK: fir.global @_QMtestEarray : !fir.array<200xf32>
More information about the flang-commits
mailing list