[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 05:28:30 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:

```
  omp.simd nontemporal(%3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)private(@_QFsimd_nontemporal_allocatableEi_private_i32 %2 -> %arg2 : !fir.ref<i32>) {
      omp.loop_nest (%arg3) : i32 = (%c1_i32) to (%c100_i32) inclusive step (%c1_i32) {
        %16 = fir.declare %arg2 {uniq_name = "_QFsimd_nontemporal_allocatableEi"} : (!fir.ref<i32>) -> !fir.ref<i32>
        fir.store %arg3 to %16 : !fir.ref<i32>
        %17 = fir.load %3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
        %18 = fir.load %16 : !fir.ref<i32>
        %19 = fir.convert %18 : (i32) -> i64
        %20 = fir.box_addr %17 : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
        %c0_0 = arith.constant 0 : index
        %21:3 = fir.box_dims %17, %c0_0 : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
        %22 = fir.shape_shift %21#0, %21#1 : (index, index) -> !fir.shapeshift<1>
        %23 = fir.array_coor %20(%22) %19 : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>, i64) -> !fir.ref<i32>
        %24 = fir.load %23 : !fir.ref<i32>
        %25 = fir.load %4 : !fir.ref<i32>
        %26 = arith.addi %24, %25 : i32
        %27 = fir.load %3 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
        %28 = fir.load %16 : !fir.ref<i32>
        %29 = fir.convert %28 : (i32) -> i64
        %30 = fir.box_addr %27 : (!fir.box<!fir.heap<!fir.array<?xi32>>>) -> !fir.heap<!fir.array<?xi32>>
        %c0_1 = arith.constant 0 : index
        %31:3 = fir.box_dims %27, %c0_1 : (!fir.box<!fir.heap<!fir.array<?xi32>>>, index) -> (index, index, index)
        %32 = fir.shape_shift %31#0, %31#1 : (index, index) -> !fir.shapeshift<1>
        %33 = fir.array_coor %30(%32) %29 : (!fir.heap<!fir.array<?xi32>>, !fir.shapeshift<1>, i64) -> !fir.ref<i32>
        fir.store %26 to %33 : !fir.ref<i32>
        omp.yield
      }
    }

```
My goal is to trace back and identify the base operand for fir.load or fir.store operation. 
Above mlir, which is an example of an allocatable array,  both `fir.load %24 = fir.load %23 : !fir.ref<i32>` and `fir.store fir.store %26 to %33 : !fir.ref<i32>`  operate on a single memory reference (the first operand), so I focused on recursively analyzing only the first operand of their defining operations to resolve the base. 



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


More information about the llvm-commits mailing list