23#include "mlir/Dialect/X86/X86Interfaces.cpp.inc"
25#include "mlir/Dialect/X86/X86Dialect.cpp.inc"
27void x86::X86Dialect::initialize() {
29#define GET_TYPEDEF_LIST
30#include "mlir/Dialect/X86/X86Types.cpp.inc"
35#include "mlir/Dialect/X86/X86.cpp.inc"
43 return memRefDescriptor.
bufferPtr(rewriter, loc, typeConverter, type);
46LogicalResult x86::avx512::MaskCompressOp::verify() {
47 if (getSrc() && getConstantSrc())
48 return emitError(
"cannot use both src and constant_src");
51 return emitError(
"failed to verify that src and dst have same type");
53 if (getConstantSrc() && (getConstantSrc()->
getType() != getDst().
getType()))
55 "failed to verify that constant_src and dst have same type");
64 Adaptor adaptor(operands, *
this);
66 auto opType = adaptor.getA().getType();
68 if (adaptor.getSrc()) {
69 src = adaptor.getSrc();
70 }
else if (adaptor.getConstantSrc()) {
71 src = LLVM::ConstantOp::create(rewriter, loc, opType,
72 adaptor.getConstantSrcAttr());
75 src = LLVM::ConstantOp::create(rewriter, loc, opType, zeroAttr);
88 LLVM::ConstantOp::create(rewriter, getLoc(), rewriter.
getI8Type(), 0xff);
89 intrinsicOperands.push_back(scale);
91 return intrinsicOperands;
97 Adaptor adaptor(operands, *
this);
99 typeConverter, rewriter)};
105 Adaptor adaptor(operands, *
this);
107 typeConverter, rewriter)};
113 Adaptor adaptor(operands, *
this);
115 typeConverter, rewriter)};
120 const unsigned kMaxRows = 16;
121 const unsigned kBitsPerRow = 64 * 8;
122 unsigned col = tp.getDimSize(1) * tp.getElementType().getIntOrFloatBitWidth();
123 if (tp.getDimSize(0) > kMaxRows)
124 return op->
emitOpError(
"bad row height: ") << tp.getDimSize(0);
125 if (col > kBitsPerRow || col & 0x1f)
126 return op->
emitOpError(
"bad column width: ") << (col >> 3);
134 unsigned am = atp.getDimSize(0), ak = atp.getDimSize(1) >> scale;
135 unsigned bk = btp.getDimSize(0), bn = btp.getDimSize(1) >> scale;
136 unsigned cm = ctp.getDimSize(0), cn = ctp.getDimSize(1);
137 if (cm != am || cn != bn || ak != bk)
139 << cm <<
" x " << cn <<
" x " << ak;
149 unsigned width = tType.getElementType().getIntOrFloatBitWidth();
150 assert(llvm::isPowerOf2_64(width) && width >= 8);
151 unsigned bytes = width >> 3;
155 LLVM::ConstantOp::create(rewriter, loc, llvmInt16Type, mattr),
156 LLVM::ConstantOp::create(rewriter, loc, llvmInt16Type, nattr)};
164 unsigned bytes = mType.getElementType().getIntOrFloatBitWidth() / 8;
166 Value scale = LLVM::ConstantOp::create(rewriter, loc, llvmInt64Type, attr);
167 return LLVM::MulOp::create(rewriter, loc, llvmInt64Type, scale, elementStride)
175 assert(mType.getRank() >= 2 &&
"Invalid shape for AMX strides");
176 int64_t preLast = mType.getRank() - 2;
178 unsigned width = mType.getElementType().getIntOrFloatBitWidth();
179 assert(llvm::isPowerOf2_64(width) && width >= 8);
180 unsigned bytes = width >> 3;
181 auto [strides, offset] = mType.getStridesAndOffset();
182 if (strides[preLast] == ShapedType::kDynamic) {
186 loc, mType, memrefDescriptor.
stride(rewriter, loc, preLast), rewriter);
190 return LLVM::ConstantOp::create(rewriter, loc, llvmInt64Type, attr)
194LogicalResult x86::amx::TileZeroOp::verify() {
204template <
typename OpTy,
typename = std::enable_if_t<
205 std::is_same_v<OpTy, x86::amx::TileLoadOp> ||
206 std::is_same_v<OpTy, x86::amx::TileStoreOp>>>
208 MemRefType memrefTy = op.getMemRefType();
209 unsigned rank = memrefTy.getRank();
210 if (op.getIndices().size() != rank)
211 return op.emitOpError(
"requires ") << rank <<
" indices";
217 if (!op.getStride()) {
219 return op.emitOpError(
"requires at least 2D memref");
222 if (failed(memrefTy.getStridesAndOffset(strides, offset)) ||
224 return op.emitOpError(
"requires memref with unit innermost stride");
232 build(builder, state, res, base,
indices,
nullptr);
235LogicalResult x86::amx::TileLoadOp::verify() {
243 Adaptor adaptor(operands, *
this);
246 intrinsicOperands.append(
getTileSizes(loc, getTileType(), rewriter));
247 intrinsicOperands.push_back(
249 adaptor.getBase(), adaptor.getIndices()));
250 if (
Value stride = adaptor.getStride())
251 intrinsicOperands.push_back(
254 intrinsicOperands.push_back(
257 return intrinsicOperands;
262 build(builder, state, base,
indices, val,
nullptr);
265LogicalResult x86::amx::TileStoreOp::verify() {
273 Adaptor adaptor(operands, *
this);
276 intrinsicOperands.append(
getTileSizes(loc, getTileType(), rewriter));
277 intrinsicOperands.push_back(
279 adaptor.getBase(), adaptor.getIndices()));
280 if (
Value stride = adaptor.getStride())
281 intrinsicOperands.push_back(
284 intrinsicOperands.push_back(
286 intrinsicOperands.push_back(adaptor.getVal());
288 return intrinsicOperands;
291LogicalResult x86::amx::TileMulFOp::verify() {
296 if (aType.getElementType().isF8E4M3FN() || aType.getElementType().isF8E5M2())
303 Type ta = aType.getElementType();
304 Type tb = bType.getElementType();
305 Type tc = cType.getElementType();
310 if (flag1 || flag2 || !tc.
isF32())
311 return emitOpError(
"unsupported type combination");
319 Adaptor adaptor(operands, *
this);
327 tsza[1], adaptor.getAcc(),
328 adaptor.getLhs(), adaptor.getRhs()};
330 return intrinsicOperands;
333LogicalResult x86::amx::TileMulIOp::verify() {
342 Type ta = aType.getElementType();
343 Type tb = bType.getElementType();
344 Type tc = cType.getElementType();
346 return emitOpError(
"unsupported type combination");
354 Adaptor adaptor(operands, *
this);
362 tsza[1], adaptor.getAcc(),
363 adaptor.getLhs(), adaptor.getRhs()};
365 return intrinsicOperands;
383 return AMXTileType::getChecked(
388void x86::amx::TileType::print(
AsmPrinter &os)
const {
396#define GET_OP_CLASSES
397#include "mlir/Dialect/X86/X86.cpp.inc"
399#define GET_TYPEDEF_CLASSES
400#include "mlir/Dialect/X86/X86Types.cpp.inc"
false
Parses a map_entries map type from a string format back into its numeric value.
static Type getElementType(Type type, ArrayRef< int32_t > indices, function_ref< InFlightDiagnostic(StringRef)> emitErrorFn)
Walks the given type hierarchy with the given indices, potentially down to component granularity,...
static ArrayRef< int64_t > getShape(Type type)
Returns the shape of the given type.
static Value getMemrefBuffPtr(Location loc, MemRefType type, Value buffer, const LLVMTypeConverter &typeConverter, RewriterBase &rewriter)
static Value inferStride(Location loc, MemRefType mType, Value base, RewriterBase &rewriter)
Maps the 2-dim memref shape to the 64-bit stride.
static Value computeStrideInBytes(Location loc, MemRefType mType, Value elementStride, RewriterBase &rewriter)
Returns stride expressed in number of bytes for the given elementStride stride encoded in number of e...
static LogicalResult tileTransferVerifier(OpTy op)
static LogicalResult verifyMultShape(Operation *op, x86::amx::TileType atp, x86::amx::TileType btp, x86::amx::TileType ctp, unsigned scale)
Verify that AMX supports the multiplication.
static SmallVector< Value > getTileSizes(Location loc, x86::amx::TileType tType, RewriterBase &rewriter)
Maps the 2-dim vector shape to the two 16-bit tile sizes.
static LogicalResult verifyTileSize(Operation *op, x86::amx::TileType tp)
Verify that AMX supports the implied tile shape.
This base class exposes generic asm parser hooks, usable across the various derived parsers.
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
virtual ParseResult parseLess()=0
Parse a '<' token.
virtual ParseResult parseDimensionList(SmallVectorImpl< int64_t > &dimensions, bool allowDynamic=true, bool withTrailingX=true)=0
Parse a dimension list of a tensor or memref type.
virtual SMLoc getNameLoc() const =0
Return the location of the original name token.
virtual ParseResult parseGreater()=0
Parse a '>' token.
virtual ParseResult parseType(Type &result)=0
Parse a type.
This base class exposes generic asm printer hooks, usable across the various derived printers.
virtual void printType(Type type)
void printDimensionList(ArrayRef< int64_t > shape)
IntegerAttr getI16IntegerAttr(int16_t value)
IntegerAttr getI64IntegerAttr(int64_t value)
IntegerType getIntegerType(unsigned width)
TypedAttr getZeroAttr(Type type)
Conversion from types to the LLVM IR dialect.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Helper class to produce LLVM dialect operations extracting or inserting elements of a MemRef descript...
Value bufferPtr(OpBuilder &builder, Location loc, const LLVMTypeConverter &converter, MemRefType type)
Builds IR for getting the start address of the buffer represented by this memref: memref....
Value stride(OpBuilder &builder, Location loc, unsigned pos)
Builds IR extracting the pos-th size from the descriptor.
This class helps build Operations.
Operation is the basic unit of execution within MLIR.
InFlightDiagnostic emitOpError(const Twine &message={})
Emit an error with the op name prefixed, like "'dim' op " which is convenient for verifiers.
This class coordinates the application of a rewrite on a set of IR, providing a way for clients to tr...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
bool isInteger() const
Return true if this is an integer type (with the specified width).
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Value getStridedElementPtr(OpBuilder &builder, Location loc, const LLVMTypeConverter &converter, MemRefType type, Value memRefDesc, ValueRange indices, LLVM::GEPNoWrapFlags noWrapFlags=LLVM::GEPNoWrapFlags::none)
Performs the index computation to get to the element at indices of the memory pointed to by memRefDes...
MemRefType getMemRefType(T &&t)
Convenience method to abbreviate casting getType().
mlir::x86::AMXTileType TileType
Include the generated interface declarations.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
This represents an operation in an abstracted form, suitable for use with the builder APIs.