Skip to content

Commit 05fcdd5

Browse files
authored
[MLIR][SPIRV-TO-LLVM] Support SPV_INTEL_split_barrier ops (llvm#116648)
Add conversion to LLVM for `SPV_INTEL_split_barrier` operations via conversion to SPIR-V built-ins. Signed-off-by: Victor Perez <victor.perez@codeplay.com>
1 parent 632c5d2 commit 05fcdd5

File tree

2 files changed

+57
-8
lines changed

2 files changed

+57
-8
lines changed

mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,17 +1057,21 @@ static LLVM::CallOp createSPIRVBuiltinCall(Location loc, OpBuilder &builder,
10571057
return call;
10581058
}
10591059

1060-
class ControlBarrierPattern
1061-
: public SPIRVToLLVMConversion<spirv::ControlBarrierOp> {
1060+
template <typename BarrierOpTy>
1061+
class ControlBarrierPattern : public SPIRVToLLVMConversion<BarrierOpTy> {
10621062
public:
1063-
using SPIRVToLLVMConversion<spirv::ControlBarrierOp>::SPIRVToLLVMConversion;
1063+
using OpAdaptor = typename SPIRVToLLVMConversion<BarrierOpTy>::OpAdaptor;
1064+
1065+
using SPIRVToLLVMConversion<BarrierOpTy>::SPIRVToLLVMConversion;
1066+
1067+
static constexpr StringRef getFuncName();
10641068

10651069
LogicalResult
1066-
matchAndRewrite(spirv::ControlBarrierOp controlBarrierOp, OpAdaptor adaptor,
1070+
matchAndRewrite(BarrierOpTy controlBarrierOp, OpAdaptor adaptor,
10671071
ConversionPatternRewriter &rewriter) const override {
1068-
constexpr StringLiteral funcName = "_Z22__spirv_ControlBarrieriii";
1072+
constexpr StringRef funcName = getFuncName();
10691073
Operation *symbolTable =
1070-
controlBarrierOp->getParentWithTrait<OpTrait::SymbolTable>();
1074+
controlBarrierOp->template getParentWithTrait<OpTrait::SymbolTable>();
10711075

10721076
Type i32 = rewriter.getI32Type();
10731077

@@ -1266,6 +1270,24 @@ class GroupReducePattern : public SPIRVToLLVMConversion<ReduceOp> {
12661270
}
12671271
};
12681272

1273+
template <>
1274+
constexpr StringRef
1275+
ControlBarrierPattern<spirv::ControlBarrierOp>::getFuncName() {
1276+
return "_Z22__spirv_ControlBarrieriii";
1277+
}
1278+
1279+
template <>
1280+
constexpr StringRef
1281+
ControlBarrierPattern<spirv::INTELControlBarrierArriveOp>::getFuncName() {
1282+
return "_Z33__spirv_ControlBarrierArriveINTELiii";
1283+
}
1284+
1285+
template <>
1286+
constexpr StringRef
1287+
ControlBarrierPattern<spirv::INTELControlBarrierWaitOp>::getFuncName() {
1288+
return "_Z31__spirv_ControlBarrierWaitINTELiii";
1289+
}
1290+
12691291
/// Converts `spirv.mlir.loop` to LLVM dialect. All blocks within selection
12701292
/// should be reachable for conversion to succeed. The structure of the loop in
12711293
/// LLVM dialect will be the following:
@@ -1899,7 +1921,9 @@ void mlir::populateSPIRVToLLVMConversionPatterns(
18991921
ReturnPattern, ReturnValuePattern,
19001922

19011923
// Barrier ops
1902-
ControlBarrierPattern,
1924+
ControlBarrierPattern<spirv::ControlBarrierOp>,
1925+
ControlBarrierPattern<spirv::INTELControlBarrierArriveOp>,
1926+
ControlBarrierPattern<spirv::INTELControlBarrierWaitOp>,
19031927

19041928
// Group reduction operations
19051929
GroupReducePattern<spirv::GroupIAddOp>,

mlir/test/Conversion/SPIRVToLLVM/barrier-ops-to-llvm.mlir

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s
1+
// RUN: mlir-opt -convert-spirv-to-llvm -split-input-file %s | FileCheck %s
22

33
//===----------------------------------------------------------------------===//
44
// spirv.ControlBarrierOp
@@ -21,3 +21,28 @@ spirv.func @control_barrier() "None" {
2121
spirv.ControlBarrier <Workgroup>, <Workgroup>, <WorkgroupMemory>
2222
spirv.Return
2323
}
24+
25+
// -----
26+
27+
//===----------------------------------------------------------------------===//
28+
// spirv.INTEL.SplitBarrier
29+
//===----------------------------------------------------------------------===//
30+
31+
// CHECK-DAG: llvm.func spir_funccc @_Z33__spirv_ControlBarrierArriveINTELiii(i32, i32, i32) attributes {convergent, no_unwind, will_return}
32+
// CHECK-DAG: llvm.func spir_funccc @_Z31__spirv_ControlBarrierWaitINTELiii(i32, i32, i32) attributes {convergent, no_unwind, will_return}
33+
34+
// CHECK-LABEL: @split_barrier
35+
spirv.func @split_barrier() "None" {
36+
// CHECK: [[EXECUTION:%.*]] = llvm.mlir.constant(2 : i32) : i32
37+
// CHECK: [[MEMORY:%.*]] = llvm.mlir.constant(2 : i32) : i32
38+
// CHECK: [[SEMANTICS:%.*]] = llvm.mlir.constant(768 : i32) : i32
39+
// CHECK: llvm.call spir_funccc @_Z33__spirv_ControlBarrierArriveINTELiii([[EXECUTION]], [[MEMORY]], [[SEMANTICS]]) {convergent, no_unwind, will_return} : (i32, i32, i32) -> ()
40+
spirv.INTEL.ControlBarrierArrive <Workgroup>, <Workgroup>, <CrossWorkgroupMemory|WorkgroupMemory>
41+
42+
// CHECK: [[EXECUTION:%.*]] = llvm.mlir.constant(2 : i32) : i32
43+
// CHECK: [[MEMORY:%.*]] = llvm.mlir.constant(2 : i32) : i32
44+
// CHECK: [[SEMANTICS:%.*]] = llvm.mlir.constant(256 : i32) : i32
45+
// CHECK: llvm.call spir_funccc @_Z31__spirv_ControlBarrierWaitINTELiii([[EXECUTION]], [[MEMORY]], [[SEMANTICS]]) {convergent, no_unwind, will_return} : (i32, i32, i32) -> ()
46+
spirv.INTEL.ControlBarrierWait <Workgroup>, <Workgroup>, <WorkgroupMemory>
47+
spirv.Return
48+
}

0 commit comments

Comments
 (0)