[flang] [llvm] [mlir] [MLIR][OpenMP] Lowering nontemporal clause to LLVM IR for SIMD directive (PR #118751)

Kaviya Rajendiran via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 22 06:56:05 PDT 2025


================
@@ -0,0 +1,76 @@
+//===- LowerNontemporal.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Add nontemporal attributes to load and stores of variables marked as
+// nontemporal.
+//
+//===----------------------------------------------------------------------===//
+
+#include "flang/Optimizer/Dialect/FIROpsSupport.h"
+#include "flang/Optimizer/OpenMP/Passes.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
+
+using namespace mlir;
+
+namespace flangomp {
+#define GEN_PASS_DEF_LOWERNONTEMPORALPASS
+#include "flang/Optimizer/OpenMP/Passes.h.inc"
+} // namespace flangomp
+
+namespace {
+class LowerNontemporalPass
+    : public flangomp::impl::LowerNontemporalPassBase<LowerNontemporalPass> {
+  void addNonTemporalAttr(omp::SimdOp simdOp) {
+    if (simdOp.getNontemporalVars().empty())
+      return;
+
+    std::function<mlir::Value(mlir::Value)> getBaseOperand =
+        [&](mlir::Value operand) -> mlir::Value {
+      if (mlir::isa<mlir::BlockArgument>(operand) ||
+          (mlir::isa<fir::AllocaOp>(operand.getDefiningOp())) ||
+          (mlir::isa<fir::DeclareOp>(operand.getDefiningOp())))
+        return operand;
+
+      Operation *definingOp = operand.getDefiningOp();
+      if (definingOp) {
+        for (Value srcOp : definingOp->getOperands()) {
+          return getBaseOperand(srcOp);
+        }
+      }
----------------
kaviya2510 wrote:

I agree, but there are some issues with this approach.
I followed the above suggested method in my previous patch, where I added the `LowerNontemporalPass` after the `LowerWorkshare` pass. This pass did not work as expected when I moved it just above `FIRToLLVM` conversion pass. This is because the defining operations for the source operand of a `fir.load` instruction varies depending on where the pass is inserted in the pipeline.

In the first scenario, the source operand for the load instruction is from `fir.array_coor` whereas in the second scenario it comes from `fircg.ext_array_coor`. Inorder to resolve the issue, I followed this generic way which recursively walks back through operands to determine the base instruction(`fir.alloca`, `fir.declare`). This ensures that future changes in the mlir won’t break the pass.

What is your thoughts on this? 
Is it fine to proceed with the generalized approach or is it be better to explicitly handle each operation type?

https://github.com/llvm/llvm-project/pull/118751


More information about the llvm-commits mailing list