From cf0e30ae99af8a1ccda4b59d385ac01ae8767a8e Mon Sep 17 00:00:00 2001 From: "Lee, Sang Ik" Date: Fri, 25 Jul 2025 19:51:52 +0000 Subject: [PATCH 1/2] Add XeVM to LLVMIR translation. --- mlir/include/mlir/Target/LLVMIR/Dialect/All.h | 3 + .../Dialect/XeVM/XeVMToLLVMIRTranslation.h | 31 +++++ mlir/lib/Target/LLVMIR/CMakeLists.txt | 1 + mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt | 1 + .../Target/LLVMIR/Dialect/XeVM/CMakeLists.txt | 21 ++++ .../Dialect/XeVM/XeVMToLLVMIRTranslation.cpp | 108 ++++++++++++++++++ mlir/test/Target/LLVMIR/xevm.mlir | 101 ++++++++++++++++ 7 files changed, 266 insertions(+) create mode 100644 mlir/include/mlir/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.h create mode 100644 mlir/lib/Target/LLVMIR/Dialect/XeVM/CMakeLists.txt create mode 100644 mlir/lib/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.cpp create mode 100644 mlir/test/Target/LLVMIR/xevm.mlir diff --git a/mlir/include/mlir/Target/LLVMIR/Dialect/All.h b/mlir/include/mlir/Target/LLVMIR/Dialect/All.h index 60615cf601655..e4670cb1a9622 100644 --- a/mlir/include/mlir/Target/LLVMIR/Dialect/All.h +++ b/mlir/include/mlir/Target/LLVMIR/Dialect/All.h @@ -28,6 +28,7 @@ #include "mlir/Target/LLVMIR/Dialect/ROCDL/ROCDLToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Dialect/SPIRV/SPIRVToLLVMIRTranslation.h" #include "mlir/Target/LLVMIR/Dialect/VCIX/VCIXToLLVMIRTranslation.h" +#include "mlir/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.h" namespace mlir { class DialectRegistry; @@ -47,6 +48,7 @@ static inline void registerAllToLLVMIRTranslations(DialectRegistry ®istry) { registerROCDLDialectTranslation(registry); registerSPIRVDialectTranslation(registry); registerVCIXDialectTranslation(registry); + registerXeVMDialectTranslation(registry); // Extension required for translating GPU offloading Ops. gpu::registerOffloadingLLVMTranslationInterfaceExternalModels(registry); @@ -63,6 +65,7 @@ registerAllGPUToLLVMIRTranslations(DialectRegistry ®istry) { registerNVVMDialectTranslation(registry); registerROCDLDialectTranslation(registry); registerSPIRVDialectTranslation(registry); + registerXeVMDialectTranslation(registry); // Extension required for translating GPU offloading Ops. gpu::registerOffloadingLLVMTranslationInterfaceExternalModels(registry); diff --git a/mlir/include/mlir/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.h b/mlir/include/mlir/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.h new file mode 100644 index 0000000000000..b4f6750718fe8 --- /dev/null +++ b/mlir/include/mlir/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.h @@ -0,0 +1,31 @@ +//===-- XeVMToLLVMIRTranslation.h - XeVM to LLVM IR -------------*- C++ -*-===// +// +// This file is licensed 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 +// +//===----------------------------------------------------------------------===// +// +// This provides registration calls for XeVM dialect to LLVM IR translation. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_TARGET_LLVMIR_DIALECT_XEVM_XEVMTOLLVMIRTRANSLATION_H +#define MLIR_TARGET_LLVMIR_DIALECT_XEVM_XEVMTOLLVMIRTRANSLATION_H + +namespace mlir { + +class DialectRegistry; +class MLIRContext; + +/// Register the XeVM dialect and the translation from it to the LLVM IR in the +/// given registry; +void registerXeVMDialectTranslation(mlir::DialectRegistry ®istry); + +/// Register the XeVM dialect and the translation from it in the registry +/// associated with the given context. +void registerXeVMDialectTranslation(mlir::MLIRContext &context); + +} // namespace mlir + +#endif // MLIR_TARGET_LLVMIR_DIALECT_XEVM_XEVMTOLLVMIRTRANSLATION_H diff --git a/mlir/lib/Target/LLVMIR/CMakeLists.txt b/mlir/lib/Target/LLVMIR/CMakeLists.txt index af22a7ff04bf0..9ea5c6835e8ef 100644 --- a/mlir/lib/Target/LLVMIR/CMakeLists.txt +++ b/mlir/lib/Target/LLVMIR/CMakeLists.txt @@ -60,6 +60,7 @@ add_mlir_translation_library(MLIRToLLVMIRTranslationRegistration MLIRROCDLToLLVMIRTranslation MLIRSPIRVToLLVMIRTranslation MLIRVCIXToLLVMIRTranslation + MLIRXeVMToLLVMIRTranslation ) add_mlir_translation_library(MLIRTargetLLVMIRImport diff --git a/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt index f030fa78942d5..86c731a1074c3 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt +++ b/mlir/lib/Target/LLVMIR/Dialect/CMakeLists.txt @@ -10,3 +10,4 @@ add_subdirectory(OpenMP) add_subdirectory(ROCDL) add_subdirectory(SPIRV) add_subdirectory(VCIX) +add_subdirectory(XeVM) diff --git a/mlir/lib/Target/LLVMIR/Dialect/XeVM/CMakeLists.txt b/mlir/lib/Target/LLVMIR/Dialect/XeVM/CMakeLists.txt new file mode 100644 index 0000000000000..6308d7e2e4404 --- /dev/null +++ b/mlir/lib/Target/LLVMIR/Dialect/XeVM/CMakeLists.txt @@ -0,0 +1,21 @@ +set(LLVM_OPTIONAL_SOURCES + XeVMToLLVMIRTranslation.cpp +) + +add_mlir_translation_library(MLIRXeVMToLLVMIRTranslation + XeVMToLLVMIRTranslation.cpp + + DEPENDS + MLIRXeVMConversionsIncGen + + LINK_COMPONENTS + Core + + LINK_LIBS PUBLIC + MLIRDialectUtils + MLIRIR + MLIRLLVMDialect + MLIRXeVMDialect + MLIRSupport + MLIRTargetLLVMIRExport +) diff --git a/mlir/lib/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.cpp new file mode 100644 index 0000000000000..67ecb53ca4b3b --- /dev/null +++ b/mlir/lib/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.cpp @@ -0,0 +1,108 @@ +//===-- XeVMToLLVMIRTranslation.cpp - Translate XeVM to LLVM IR -*- C++ -*-===// +// +// This file is licensed 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 +// +//===----------------------------------------------------------------------===// +// +// This file implements a translation between the MLIR XeVM dialect and +// LLVM IR. +// +//===----------------------------------------------------------------------===// + +#include "mlir/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.h" +#include "mlir/Dialect/LLVMIR/XeVMDialect.h" +#include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/Operation.h" +#include "mlir/Target/LLVMIR/ModuleTranslation.h" + +#include "llvm/ADT/TypeSwitch.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Metadata.h" + +#include "llvm/IR/ConstantRange.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/Support/raw_ostream.h" + +using namespace mlir; +using namespace mlir::LLVM; + +namespace { +/// Implementation of the dialect interface that converts operations belonging +/// to the XeVM dialect to LLVM IR. +class XeVMDialectLLVMIRTranslationInterface + : public LLVMTranslationDialectInterface { +public: + using LLVMTranslationDialectInterface::LLVMTranslationDialectInterface; + + /// Attaches module-level metadata for functions marked as kernels. + LogicalResult + amendOperation(Operation *op, ArrayRef instructions, + NamedAttribute attribute, + LLVM::ModuleTranslation &moduleTranslation) const final { + StringRef attrName = attribute.getName().getValue(); + if (attrName == mlir::xevm::XeVMDialect::getCacheControlsAttrName()) { + auto cacheControlsArray = dyn_cast(attribute.getValue()); + if (cacheControlsArray.size() != 2) { + return op->emitOpError( + "Expected both L1 and L3 cache control attributes!"); + } + if (instructions.size() != 1) { + return op->emitOpError("Expecting a single instruction"); + } + return handleDecorationCacheControl(instructions.front(), + cacheControlsArray.getValue()); + } + auto func = dyn_cast(op); + if (!func) + return failure(); + + return success(); + } + +private: + template + static llvm::Metadata *getConstantIntMD(llvm::Type *type, IntTy val) { + return llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(type, val)); + } + + static LogicalResult handleDecorationCacheControl(llvm::Instruction *inst, + ArrayRef attrs) { + SmallVector decorations; + llvm::LLVMContext &ctx = inst->getContext(); + llvm::Type *i32Ty = llvm::IntegerType::getInt32Ty(ctx); + llvm::transform( + attrs, std::back_inserter(decorations), + [&ctx, i32Ty](Attribute attr) -> llvm::Metadata * { + auto valuesArray = dyn_cast(attr).getValue(); + std::array metadata; + llvm::transform( + valuesArray, metadata.begin(), [i32Ty](Attribute valueAttr) { + return llvm::ConstantAsMetadata::get(llvm::ConstantInt::get( + i32Ty, cast(valueAttr).getValue())); + }); + return llvm::MDNode::get(ctx, metadata); + }); + constexpr llvm::StringLiteral decorationCacheControlMDName = + "spirv.DecorationCacheControlINTEL"; + inst->setMetadata(decorationCacheControlMDName, + llvm::MDNode::get(ctx, decorations)); + return success(); + } +}; +} // namespace + +void ::mlir::registerXeVMDialectTranslation(::mlir::DialectRegistry ®istry) { + registry.insert(); + registry.addExtension(+[](MLIRContext *ctx, xevm::XeVMDialect *dialect) { + dialect->addInterfaces(); + }); +} + +void ::mlir::registerXeVMDialectTranslation(::mlir::MLIRContext &context) { + DialectRegistry registry; + registerXeVMDialectTranslation(registry); + context.appendDialectRegistry(registry); +} diff --git a/mlir/test/Target/LLVMIR/xevm.mlir b/mlir/test/Target/LLVMIR/xevm.mlir new file mode 100644 index 0000000000000..c71c235233ad5 --- /dev/null +++ b/mlir/test/Target/LLVMIR/xevm.mlir @@ -0,0 +1,101 @@ +// RUN: mlir-translate --split-input-file -mlir-to-llvmir %s | FileCheck %s + +module { + llvm.func spir_funccc @_Z41intel_sub_group_2d_block_read_16b_8r16x1cPU3AS1viiiDv2_iPt(!llvm.ptr<1> {llvm.nonnull, llvm.readonly}, i32, i32, i32, vector<2xi32>, !llvm.ptr {llvm.nonnull, llvm.writeonly}) attributes {no_unwind, will_return} + llvm.func @blockload2d_cache_control(%arg0: !llvm.ptr<1>, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: i32, %arg5: i32) -> vector<8xi16> { + %0 = llvm.mlir.undef : vector<2xi32> + %1 = llvm.mlir.constant(0 : i32) : i32 + %2 = llvm.mlir.constant(1 : i32) : i32 + %3 = llvm.insertelement %arg4, %0[%1 : i32] : vector<2xi32> + %4 = llvm.insertelement %arg5, %3[%2 : i32] : vector<2xi32> + %5 = llvm.mlir.constant(8 : i32) : i32 + %6 = llvm.alloca %5 x i16 : (i32) -> !llvm.ptr + // CHECK-LABEL: call spir_func void @_Z41intel_sub_group_2d_block_read_16b_8r16x1cPU3AS1viiiDv2_iPt + // CHECK-SAME: !spirv.DecorationCacheControlINTEL ![[DECO1:.*]] + llvm.call spir_funccc @_Z41intel_sub_group_2d_block_read_16b_8r16x1cPU3AS1viiiDv2_iPt(%arg0, %arg1, %arg2, %arg3, %4, %6) + {function_type = !llvm.func, i32, i32, i32, vector<2xi32>, ptr)>, linkage = #llvm.linkage, no_unwind, + sym_name = "_Z41intel_sub_group_2d_block_read_16b_8r16x1cPU3AS1viiiDv2_iPt", visibility_ = 0 : i64, will_return, + xevm.DecorationCacheControl = [[6442 : i32, 0 : i32, 1 : i32, 0 : i32], [6442 : i32, 1 : i32, 1 : i32, 0 : i32]]} + : (!llvm.ptr<1> {llvm.nonnull, llvm.readonly}, i32, i32, i32, vector<2xi32>, !llvm.ptr {llvm.nonnull, llvm.writeonly}) -> () + %7 = llvm.load %6 : !llvm.ptr -> vector<8xi16> + llvm.return %7 : vector<8xi16> + } +} + +// CHECK: ![[DECO1]] = !{![[DECO2:.*]], ![[DECO3:.*]]} +// CHECK: ![[DECO2]] = !{i32 6442, i32 0, i32 1, i32 0} +// CHECK: ![[DECO3]] = !{i32 6442, i32 1, i32 1, i32 0} + +// ----- +module { + llvm.func spir_funccc @_Z42intel_sub_group_2d_block_write_32b_8r16x1cPU3AS1viiiDv2_iPj(!llvm.ptr<1> {llvm.nonnull, llvm.writeonly}, i32, i32, i32, vector<2xi32>, !llvm.ptr {llvm.nonnull, llvm.readonly}) attributes {no_unwind, will_return} + llvm.func @blockstore2d_cache_control(%arg0: !llvm.ptr<1>, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: i32, %arg5: i32, %arg6: vector<8xi32>) { + %0 = llvm.mlir.undef : vector<2xi32> + %1 = llvm.mlir.constant(0 : i32) : i32 + %2 = llvm.mlir.constant(1 : i32) : i32 + %3 = llvm.insertelement %arg4, %0[%1 : i32] : vector<2xi32> + %4 = llvm.insertelement %arg5, %3[%2 : i32] : vector<2xi32> + %5 = llvm.mlir.constant(8 : i32) : i32 + %6 = llvm.alloca %5 x i32 : (i32) -> !llvm.ptr + llvm.store %arg6, %6 : vector<8xi32>, !llvm.ptr + // CHECK-LABEL: call spir_func void @_Z42intel_sub_group_2d_block_write_32b_8r16x1cPU3AS1viiiDv2_iPj + // CHECK-SAME: !spirv.DecorationCacheControlINTEL ![[DECO1:.*]] + llvm.call spir_funccc @_Z42intel_sub_group_2d_block_write_32b_8r16x1cPU3AS1viiiDv2_iPj(%arg0, %arg1, %arg2, %arg3, %4, %6) + {function_type = !llvm.func, i32, i32, i32, vector<2xi32>, ptr)>, linkage = #llvm.linkage, no_unwind, + sym_name = "_Z42intel_sub_group_2d_block_write_32b_8r16x1cPU3AS1viiiDv2_iPj", visibility_ = 0 : i64, will_return, + xevm.DecorationCacheControl = [[6443 : i32, 0 : i32, 2 : i32, 0 : i32], [6443 : i32, 1 : i32, 2 : i32, 0 : i32]]} + : (!llvm.ptr<1> {llvm.nonnull, llvm.writeonly}, i32, i32, i32, vector<2xi32>, !llvm.ptr {llvm.nonnull, llvm.readonly}) -> () + llvm.return + } +} + +// CHECK: ![[DECO1]] = !{![[DECO2:.*]], ![[DECO3:.*]]} +// CHECK: ![[DECO2]] = !{i32 6443, i32 0, i32 2, i32 0} +// CHECK: ![[DECO3]] = !{i32 6443, i32 1, i32 2, i32 0} + +// ----- +module { + llvm.func spir_funccc @_Z44intel_sub_group_2d_block_prefetch_8b_8r32x1cPU3AS1viiiDv2_i(!llvm.ptr<1> {llvm.nonnull}, i32, i32, i32, vector<2xi32>) attributes {memory_effects = #llvm.memory_effects, no_unwind} + llvm.func @blockprefetch2d(%arg0: !llvm.ptr<1>, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: i32, %arg5: i32) { + %0 = llvm.mlir.undef : vector<2xi32> + %1 = llvm.mlir.constant(0 : i32) : i32 + %2 = llvm.mlir.constant(1 : i32) : i32 + %3 = llvm.insertelement %arg4, %0[%1 : i32] : vector<2xi32> + %4 = llvm.insertelement %arg5, %3[%2 : i32] : vector<2xi32> + // CHECK-LABEL: call spir_func void @_Z44intel_sub_group_2d_block_prefetch_8b_8r32x1cPU3AS1viiiDv2_i + // CHECK-SAME: !spirv.DecorationCacheControlINTEL ![[DECO1:.*]] + llvm.call spir_funccc @_Z44intel_sub_group_2d_block_prefetch_8b_8r32x1cPU3AS1viiiDv2_i(%arg0, %arg1, %arg2, %arg3, %4) + {function_type = !llvm.func, i32, i32, i32, vector<2xi32>)>, linkage = #llvm.linkage, + memory_effects = #llvm.memory_effects, no_unwind, + sym_name = "_Z44intel_sub_group_2d_block_prefetch_8b_8r32x1cPU3AS1viiiDv2_i", visibility_ = 0 : i64, + xevm.DecorationCacheControl = [[6442 : i32, 0 : i32, 1 : i32, 0 : i32], [6442 : i32, 1 : i32, 1 : i32, 0 : i32]]} + : (!llvm.ptr<1> {llvm.nonnull}, i32, i32, i32, vector<2xi32>) -> () + llvm.return + } +} + +// CHECK: ![[DECO1]] = !{![[DECO2:.*]], ![[DECO3:.*]]} +// CHECK: ![[DECO2]] = !{i32 6442, i32 0, i32 1, i32 0} +// CHECK: ![[DECO3]] = !{i32 6442, i32 1, i32 1, i32 0} + +// ----- +module { + llvm.func spir_funccc @_Z8prefetchPU3AS1Kcm(!llvm.ptr<1>, i64) attributes {memory_effects = #llvm.memory_effects, no_unwind} + llvm.func @prefetch(%arg0: !llvm.ptr<1>) { + %0 = llvm.mlir.constant(1 : i64) : i64 + // CHECK-LABEL: call spir_func void @_Z8prefetchPU3AS1Kcm + // CHECK-SAME: !spirv.DecorationCacheControlINTEL ![[DECO1:.*]] + llvm.call spir_funccc @_Z8prefetchPU3AS1Kcm(%arg0, %0) + {function_type = !llvm.func, i64)>, linkage = #llvm.linkage, + memory_effects = #llvm.memory_effects, + no_unwind, sym_name = "_Z8prefetchPU3AS1Kcm", visibility_ = 0 : i64, + xevm.DecorationCacheControl = [[6442 : i32, 0 : i32, 1 : i32, 0 : i32], [6442 : i32, 1 : i32, 1 : i32, 0 : i32]]} + : (!llvm.ptr<1>, i64) -> () + llvm.return + } +} + +// CHECK: ![[DECO1]] = !{![[DECO2:.*]], ![[DECO3:.*]]} +// CHECK: ![[DECO2]] = !{i32 6442, i32 0, i32 1, i32 0} +// CHECK: ![[DECO3]] = !{i32 6442, i32 1, i32 1, i32 0} + From 07aa2f21b237379b63bce832cfc88259cb1f6d8f Mon Sep 17 00:00:00 2001 From: "Lee, Sang Ik" Date: Mon, 28 Jul 2025 17:08:42 +0000 Subject: [PATCH 2/2] Address reviewer comments. --- .../Dialect/XeVM/XeVMToLLVMIRTranslation.cpp | 9 +- mlir/test/Target/LLVMIR/xevm.mlir | 82 +------------------ 2 files changed, 3 insertions(+), 88 deletions(-) diff --git a/mlir/lib/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.cpp b/mlir/lib/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.cpp index 67ecb53ca4b3b..73b166d045d5b 100644 --- a/mlir/lib/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/Dialect/XeVM/XeVMToLLVMIRTranslation.cpp @@ -63,11 +63,6 @@ class XeVMDialectLLVMIRTranslationInterface } private: - template - static llvm::Metadata *getConstantIntMD(llvm::Type *type, IntTy val) { - return llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(type, val)); - } - static LogicalResult handleDecorationCacheControl(llvm::Instruction *inst, ArrayRef attrs) { SmallVector decorations; @@ -94,14 +89,14 @@ class XeVMDialectLLVMIRTranslationInterface }; } // namespace -void ::mlir::registerXeVMDialectTranslation(::mlir::DialectRegistry ®istry) { +void mlir::registerXeVMDialectTranslation(::mlir::DialectRegistry ®istry) { registry.insert(); registry.addExtension(+[](MLIRContext *ctx, xevm::XeVMDialect *dialect) { dialect->addInterfaces(); }); } -void ::mlir::registerXeVMDialectTranslation(::mlir::MLIRContext &context) { +void mlir::registerXeVMDialectTranslation(::mlir::MLIRContext &context) { DialectRegistry registry; registerXeVMDialectTranslation(registry); context.appendDialectRegistry(registry); diff --git a/mlir/test/Target/LLVMIR/xevm.mlir b/mlir/test/Target/LLVMIR/xevm.mlir index c71c235233ad5..a3dd0b6c17914 100644 --- a/mlir/test/Target/LLVMIR/xevm.mlir +++ b/mlir/test/Target/LLVMIR/xevm.mlir @@ -1,93 +1,13 @@ // RUN: mlir-translate --split-input-file -mlir-to-llvmir %s | FileCheck %s module { - llvm.func spir_funccc @_Z41intel_sub_group_2d_block_read_16b_8r16x1cPU3AS1viiiDv2_iPt(!llvm.ptr<1> {llvm.nonnull, llvm.readonly}, i32, i32, i32, vector<2xi32>, !llvm.ptr {llvm.nonnull, llvm.writeonly}) attributes {no_unwind, will_return} - llvm.func @blockload2d_cache_control(%arg0: !llvm.ptr<1>, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: i32, %arg5: i32) -> vector<8xi16> { - %0 = llvm.mlir.undef : vector<2xi32> - %1 = llvm.mlir.constant(0 : i32) : i32 - %2 = llvm.mlir.constant(1 : i32) : i32 - %3 = llvm.insertelement %arg4, %0[%1 : i32] : vector<2xi32> - %4 = llvm.insertelement %arg5, %3[%2 : i32] : vector<2xi32> - %5 = llvm.mlir.constant(8 : i32) : i32 - %6 = llvm.alloca %5 x i16 : (i32) -> !llvm.ptr - // CHECK-LABEL: call spir_func void @_Z41intel_sub_group_2d_block_read_16b_8r16x1cPU3AS1viiiDv2_iPt - // CHECK-SAME: !spirv.DecorationCacheControlINTEL ![[DECO1:.*]] - llvm.call spir_funccc @_Z41intel_sub_group_2d_block_read_16b_8r16x1cPU3AS1viiiDv2_iPt(%arg0, %arg1, %arg2, %arg3, %4, %6) - {function_type = !llvm.func, i32, i32, i32, vector<2xi32>, ptr)>, linkage = #llvm.linkage, no_unwind, - sym_name = "_Z41intel_sub_group_2d_block_read_16b_8r16x1cPU3AS1viiiDv2_iPt", visibility_ = 0 : i64, will_return, - xevm.DecorationCacheControl = [[6442 : i32, 0 : i32, 1 : i32, 0 : i32], [6442 : i32, 1 : i32, 1 : i32, 0 : i32]]} - : (!llvm.ptr<1> {llvm.nonnull, llvm.readonly}, i32, i32, i32, vector<2xi32>, !llvm.ptr {llvm.nonnull, llvm.writeonly}) -> () - %7 = llvm.load %6 : !llvm.ptr -> vector<8xi16> - llvm.return %7 : vector<8xi16> - } -} - -// CHECK: ![[DECO1]] = !{![[DECO2:.*]], ![[DECO3:.*]]} -// CHECK: ![[DECO2]] = !{i32 6442, i32 0, i32 1, i32 0} -// CHECK: ![[DECO3]] = !{i32 6442, i32 1, i32 1, i32 0} - -// ----- -module { - llvm.func spir_funccc @_Z42intel_sub_group_2d_block_write_32b_8r16x1cPU3AS1viiiDv2_iPj(!llvm.ptr<1> {llvm.nonnull, llvm.writeonly}, i32, i32, i32, vector<2xi32>, !llvm.ptr {llvm.nonnull, llvm.readonly}) attributes {no_unwind, will_return} - llvm.func @blockstore2d_cache_control(%arg0: !llvm.ptr<1>, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: i32, %arg5: i32, %arg6: vector<8xi32>) { - %0 = llvm.mlir.undef : vector<2xi32> - %1 = llvm.mlir.constant(0 : i32) : i32 - %2 = llvm.mlir.constant(1 : i32) : i32 - %3 = llvm.insertelement %arg4, %0[%1 : i32] : vector<2xi32> - %4 = llvm.insertelement %arg5, %3[%2 : i32] : vector<2xi32> - %5 = llvm.mlir.constant(8 : i32) : i32 - %6 = llvm.alloca %5 x i32 : (i32) -> !llvm.ptr - llvm.store %arg6, %6 : vector<8xi32>, !llvm.ptr - // CHECK-LABEL: call spir_func void @_Z42intel_sub_group_2d_block_write_32b_8r16x1cPU3AS1viiiDv2_iPj - // CHECK-SAME: !spirv.DecorationCacheControlINTEL ![[DECO1:.*]] - llvm.call spir_funccc @_Z42intel_sub_group_2d_block_write_32b_8r16x1cPU3AS1viiiDv2_iPj(%arg0, %arg1, %arg2, %arg3, %4, %6) - {function_type = !llvm.func, i32, i32, i32, vector<2xi32>, ptr)>, linkage = #llvm.linkage, no_unwind, - sym_name = "_Z42intel_sub_group_2d_block_write_32b_8r16x1cPU3AS1viiiDv2_iPj", visibility_ = 0 : i64, will_return, - xevm.DecorationCacheControl = [[6443 : i32, 0 : i32, 2 : i32, 0 : i32], [6443 : i32, 1 : i32, 2 : i32, 0 : i32]]} - : (!llvm.ptr<1> {llvm.nonnull, llvm.writeonly}, i32, i32, i32, vector<2xi32>, !llvm.ptr {llvm.nonnull, llvm.readonly}) -> () - llvm.return - } -} - -// CHECK: ![[DECO1]] = !{![[DECO2:.*]], ![[DECO3:.*]]} -// CHECK: ![[DECO2]] = !{i32 6443, i32 0, i32 2, i32 0} -// CHECK: ![[DECO3]] = !{i32 6443, i32 1, i32 2, i32 0} - -// ----- -module { - llvm.func spir_funccc @_Z44intel_sub_group_2d_block_prefetch_8b_8r32x1cPU3AS1viiiDv2_i(!llvm.ptr<1> {llvm.nonnull}, i32, i32, i32, vector<2xi32>) attributes {memory_effects = #llvm.memory_effects, no_unwind} - llvm.func @blockprefetch2d(%arg0: !llvm.ptr<1>, %arg1: i32, %arg2: i32, %arg3: i32, %arg4: i32, %arg5: i32) { - %0 = llvm.mlir.undef : vector<2xi32> - %1 = llvm.mlir.constant(0 : i32) : i32 - %2 = llvm.mlir.constant(1 : i32) : i32 - %3 = llvm.insertelement %arg4, %0[%1 : i32] : vector<2xi32> - %4 = llvm.insertelement %arg5, %3[%2 : i32] : vector<2xi32> - // CHECK-LABEL: call spir_func void @_Z44intel_sub_group_2d_block_prefetch_8b_8r32x1cPU3AS1viiiDv2_i - // CHECK-SAME: !spirv.DecorationCacheControlINTEL ![[DECO1:.*]] - llvm.call spir_funccc @_Z44intel_sub_group_2d_block_prefetch_8b_8r32x1cPU3AS1viiiDv2_i(%arg0, %arg1, %arg2, %arg3, %4) - {function_type = !llvm.func, i32, i32, i32, vector<2xi32>)>, linkage = #llvm.linkage, - memory_effects = #llvm.memory_effects, no_unwind, - sym_name = "_Z44intel_sub_group_2d_block_prefetch_8b_8r32x1cPU3AS1viiiDv2_i", visibility_ = 0 : i64, - xevm.DecorationCacheControl = [[6442 : i32, 0 : i32, 1 : i32, 0 : i32], [6442 : i32, 1 : i32, 1 : i32, 0 : i32]]} - : (!llvm.ptr<1> {llvm.nonnull}, i32, i32, i32, vector<2xi32>) -> () - llvm.return - } -} - -// CHECK: ![[DECO1]] = !{![[DECO2:.*]], ![[DECO3:.*]]} -// CHECK: ![[DECO2]] = !{i32 6442, i32 0, i32 1, i32 0} -// CHECK: ![[DECO3]] = !{i32 6442, i32 1, i32 1, i32 0} - -// ----- -module { - llvm.func spir_funccc @_Z8prefetchPU3AS1Kcm(!llvm.ptr<1>, i64) attributes {memory_effects = #llvm.memory_effects, no_unwind} + llvm.func spir_funccc @_Z8prefetchPU3AS1Kcm(!llvm.ptr<1>, i64) llvm.func @prefetch(%arg0: !llvm.ptr<1>) { %0 = llvm.mlir.constant(1 : i64) : i64 // CHECK-LABEL: call spir_func void @_Z8prefetchPU3AS1Kcm // CHECK-SAME: !spirv.DecorationCacheControlINTEL ![[DECO1:.*]] llvm.call spir_funccc @_Z8prefetchPU3AS1Kcm(%arg0, %0) {function_type = !llvm.func, i64)>, linkage = #llvm.linkage, - memory_effects = #llvm.memory_effects, no_unwind, sym_name = "_Z8prefetchPU3AS1Kcm", visibility_ = 0 : i64, xevm.DecorationCacheControl = [[6442 : i32, 0 : i32, 1 : i32, 0 : i32], [6442 : i32, 1 : i32, 1 : i32, 0 : i32]]} : (!llvm.ptr<1>, i64) -> ()