[Mlir-commits] [mlir] [MLIR][XeGPU] Enable `isa<>` check for uarch (PR #204577)
Artem Kroviakov
llvmlistbot at llvm.org
Thu Jun 25 06:24:37 PDT 2026
================
@@ -0,0 +1,603 @@
+//===--- IntelGpuXe3.h ------------------------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// \file
+// Xe2 uArch definition. Xe3 is the second generation of Intel Xe GPUs.
+// This file defines the uArch details for Xe3 and its derived architectures.
+// This includes Crescent Island Architecture.
+//
+//===----------------------------------------------------------------------===//
+#ifndef MLIR_DIALECT_XEGPU_UARCH_INTELGPUXE3_H
+#define MLIR_DIALECT_XEGPU_UARCH_INTELGPUXE3_H
+
+#include "mlir/Dialect/XeGPU/uArch/uArchBase.h"
+#include "mlir/IR/BuiltinTypes.h"
+#include "mlir/IR/TypeUtilities.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/DebugLog.h"
+#include <map>
+#include <string>
+
+using namespace mlir;
+using namespace mlir::xegpu::uArch;
+
+namespace mlir {
+namespace xegpu {
+namespace uArch {
+
+struct Xe3 : public uArch {
+ Xe3(Kind kind, llvm::ArrayRef<const Instruction *> instructionRegistry,
+ const XeCoreInfo &xeCore)
+ : uArch(kind, instructionRegistry), xeCore(xeCore) {}
+ int getSubgroupSize() const override { return 16; }
+ unsigned getGeneralPackedFormatBitSize() const override { return 32; }
+
+ static bool classof(const uArch *u) {
+ return u->getKind() >= Kind::Xe3_First && u->getKind() <= Kind::Xe3_Last;
+ }
+
+protected:
+ XeCoreInfo xeCore;
+};
+
+//===----------------------------------------------------------------------===//
+// uArch instructions
+//===----------------------------------------------------------------------===//
+struct CriSubgroup2DBlockStoreInstruction : public Instruction {
+ CriSubgroup2DBlockStoreInstruction()
+ : Instruction(InstructionKind::Subgroup2DBlockStore,
+ InstructionScope::Subgroup) {}
+ static bool classof(const Instruction *B) {
+ return B->getInstructionKind() == InstructionKind::Subgroup2DBlockStore;
+ }
+ // Source :
+ // https://registry.khronos.org/OpenCL/extensions/intel/cl_intel_subgroup_2d_block_io.html#_add_a_new_section_5_2_x_cl_intel_subgroup_2d_block_io
+ std::optional<
+ std::tuple<llvm::ArrayRef<int>, llvm::ArrayRef<int>, llvm::ArrayRef<int>>>
+ getBlockWidthHeightCount(Type elemTy) const {
+ const static int kHeight[] = {1, 2, 4, 8};
+ const static int kWidth16[] = {16};
+ const static int kWidth32[] = {16};
+ const static int kCount[] = {1};
+ const int elemByteSize = elemTy.getIntOrFloatBitWidth() / 8;
+ if (elemByteSize == 1)
+ return std::make_tuple(llvm::ArrayRef<int>(kWidth32),
+ llvm::ArrayRef<int>(kHeight),
+ llvm::ArrayRef<int>(kCount));
+ else if (elemByteSize == 2 || elemByteSize == 4)
+ return std::make_tuple(llvm::ArrayRef<int>(kWidth16),
+ llvm::ArrayRef<int>(kHeight),
+ llvm::ArrayRef<int>(kCount));
+ return std::nullopt;
+ }
+
+ int32_t getPackedFormatBitSize() const { return 16; }
+};
+
+struct CriSubgroup2DBlockLoadInstruction : public Instruction {
+ CriSubgroup2DBlockLoadInstruction()
+ : Instruction(InstructionKind::Subgroup2DBlockLoad,
+ InstructionScope::Subgroup) {}
+ static bool classof(const Instruction *B) {
+ return B->getInstructionKind() == InstructionKind::Subgroup2DBlockLoad;
+ }
+
+ // Source :
+ // https://registry.khronos.org/OpenCL/extensions/intel/cl_intel_subgroup_2d_block_io.html#_add_a_new_section_5_2_x_cl_intel_subgroup_2d_block_io
+ std::optional<
+ std::tuple<llvm::ArrayRef<int>, llvm::ArrayRef<int>, llvm::ArrayRef<int>>>
+ getBlockWidthHeightCount(Type elemTy, bool hasTransform, bool hasTranspose,
+ bool upConv = false) const {
+ static const int kHeightAtLeast1[] = {1, 2, 4, 8, 16, 32};
+ static const int kHeightAtLeast8[] = {8, 16, 32};
+ static const int kHeightAtLeast16[] = {16, 32};
+ static const int kHeightAtLeast32[] = {32};
+
+ static const int kWidth32[] = {32};
+ static const int kWidth16[] = {16};
+ static const int kWidth8[] = {8};
+
+ static const int32_t kCount1[] = {1};
+ static const int32_t kCount2[] = {1, 2};
+ static const int32_t kCount4[] = {1, 2, 4};
+ static const int32_t kCount4Only[] = {4};
+ // (elemBytes, transform, transpose, upConvert)
+ using Key = std::tuple<int, uint8_t, uint8_t, uint8_t>;
+ // (widths, heights, counts)
+ using Value = std::tuple<llvm::ArrayRef<int32_t>, llvm::ArrayRef<int32_t>,
+ llvm::ArrayRef<int32_t>>;
+ static const llvm::DenseMap<Key, Value> kMap = {
+ {{1, false, false, false}, {kWidth32, kHeightAtLeast1, kCount2}},
+ {{1, false, false, true}, {kWidth16, kHeightAtLeast8, kCount4Only}},
+ {{2, false, false, false}, {kWidth16, kHeightAtLeast1, kCount2}},
+ {{4, false, false, false}, {kWidth16, kHeightAtLeast1, kCount1}},
+ // Block Loads with Transform:
+ {{1, true, false, false}, {kWidth16, kHeightAtLeast32, kCount4}},
+ {{2, true, false, false}, {kWidth16, kHeightAtLeast16, kCount2}},
+ // Block Loads with Transpose:
+ {{4, false, true, false}, {kWidth8, kHeightAtLeast16, kCount1}},
+ };
----------------
akroviakov wrote:
Fixed, using a unified "spirv" instruction set in `uArchBase` for both xe2 and xe3
https://github.com/llvm/llvm-project/pull/204577
More information about the Mlir-commits
mailing list