[Mlir-commits] [mlir] [mlir] Add optimization attrs for gpu-to-llvmspv function declarations (PR #99301)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Jul 23 06:12:33 PDT 2024


https://github.com/FMarno updated https://github.com/llvm/llvm-project/pull/99301

>From d79478a99ba3b59649782d9030385b2cf227ec22 Mon Sep 17 00:00:00 2001
From: Finlay Marno <finlay.marno at codeplay.com>
Date: Tue, 16 Jul 2024 11:15:04 +0100
Subject: [PATCH 1/3] set optimization attrs for gpu-to-llvmspv ops

Adds the attributes include nounwind, willreturn and memory(none).
---
 .../Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp  |  35 ++++--
 .../GPUToLLVMSPV/gpu-to-llvm-spv.mlir         | 104 ++++++++++++++----
 2 files changed, 108 insertions(+), 31 deletions(-)

diff --git a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
index ebeb8f803d71d..81682a52c8c4b 100644
--- a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
+++ b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
@@ -40,11 +40,10 @@ namespace mlir {
 // Helper Functions
 //===----------------------------------------------------------------------===//
 
-static LLVM::LLVMFuncOp lookupOrCreateSPIRVFn(Operation *symbolTable,
-                                              StringRef name,
-                                              ArrayRef<Type> paramTypes,
-                                              Type resultType,
-                                              bool isConvergent = false) {
+static LLVM::LLVMFuncOp
+lookupOrCreateSPIRVFn(Operation *symbolTable, StringRef name,
+                      ArrayRef<Type> paramTypes, Type resultType,
+                      bool hasMemoryEffects = true, bool isConvergent = false) {
   auto func = dyn_cast_or_null<LLVM::LLVMFuncOp>(
       SymbolTable::lookupSymbolIn(symbolTable, name));
   if (!func) {
@@ -53,6 +52,17 @@ static LLVM::LLVMFuncOp lookupOrCreateSPIRVFn(Operation *symbolTable,
         symbolTable->getLoc(), name,
         LLVM::LLVMFunctionType::get(resultType, paramTypes));
     func.setCConv(LLVM::cconv::CConv::SPIR_FUNC);
+    func.setNoUnwind(true);
+    func.setWillReturn(true);
+    if (!hasMemoryEffects) {
+      // no externally observable effects
+      constexpr auto noModRef = mlir::LLVM::ModRefInfo::NoModRef;
+      auto memAttr = b.getAttr<LLVM::MemoryEffectsAttr>(
+          /*other*/ noModRef,
+          /*argMem*/ noModRef, /*inaccessibleMem*/ noModRef);
+      func.setMemoryAttr(memAttr);
+    }
+
     func.setConvergent(isConvergent);
   }
   return func;
@@ -91,8 +101,9 @@ struct GPUBarrierConversion final : ConvertOpToLLVMPattern<gpu::BarrierOp> {
     assert(moduleOp && "Expecting module");
     Type flagTy = rewriter.getI32Type();
     Type voidTy = rewriter.getType<LLVM::LLVMVoidType>();
-    LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(
-        moduleOp, funcName, flagTy, voidTy, /*isConvergent=*/true);
+    LLVM::LLVMFuncOp func =
+        lookupOrCreateSPIRVFn(moduleOp, funcName, flagTy, voidTy,
+                              /*hasMemoryEffects*/ true, /*isConvergent=*/true);
 
     // Value used by SPIR-V backend to represent `CLK_LOCAL_MEM_FENCE`.
     // See `llvm/lib/Target/SPIRV/SPIRVBuiltins.td`.
@@ -134,8 +145,8 @@ struct LaunchConfigConversion : ConvertToLLVMPattern {
     assert(moduleOp && "Expecting module");
     Type dimTy = rewriter.getI32Type();
     Type indexTy = getTypeConverter()->getIndexType();
-    LLVM::LLVMFuncOp func =
-        lookupOrCreateSPIRVFn(moduleOp, funcName, dimTy, indexTy);
+    LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(
+        moduleOp, funcName, dimTy, indexTy, /*hasMemoryEffects*/ false);
 
     Location loc = op->getLoc();
     gpu::Dimension dim = getDimension(op);
@@ -268,9 +279,9 @@ struct GPUShuffleConversion final : ConvertOpToLLVMPattern<gpu::ShuffleOp> {
     Type valueType = adaptor.getValue().getType();
     Type offsetType = adaptor.getOffset().getType();
     Type resultType = valueType;
-    LLVM::LLVMFuncOp func =
-        lookupOrCreateSPIRVFn(moduleOp, funcName, {valueType, offsetType},
-                              resultType, /*isConvergent=*/true);
+    LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(
+        moduleOp, funcName, {valueType, offsetType}, resultType,
+        /*hasMemoryEffects*/ true, /*isConvergent=*/true);
 
     Location loc = op->getLoc();
     std::array<Value, 2> args{adaptor.getValue(), adaptor.getOffset()};
diff --git a/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir b/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
index 1b0f89a9a573e..d094c786414fc 100644
--- a/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
+++ b/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
@@ -4,16 +4,46 @@
 // RUN: | FileCheck --check-prefixes=CHECK-32,CHECK %s
 
 gpu.module @builtins {
-  // CHECK-64:    llvm.func spir_funccc @_Z14get_num_groupsj(i32) -> i64
-  // CHECK-64:    llvm.func spir_funccc @_Z12get_local_idj(i32) -> i64
-  // CHECK-64:    llvm.func spir_funccc @_Z14get_local_sizej(i32) -> i64
-  // CHECK-64:    llvm.func spir_funccc @_Z13get_global_idj(i32) -> i64
-  // CHECK-64:    llvm.func spir_funccc @_Z12get_group_idj(i32) -> i64
-  // CHECK-32:    llvm.func spir_funccc @_Z14get_num_groupsj(i32) -> i32
-  // CHECK-32:    llvm.func spir_funccc @_Z12get_local_idj(i32) -> i32
-  // CHECK-32:    llvm.func spir_funccc @_Z14get_local_sizej(i32) -> i32
-  // CHECK-32:    llvm.func spir_funccc @_Z13get_global_idj(i32) -> i32
-  // CHECK-32:    llvm.func spir_funccc @_Z12get_group_idj(i32) -> i32
+  // CHECK-64:        llvm.func spir_funccc @_Z14get_num_groupsj(i32) -> i64 attributes {
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-64:        llvm.func spir_funccc @_Z12get_local_idj(i32) -> i64 attributes {
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-64:        llvm.func spir_funccc @_Z14get_local_sizej(i32) -> i64 attributes {
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-64:        llvm.func spir_funccc @_Z13get_global_idj(i32) -> i64 attributes {
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-64:        llvm.func spir_funccc @_Z12get_group_idj(i32) -> i64 attributes {
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-32:        llvm.func spir_funccc @_Z14get_num_groupsj(i32) -> i32 attributes {
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-32:        llvm.func spir_funccc @_Z12get_local_idj(i32) -> i32 attributes {
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-32:        llvm.func spir_funccc @_Z14get_local_sizej(i32) -> i32 attributes {
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-32:        llvm.func spir_funccc @_Z13get_global_idj(i32) -> i32 attributes {
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-32:        llvm.func spir_funccc @_Z12get_group_idj(i32) -> i32 attributes {
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
 
   // CHECK-LABEL: gpu_block_id
   func.func @gpu_block_id() -> (index, index, index) {
@@ -104,7 +134,11 @@ gpu.module @builtins {
 // -----
 
 gpu.module @barriers {
-  // CHECK:       llvm.func spir_funccc @_Z7barrierj(i32) attributes {convergent}
+  // CHECK:           llvm.func spir_funccc @_Z7barrierj(i32) attributes {
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  convergent
+  // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-SAME:      }
 
   // CHECK-LABEL: gpu_barrier
   func.func @gpu_barrier() {
@@ -120,10 +154,26 @@ gpu.module @barriers {
 // Check `gpu.shuffle` conversion with default subgroup size.
 
 gpu.module @shuffles {
-  // CHECK:       llvm.func spir_funccc @_Z22sub_group_shuffle_downdj(f64, i32) -> f64 attributes {convergent}
-  // CHECK:       llvm.func spir_funccc @_Z20sub_group_shuffle_upfj(f32, i32) -> f32 attributes {convergent}
-  // CHECK:       llvm.func spir_funccc @_Z21sub_group_shuffle_xorlj(i64, i32) -> i64 attributes {convergent}
-  // CHECK:       llvm.func spir_funccc @_Z17sub_group_shuffleij(i32, i32) -> i32 attributes {convergent}
+  // CHECK:           llvm.func spir_funccc @_Z22sub_group_shuffle_downdj(f64, i32) -> f64 attributes {
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  convergent
+  // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-SAME:      }
+  // CHECK:           llvm.func spir_funccc @_Z20sub_group_shuffle_upfj(f32, i32) -> f32 attributes {
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  convergent
+  // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-SAME:      }
+  // CHECK:           llvm.func spir_funccc @_Z21sub_group_shuffle_xorlj(i64, i32) -> i64 attributes {
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  convergent
+  // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-SAME:      }
+  // CHECK:           llvm.func spir_funccc @_Z17sub_group_shuffleij(i32, i32) -> i32 attributes {
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  convergent
+  // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-SAME:      }
 
   // CHECK-LABEL: gpu_shuffles
   // CHECK-SAME:              (%[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i64, %[[VAL_3:.*]]: i32, %[[VAL_4:.*]]: f32, %[[VAL_5:.*]]: i32, %[[VAL_6:.*]]: f64, %[[VAL_7:.*]]: i32)
@@ -155,10 +205,26 @@ gpu.module @shuffles {
 gpu.module @shuffles attributes {
   spirv.target_env = #spirv.target_env<#spirv.vce<v1.4, [Kernel, Addresses, GroupNonUniformShuffle, Int64], []>, #spirv.resource_limits<subgroup_size = 16>>
 } {
-  // CHECK:       llvm.func spir_funccc @_Z22sub_group_shuffle_downdj(f64, i32) -> f64 attributes {convergent}
-  // CHECK:       llvm.func spir_funccc @_Z20sub_group_shuffle_upfj(f32, i32) -> f32 attributes {convergent}
-  // CHECK:       llvm.func spir_funccc @_Z21sub_group_shuffle_xorlj(i64, i32) -> i64 attributes {convergent}
-  // CHECK:       llvm.func spir_funccc @_Z17sub_group_shuffleij(i32, i32) -> i32 attributes {convergent}
+  // CHECK:           llvm.func spir_funccc @_Z22sub_group_shuffle_downdj(f64, i32) -> f64 attributes {
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  convergent
+  // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-SAME:      }
+  // CHECK:           llvm.func spir_funccc @_Z20sub_group_shuffle_upfj(f32, i32) -> f32 attributes {
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  convergent
+  // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-SAME:      }
+  // CHECK:           llvm.func spir_funccc @_Z21sub_group_shuffle_xorlj(i64, i32) -> i64 attributes {
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  convergent
+  // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-SAME:      }
+  // CHECK:           llvm.func spir_funccc @_Z17sub_group_shuffleij(i32, i32) -> i32 attributes {
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  convergent
+  // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-SAME:      }
 
   // CHECK-LABEL: gpu_shuffles
   // CHECK-SAME:              (%[[VAL_0:.*]]: i32, %[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i64, %[[VAL_3:.*]]: i32, %[[VAL_4:.*]]: f32, %[[VAL_5:.*]]: i32, %[[VAL_6:.*]]: f64, %[[VAL_7:.*]]: i32)

>From 71b3d39b9bcbb3c9e3c946cabd6c24270930d61f Mon Sep 17 00:00:00 2001
From: Finlay Marno <finlay.marno at codeplay.com>
Date: Wed, 17 Jul 2024 15:37:45 +0100
Subject: [PATCH 2/3] amend! refine while attrs applied to which ops

set optimization attrs for gpu-to-llvmspv ops

Adds the attributes include nounwind, willreturn and memory(none).

Co-authored-by: Victor Perez <victor.perez at codeplay.com>
---
 .../Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp  | 22 ++---
 .../GPUToLLVMSPV/gpu-to-llvm-spv.mlir         | 89 ++++++++++++-------
 2 files changed, 71 insertions(+), 40 deletions(-)

diff --git a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
index 81682a52c8c4b..aab5b4a730658 100644
--- a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
+++ b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
@@ -43,7 +43,7 @@ namespace mlir {
 static LLVM::LLVMFuncOp
 lookupOrCreateSPIRVFn(Operation *symbolTable, StringRef name,
                       ArrayRef<Type> paramTypes, Type resultType,
-                      bool hasMemoryEffects = true, bool isConvergent = false) {
+                      bool isMemNone, bool isConvergent, bool isWillReturn) {
   auto func = dyn_cast_or_null<LLVM::LLVMFuncOp>(
       SymbolTable::lookupSymbolIn(symbolTable, name));
   if (!func) {
@@ -53,17 +53,18 @@ lookupOrCreateSPIRVFn(Operation *symbolTable, StringRef name,
         LLVM::LLVMFunctionType::get(resultType, paramTypes));
     func.setCConv(LLVM::cconv::CConv::SPIR_FUNC);
     func.setNoUnwind(true);
-    func.setWillReturn(true);
-    if (!hasMemoryEffects) {
+
+    if (!isMemNone) {
       // no externally observable effects
       constexpr auto noModRef = mlir::LLVM::ModRefInfo::NoModRef;
       auto memAttr = b.getAttr<LLVM::MemoryEffectsAttr>(
-          /*other*/ noModRef,
-          /*argMem*/ noModRef, /*inaccessibleMem*/ noModRef);
+          /*other=*/noModRef,
+          /*argMem=*/noModRef, /*inaccessibleMem=*/noModRef);
       func.setMemoryAttr(memAttr);
     }
 
     func.setConvergent(isConvergent);
+    func.setWillReturn(isWillReturn);
   }
   return func;
 }
@@ -101,9 +102,9 @@ struct GPUBarrierConversion final : ConvertOpToLLVMPattern<gpu::BarrierOp> {
     assert(moduleOp && "Expecting module");
     Type flagTy = rewriter.getI32Type();
     Type voidTy = rewriter.getType<LLVM::LLVMVoidType>();
-    LLVM::LLVMFuncOp func =
-        lookupOrCreateSPIRVFn(moduleOp, funcName, flagTy, voidTy,
-                              /*hasMemoryEffects*/ true, /*isConvergent=*/true);
+    LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(
+        moduleOp, funcName, flagTy, voidTy,
+        /*isMemNone=*/true, /*isConvergent=*/true, /*isWillReturn=*/false);
 
     // Value used by SPIR-V backend to represent `CLK_LOCAL_MEM_FENCE`.
     // See `llvm/lib/Target/SPIRV/SPIRVBuiltins.td`.
@@ -146,7 +147,8 @@ struct LaunchConfigConversion : ConvertToLLVMPattern {
     Type dimTy = rewriter.getI32Type();
     Type indexTy = getTypeConverter()->getIndexType();
     LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(
-        moduleOp, funcName, dimTy, indexTy, /*hasMemoryEffects*/ false);
+        moduleOp, funcName, dimTy, indexTy, /*isMemNone=*/true,
+        /*isConvergent=*/false, /*isWillReturn=*/true);
 
     Location loc = op->getLoc();
     gpu::Dimension dim = getDimension(op);
@@ -281,7 +283,7 @@ struct GPUShuffleConversion final : ConvertOpToLLVMPattern<gpu::ShuffleOp> {
     Type resultType = valueType;
     LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(
         moduleOp, funcName, {valueType, offsetType}, resultType,
-        /*hasMemoryEffects*/ true, /*isConvergent=*/true);
+        /*isMemNone=*/true, /*isConvergent=*/true, /*isWillReturn=*/false);
 
     Location loc = op->getLoc();
     std::array<Value, 2> args{adaptor.getValue(), adaptor.getOffset()};
diff --git a/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir b/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
index d094c786414fc..8ab049253439a 100644
--- a/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
+++ b/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
@@ -5,45 +5,65 @@
 
 gpu.module @builtins {
   // CHECK-64:        llvm.func spir_funccc @_Z14get_num_groupsj(i32) -> i64 attributes {
-  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-SAME-DAG:  no_unwind
-  // CHECK-SAME-DAG:  will_return
+  // CHECK-64-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-64-SAME-DAG:  no_unwind
+  // CHECK-64-SAME-DAG:  will_return
+  // CHECK-64-NOT:       convergent
+  // CHECK-64-SAME:      }
   // CHECK-64:        llvm.func spir_funccc @_Z12get_local_idj(i32) -> i64 attributes {
-  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-SAME-DAG:  no_unwind
-  // CHECK-SAME-DAG:  will_return
+  // CHECK-64-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-64-SAME-DAG:  no_unwind
+  // CHECK-64-SAME-DAG:  will_return
+  // CHECK-64-NOT:       convergent
+  // CHECK-64-SAME:      }
   // CHECK-64:        llvm.func spir_funccc @_Z14get_local_sizej(i32) -> i64 attributes {
-  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-SAME-DAG:  no_unwind
-  // CHECK-SAME-DAG:  will_return
+  // CHECK-64-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-64-SAME-DAG:  no_unwind
+  // CHECK-64-SAME-DAG:  will_return
+  // CHECK-64-NOT:       convergent
+  // CHECK-64-SAME:      }
   // CHECK-64:        llvm.func spir_funccc @_Z13get_global_idj(i32) -> i64 attributes {
-  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-SAME-DAG:  no_unwind
-  // CHECK-SAME-DAG:  will_return
+  // CHECK-64-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-64-SAME-DAG:  no_unwind
+  // CHECK-64-SAME-DAG:  will_return
+  // CHECK-64-NOT:       convergent
+  // CHECK-64-SAME:      }
   // CHECK-64:        llvm.func spir_funccc @_Z12get_group_idj(i32) -> i64 attributes {
-  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-SAME-DAG:  no_unwind
-  // CHECK-SAME-DAG:  will_return
+  // CHECK-64-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-64-SAME-DAG:  no_unwind
+  // CHECK-64-SAME-DAG:  will_return
+  // CHECK-64-NOT:       convergent
+  // CHECK-64-SAME:      }
   // CHECK-32:        llvm.func spir_funccc @_Z14get_num_groupsj(i32) -> i32 attributes {
-  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-SAME-DAG:  no_unwind
-  // CHECK-SAME-DAG:  will_return
+  // CHECK-32-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-32-SAME-DAG:  no_unwind
+  // CHECK-32-SAME-DAG:  will_return
+  // CHECK-32-NOT:       convergent
+  // CHECK-32-SAME:      }
   // CHECK-32:        llvm.func spir_funccc @_Z12get_local_idj(i32) -> i32 attributes {
-  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-SAME-DAG:  no_unwind
-  // CHECK-SAME-DAG:  will_return
+  // CHECK-32-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-32-SAME-DAG:  no_unwind
+  // CHECK-32-SAME-DAG:  will_return
+  // CHECK-32-NOT:       convergent
+  // CHECK-32-SAME:      }
   // CHECK-32:        llvm.func spir_funccc @_Z14get_local_sizej(i32) -> i32 attributes {
-  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-SAME-DAG:  no_unwind
-  // CHECK-SAME-DAG:  will_return
+  // CHECK-32-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-32-SAME-DAG:  no_unwind
+  // CHECK-32-SAME-DAG:  will_return
+  // CHECK-32-NOT:       convergent
+  // CHECK-32-SAME:      }
   // CHECK-32:        llvm.func spir_funccc @_Z13get_global_idj(i32) -> i32 attributes {
-  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-SAME-DAG:  no_unwind
-  // CHECK-SAME-DAG:  will_return
+  // CHECK-32-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-32-SAME-DAG:  no_unwind
+  // CHECK-32-SAME-DAG:  will_return
+  // CHECK-32-NOT:       convergent
+  // CHECK-32-SAME:      }
   // CHECK-32:        llvm.func spir_funccc @_Z12get_group_idj(i32) -> i32 attributes {
-  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-SAME-DAG:  no_unwind
-  // CHECK-SAME-DAG:  will_return
+  // CHECK-32-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-32-SAME-DAG:  no_unwind
+  // CHECK-32-SAME-DAG:  will_return
+  // CHECK-32-NOT:       convergent
+  // CHECK-32-SAME:      }
 
   // CHECK-LABEL: gpu_block_id
   func.func @gpu_block_id() -> (index, index, index) {
@@ -138,6 +158,7 @@ gpu.module @barriers {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
   // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
 
   // CHECK-LABEL: gpu_barrier
@@ -158,21 +179,25 @@ gpu.module @shuffles {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
   // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z20sub_group_shuffle_upfj(f32, i32) -> f32 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
   // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z21sub_group_shuffle_xorlj(i64, i32) -> i64 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
   // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z17sub_group_shuffleij(i32, i32) -> i32 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
   // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
 
   // CHECK-LABEL: gpu_shuffles
@@ -209,21 +234,25 @@ gpu.module @shuffles attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
   // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z20sub_group_shuffle_upfj(f32, i32) -> f32 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
   // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z21sub_group_shuffle_xorlj(i64, i32) -> i64 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
   // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z17sub_group_shuffleij(i32, i32) -> i32 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
   // CHECK-NOT:       memory = #llvm.memory_effects
+  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
 
   // CHECK-LABEL: gpu_shuffles

>From 54d16fee92901c366fb97e772dd9ddf607b66a7b Mon Sep 17 00:00:00 2001
From: Finlay Marno <finlay.marno at codeplay.com>
Date: Thu, 18 Jul 2024 10:22:03 +0100
Subject: [PATCH 3/3] fixup! amend! refine while attrs applied to which ops

---
 .../Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp  |  27 ++---
 .../GPUToLLVMSPV/gpu-to-llvm-spv.mlir         | 101 +++++++-----------
 2 files changed, 52 insertions(+), 76 deletions(-)

diff --git a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
index aab5b4a730658..9a96408465d4c 100644
--- a/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
+++ b/mlir/lib/Conversion/GPUToLLVMSPV/GPUToLLVMSPV.cpp
@@ -40,10 +40,11 @@ namespace mlir {
 // Helper Functions
 //===----------------------------------------------------------------------===//
 
-static LLVM::LLVMFuncOp
-lookupOrCreateSPIRVFn(Operation *symbolTable, StringRef name,
-                      ArrayRef<Type> paramTypes, Type resultType,
-                      bool isMemNone, bool isConvergent, bool isWillReturn) {
+static LLVM::LLVMFuncOp lookupOrCreateSPIRVFn(Operation *symbolTable,
+                                              StringRef name,
+                                              ArrayRef<Type> paramTypes,
+                                              Type resultType, bool isMemNone,
+                                              bool isConvergent) {
   auto func = dyn_cast_or_null<LLVM::LLVMFuncOp>(
       SymbolTable::lookupSymbolIn(symbolTable, name));
   if (!func) {
@@ -53,8 +54,9 @@ lookupOrCreateSPIRVFn(Operation *symbolTable, StringRef name,
         LLVM::LLVMFunctionType::get(resultType, paramTypes));
     func.setCConv(LLVM::cconv::CConv::SPIR_FUNC);
     func.setNoUnwind(true);
+    func.setWillReturn(true);
 
-    if (!isMemNone) {
+    if (isMemNone) {
       // no externally observable effects
       constexpr auto noModRef = mlir::LLVM::ModRefInfo::NoModRef;
       auto memAttr = b.getAttr<LLVM::MemoryEffectsAttr>(
@@ -64,7 +66,6 @@ lookupOrCreateSPIRVFn(Operation *symbolTable, StringRef name,
     }
 
     func.setConvergent(isConvergent);
-    func.setWillReturn(isWillReturn);
   }
   return func;
 }
@@ -102,9 +103,9 @@ struct GPUBarrierConversion final : ConvertOpToLLVMPattern<gpu::BarrierOp> {
     assert(moduleOp && "Expecting module");
     Type flagTy = rewriter.getI32Type();
     Type voidTy = rewriter.getType<LLVM::LLVMVoidType>();
-    LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(
-        moduleOp, funcName, flagTy, voidTy,
-        /*isMemNone=*/true, /*isConvergent=*/true, /*isWillReturn=*/false);
+    LLVM::LLVMFuncOp func =
+        lookupOrCreateSPIRVFn(moduleOp, funcName, flagTy, voidTy,
+                              /*isMemNone=*/false, /*isConvergent=*/true);
 
     // Value used by SPIR-V backend to represent `CLK_LOCAL_MEM_FENCE`.
     // See `llvm/lib/Target/SPIRV/SPIRVBuiltins.td`.
@@ -146,9 +147,9 @@ struct LaunchConfigConversion : ConvertToLLVMPattern {
     assert(moduleOp && "Expecting module");
     Type dimTy = rewriter.getI32Type();
     Type indexTy = getTypeConverter()->getIndexType();
-    LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(
-        moduleOp, funcName, dimTy, indexTy, /*isMemNone=*/true,
-        /*isConvergent=*/false, /*isWillReturn=*/true);
+    LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(moduleOp, funcName, dimTy,
+                                                  indexTy, /*isMemNone=*/true,
+                                                  /*isConvergent=*/false);
 
     Location loc = op->getLoc();
     gpu::Dimension dim = getDimension(op);
@@ -283,7 +284,7 @@ struct GPUShuffleConversion final : ConvertOpToLLVMPattern<gpu::ShuffleOp> {
     Type resultType = valueType;
     LLVM::LLVMFuncOp func = lookupOrCreateSPIRVFn(
         moduleOp, funcName, {valueType, offsetType}, resultType,
-        /*isMemNone=*/true, /*isConvergent=*/true, /*isWillReturn=*/false);
+        /*isMemNone=*/false, /*isConvergent=*/true);
 
     Location loc = op->getLoc();
     std::array<Value, 2> args{adaptor.getValue(), adaptor.getOffset()};
diff --git a/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir b/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
index 8ab049253439a..1a0bf337ad1b6 100644
--- a/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
+++ b/mlir/test/Conversion/GPUToLLVMSPV/gpu-to-llvm-spv.mlir
@@ -5,65 +5,40 @@
 
 gpu.module @builtins {
   // CHECK-64:        llvm.func spir_funccc @_Z14get_num_groupsj(i32) -> i64 attributes {
-  // CHECK-64-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-64-SAME-DAG:  no_unwind
-  // CHECK-64-SAME-DAG:  will_return
-  // CHECK-64-NOT:       convergent
-  // CHECK-64-SAME:      }
-  // CHECK-64:        llvm.func spir_funccc @_Z12get_local_idj(i32) -> i64 attributes {
-  // CHECK-64-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-64-SAME-DAG:  no_unwind
-  // CHECK-64-SAME-DAG:  will_return
-  // CHECK-64-NOT:       convergent
-  // CHECK-64-SAME:      }
-  // CHECK-64:        llvm.func spir_funccc @_Z14get_local_sizej(i32) -> i64 attributes {
-  // CHECK-64-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-64-SAME-DAG:  no_unwind
-  // CHECK-64-SAME-DAG:  will_return
-  // CHECK-64-NOT:       convergent
-  // CHECK-64-SAME:      }
-  // CHECK-64:        llvm.func spir_funccc @_Z13get_global_idj(i32) -> i64 attributes {
-  // CHECK-64-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-64-SAME-DAG:  no_unwind
-  // CHECK-64-SAME-DAG:  will_return
-  // CHECK-64-NOT:       convergent
-  // CHECK-64-SAME:      }
-  // CHECK-64:        llvm.func spir_funccc @_Z12get_group_idj(i32) -> i64 attributes {
-  // CHECK-64-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-64-SAME-DAG:  no_unwind
-  // CHECK-64-SAME-DAG:  will_return
-  // CHECK-64-NOT:       convergent
-  // CHECK-64-SAME:      }
   // CHECK-32:        llvm.func spir_funccc @_Z14get_num_groupsj(i32) -> i32 attributes {
-  // CHECK-32-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-32-SAME-DAG:  no_unwind
-  // CHECK-32-SAME-DAG:  will_return
-  // CHECK-32-NOT:       convergent
-  // CHECK-32-SAME:      }
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-NOT:       convergent
+  // CHECK-SAME:      }
+  // CHECK-64:        llvm.func spir_funccc @_Z12get_local_idj(i32) -> i64 attributes {
   // CHECK-32:        llvm.func spir_funccc @_Z12get_local_idj(i32) -> i32 attributes {
-  // CHECK-32-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-32-SAME-DAG:  no_unwind
-  // CHECK-32-SAME-DAG:  will_return
-  // CHECK-32-NOT:       convergent
-  // CHECK-32-SAME:      }
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-NOT:       convergent
+  // CHECK-SAME:      }
+  // CHECK-64:        llvm.func spir_funccc @_Z14get_local_sizej(i32) -> i64 attributes {
   // CHECK-32:        llvm.func spir_funccc @_Z14get_local_sizej(i32) -> i32 attributes {
-  // CHECK-32-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-32-SAME-DAG:  no_unwind
-  // CHECK-32-SAME-DAG:  will_return
-  // CHECK-32-NOT:       convergent
-  // CHECK-32-SAME:      }
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-NOT:       convergent
+  // CHECK-SAME:      }
+  // CHECK-64:        llvm.func spir_funccc @_Z13get_global_idj(i32) -> i64 attributes {
   // CHECK-32:        llvm.func spir_funccc @_Z13get_global_idj(i32) -> i32 attributes {
-  // CHECK-32-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-32-SAME-DAG:  no_unwind
-  // CHECK-32-SAME-DAG:  will_return
-  // CHECK-32-NOT:       convergent
-  // CHECK-32-SAME:      }
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-NOT:       convergent
+  // CHECK-SAME:      }
+  // CHECK-64:        llvm.func spir_funccc @_Z12get_group_idj(i32) -> i64 attributes {
   // CHECK-32:        llvm.func spir_funccc @_Z12get_group_idj(i32) -> i32 attributes {
-  // CHECK-32-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
-  // CHECK-32-SAME-DAG:  no_unwind
-  // CHECK-32-SAME-DAG:  will_return
-  // CHECK-32-NOT:       convergent
-  // CHECK-32-SAME:      }
+  // CHECK-SAME-DAG:  memory = #llvm.memory_effects<other = none, argMem = none, inaccessibleMem = none>
+  // CHECK-SAME-DAG:  no_unwind
+  // CHECK-SAME-DAG:  will_return
+  // CHECK-NOT:       convergent
+  // CHECK-SAME:      }
 
   // CHECK-LABEL: gpu_block_id
   func.func @gpu_block_id() -> (index, index, index) {
@@ -157,8 +132,8 @@ gpu.module @barriers {
   // CHECK:           llvm.func spir_funccc @_Z7barrierj(i32) attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
+  // CHECK-SAME-DAG:  will_return
   // CHECK-NOT:       memory = #llvm.memory_effects
-  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
 
   // CHECK-LABEL: gpu_barrier
@@ -178,26 +153,26 @@ gpu.module @shuffles {
   // CHECK:           llvm.func spir_funccc @_Z22sub_group_shuffle_downdj(f64, i32) -> f64 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
+  // CHECK-SAME-DAG:  will_return
   // CHECK-NOT:       memory = #llvm.memory_effects
-  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z20sub_group_shuffle_upfj(f32, i32) -> f32 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
+  // CHECK-SAME-DAG:  will_return
   // CHECK-NOT:       memory = #llvm.memory_effects
-  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z21sub_group_shuffle_xorlj(i64, i32) -> i64 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
+  // CHECK-SAME-DAG:  will_return
   // CHECK-NOT:       memory = #llvm.memory_effects
-  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z17sub_group_shuffleij(i32, i32) -> i32 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
+  // CHECK-SAME-DAG:  will_return
   // CHECK-NOT:       memory = #llvm.memory_effects
-  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
 
   // CHECK-LABEL: gpu_shuffles
@@ -233,26 +208,26 @@ gpu.module @shuffles attributes {
   // CHECK:           llvm.func spir_funccc @_Z22sub_group_shuffle_downdj(f64, i32) -> f64 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
+  // CHECK-SAME-DAG:  will_return
   // CHECK-NOT:       memory = #llvm.memory_effects
-  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z20sub_group_shuffle_upfj(f32, i32) -> f32 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
+  // CHECK-SAME-DAG:  will_return
   // CHECK-NOT:       memory = #llvm.memory_effects
-  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z21sub_group_shuffle_xorlj(i64, i32) -> i64 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
+  // CHECK-SAME-DAG:  will_return
   // CHECK-NOT:       memory = #llvm.memory_effects
-  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
   // CHECK:           llvm.func spir_funccc @_Z17sub_group_shuffleij(i32, i32) -> i32 attributes {
   // CHECK-SAME-DAG:  no_unwind
   // CHECK-SAME-DAG:  convergent
+  // CHECK-SAME-DAG:  will_return
   // CHECK-NOT:       memory = #llvm.memory_effects
-  // CHECK-NOT:       will_return
   // CHECK-SAME:      }
 
   // CHECK-LABEL: gpu_shuffles



More information about the Mlir-commits mailing list