[Mlir-commits] [mlir] [mlir][llvm][x86vector] One-to-one intrinsic op interface (PR #140055)
llvmlistbot at llvm.org
llvmlistbot at llvm.org
Thu May 15 06:18:07 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir-vector
Author: Adam Siemieniuk (adam-smnk)
<details>
<summary>Changes</summary>
Adds an LLVMIR op interface that can used by external operations to model LLVM intrinsics. Related 'op to llvm.call_intrinsic' rewriter helper is moved into common LLVM conversion patterns. The x86vector dialect is refactored to use the new common abstraction.
The one-to-one intrinsic op is tied to LLVM intrinsic call semantics. Thus, the op interface, previously defined as a part of x86vector dialect, is moved into the LLVMIR interfaces to allow other low-level dialects to define operations abstracting specific intrinsic semantics while minimizing infrastructure duplication.
Related RFC: https://discourse.llvm.org/t/rfc-simplify-x86-intrinsic-generation/85581
---
Patch is 29.49 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/140055.diff
8 Files Affected:
- (modified) mlir/include/mlir/Conversion/LLVMCommon/Pattern.h (+26)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.h (+4)
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td (+51)
- (modified) mlir/include/mlir/Dialect/X86Vector/X86Vector.td (+92-83)
- (modified) mlir/include/mlir/Dialect/X86Vector/X86VectorInterfaces.td (+5-44)
- (modified) mlir/lib/Conversion/LLVMCommon/Pattern.cpp (+39)
- (modified) mlir/lib/Dialect/LLVMIR/IR/LLVMInterfaces.cpp (+3)
- (modified) mlir/lib/Dialect/X86Vector/Transforms/LegalizeForLLVMExport.cpp (+9-73)
``````````diff
diff --git a/mlir/include/mlir/Conversion/LLVMCommon/Pattern.h b/mlir/include/mlir/Conversion/LLVMCommon/Pattern.h
index 7a58e4fc2f984..ddbac85aa34fd 100644
--- a/mlir/include/mlir/Conversion/LLVMCommon/Pattern.h
+++ b/mlir/include/mlir/Conversion/LLVMCommon/Pattern.h
@@ -30,6 +30,32 @@ LogicalResult oneToOneRewrite(
const LLVMTypeConverter &typeConverter, ConversionPatternRewriter &rewriter,
IntegerOverflowFlags overflowFlags = IntegerOverflowFlags::none);
+/// Replaces the given operation "op" with a call to an LLVM intrinsic with the
+/// specified name "intrinsic" and operands.
+///
+/// The rewrite performs a simple one-to-one matching between the op and LLVM
+/// intrinsic. For example:
+///
+/// ```mlir
+/// %res = intr.op %val : vector<16xf32>
+/// ```
+///
+/// can be converted to
+///
+/// ```mlir
+/// %res = llvm.call_intrinsic "intrinsic"(%val)
+/// ```
+///
+/// The provided operands must be LLVM-compatible.
+///
+/// Upholds a convention that multi-result operations get converted into an
+/// operation returning the LLVM IR structure type, in which case individual
+/// values are first extracted before replacing the original results.
+LogicalResult intrinsicRewrite(Operation *op, StringRef intrinsic,
+ ValueRange operands,
+ const LLVMTypeConverter &typeConverter,
+ RewriterBase &rewriter);
+
} // namespace detail
/// Decomposes a `src` value into a set of values of type `dstType` through
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.h b/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.h
index 05bd32c5d45da..d3e5408b73764 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.h
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.h
@@ -16,6 +16,10 @@
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
namespace mlir {
+
+class LLVMTypeConverter;
+class RewriterBase;
+
namespace LLVM {
namespace detail {
diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td
index 9db019af68b8e..2824f09dab6ce 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMInterfaces.td
@@ -435,6 +435,57 @@ def RoundingModeOpInterface : OpInterface<"RoundingModeOpInterface"> {
];
}
+def OneToOneIntrinsicOpInterface : OpInterface<"OneToOneIntrinsicOpInterface"> {
+ let description = [{
+ An interface for operations modelling LLVM intrinsics suitable for
+ 1-to-1 conversion.
+
+ An op implementing this interface can be directly replaced by a call
+ to a matching intrinsic function.
+ The op must ensure that the combinations of its arguments and results
+ have valid intrinsic counterparts.
+
+ For example, an operation supporting different inputs:
+ ```mlir
+ %res_v8 = intr.op %value_v8 : vector<8xf32>
+ %res_v16 = intr.op %value_v16 : vector<16xf32>
+ ```
+ can be converted to the following intrinsic calls:
+ ```mlir
+ %res_v8 = llvm.call_intrinsic "llvm.x86.op.intr.256"(%value_v8)
+ %res_v16 = llvm.call_intrinsic "llvm.x86.op.intr.512"(%value_v16)
+ ```
+ }];
+
+ let cppNamespace = "::mlir::LLVM";
+
+ let methods = [
+ InterfaceMethod<
+ /*desc=*/[{
+ Returns mangled LLVM intrinsic function name matching the operation
+ variant.
+ }],
+ /*retType=*/"std::string",
+ /*methodName=*/"getIntrinsicName"
+ >,
+ InterfaceMethod<
+ /*desc=*/[{
+ Returns operands for a corresponding LLVM intrinsic.
+
+ Additional operations may be created to facilitate mapping
+ between the source operands and the target intrinsic.
+ }],
+ /*retType=*/"SmallVector<Value>",
+ /*methodName=*/"getIntrinsicOperands",
+ /*args=*/(ins "::mlir::ArrayRef<Value>":$operands,
+ "const ::mlir::LLVMTypeConverter &":$typeConverter,
+ "::mlir::RewriterBase &":$rewriter),
+ /*methodBody=*/"",
+ /*defaultImplementation=*/"return SmallVector<Value>(operands);"
+ >,
+ ];
+}
+
//===----------------------------------------------------------------------===//
// LLVM dialect type interfaces.
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/X86Vector/X86Vector.td b/mlir/include/mlir/Dialect/X86Vector/X86Vector.td
index 25d9c404f0181..66213b0041958 100644
--- a/mlir/include/mlir/Dialect/X86Vector/X86Vector.td
+++ b/mlir/include/mlir/Dialect/X86Vector/X86Vector.td
@@ -40,14 +40,15 @@ class AVX512_Op<string mnemonic, list<Trait> traits = []> :
//----------------------------------------------------------------------------//
def MaskCompressOp : AVX512_Op<"mask.compress", [Pure,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>,
- // TODO: Support optional arguments in `AllTypesMatch`. "type($src)" could
- // then be removed from assemblyFormat.
- AllTypesMatch<["a", "dst"]>,
- TypesMatchWith<"`k` has the same number of bits as elements in `dst`",
- "dst", "k",
- "VectorType::get({::llvm::cast<VectorType>($_self).getShape()[0]}, "
- "IntegerType::get($_self.getContext(), 1))">]> {
+ IntrinsicOpInterface,
+ // TODO: Support optional arguments in `AllTypesMatch`. "type($src)" could
+ // then be removed from assemblyFormat.
+ AllTypesMatch<["a", "dst"]>,
+ TypesMatchWith<"`k` has the same number of bits as elements in `dst`",
+ "dst", "k",
+ "VectorType::get({::llvm::cast<VectorType>($_self).getShape()[0]}, "
+ "IntegerType::get($_self.getContext(), 1))">
+ ]> {
let summary = "Masked compress op";
let description = [{
The mask.compress op is an AVX512 specific op that can lower to the
@@ -75,14 +76,13 @@ def MaskCompressOp : AVX512_Op<"mask.compress", [Pure,
" `:` type($dst) (`,` type($src)^)?";
let hasVerifier = 1;
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
// Call the baseline overloaded intrisic.
// Final overload name mangling is resolved by the created function call.
return "llvm.x86.avx512.mask.compress";
}
- }];
- let extraClassDeclaration = [{
+
SmallVector<Value> getIntrinsicOperands(
::mlir::ArrayRef<Value> operands,
const ::mlir::LLVMTypeConverter &typeConverter,
@@ -95,12 +95,13 @@ def MaskCompressOp : AVX512_Op<"mask.compress", [Pure,
//----------------------------------------------------------------------------//
def MaskRndScaleOp : AVX512_Op<"mask.rndscale", [Pure,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>,
- AllTypesMatch<["src", "a", "dst"]>,
- TypesMatchWith<"imm has the same number of bits as elements in dst",
- "dst", "imm",
- "IntegerType::get($_self.getContext(), "
- "(::llvm::cast<VectorType>($_self).getShape()[0]))">]> {
+ IntrinsicOpInterface,
+ AllTypesMatch<["src", "a", "dst"]>,
+ TypesMatchWith<"imm has the same number of bits as elements in dst",
+ "dst", "imm",
+ "IntegerType::get($_self.getContext(), "
+ "(::llvm::cast<VectorType>($_self).getShape()[0]))">
+ ]> {
let summary = "Masked roundscale op";
let description = [{
The mask.rndscale op is an AVX512 specific op that can lower to the proper
@@ -126,8 +127,8 @@ def MaskRndScaleOp : AVX512_Op<"mask.rndscale", [Pure,
let assemblyFormat =
"$src `,` $k `,` $a `,` $imm `,` $rounding attr-dict `:` type($dst)";
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
std::string intr = "llvm.x86.avx512.mask.rndscale";
VectorType vecType = getSrc().getType();
Type elemType = vecType.getElementType();
@@ -146,12 +147,13 @@ def MaskRndScaleOp : AVX512_Op<"mask.rndscale", [Pure,
//----------------------------------------------------------------------------//
def MaskScaleFOp : AVX512_Op<"mask.scalef", [Pure,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>,
- AllTypesMatch<["src", "a", "b", "dst"]>,
- TypesMatchWith<"k has the same number of bits as elements in dst",
- "dst", "k",
- "IntegerType::get($_self.getContext(), "
- "(::llvm::cast<VectorType>($_self).getShape()[0]))">]> {
+ IntrinsicOpInterface,
+ AllTypesMatch<["src", "a", "b", "dst"]>,
+ TypesMatchWith<"k has the same number of bits as elements in dst",
+ "dst", "k",
+ "IntegerType::get($_self.getContext(), "
+ "(::llvm::cast<VectorType>($_self).getShape()[0]))">
+ ]> {
let summary = "ScaleF op";
let description = [{
The `mask.scalef` op is an AVX512 specific op that can lower to the proper
@@ -178,8 +180,8 @@ def MaskScaleFOp : AVX512_Op<"mask.scalef", [Pure,
let assemblyFormat =
"$src `,` $a `,` $b `,` $k `,` $rounding attr-dict `:` type($dst)";
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
std::string intr = "llvm.x86.avx512.mask.scalef";
VectorType vecType = getSrc().getType();
Type elemType = vecType.getElementType();
@@ -198,18 +200,19 @@ def MaskScaleFOp : AVX512_Op<"mask.scalef", [Pure,
//----------------------------------------------------------------------------//
def Vp2IntersectOp : AVX512_Op<"vp2intersect", [Pure,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>,
- AllTypesMatch<["a", "b"]>,
- TypesMatchWith<"k1 has the same number of bits as elements in a",
- "a", "k1",
- "VectorType::get({::llvm::cast<VectorType>($_self).getShape()[0]}, "
- "IntegerType::get($_self.getContext(), 1))">,
- TypesMatchWith<"k2 has the same number of bits as elements in b",
- // Should use `b` instead of `a`, but that would require
- // adding `type($b)` to assemblyFormat.
- "a", "k2",
- "VectorType::get({::llvm::cast<VectorType>($_self).getShape()[0]}, "
- "IntegerType::get($_self.getContext(), 1))">]> {
+ IntrinsicOpInterface,
+ AllTypesMatch<["a", "b"]>,
+ TypesMatchWith<"k1 has the same number of bits as elements in a",
+ "a", "k1",
+ "VectorType::get({::llvm::cast<VectorType>($_self).getShape()[0]}, "
+ "IntegerType::get($_self.getContext(), 1))">,
+ TypesMatchWith<"k2 has the same number of bits as elements in b",
+ // Should use `b` instead of `a`, but that would require
+ // adding `type($b)` to assemblyFormat.
+ "a", "k2",
+ "VectorType::get({::llvm::cast<VectorType>($_self).getShape()[0]}, "
+ "IntegerType::get($_self.getContext(), 1))">
+ ]> {
let summary = "Vp2Intersect op";
let description = [{
The `vp2intersect` op is an AVX512 specific op that can lower to the proper
@@ -234,8 +237,8 @@ def Vp2IntersectOp : AVX512_Op<"vp2intersect", [Pure,
let assemblyFormat =
"$a `,` $b attr-dict `:` type($a)";
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
std::string intr = "llvm.x86.avx512.vp2intersect";
VectorType vecType = getA().getType();
Type elemType = vecType.getElementType();
@@ -254,13 +257,14 @@ def Vp2IntersectOp : AVX512_Op<"vp2intersect", [Pure,
//----------------------------------------------------------------------------//
def DotBF16Op : AVX512_Op<"dot", [Pure,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>,
- AllTypesMatch<["a", "b"]>,
- AllTypesMatch<["src", "dst"]>,
- TypesMatchWith<"`a` has twice an many elements as `src`",
- "src", "a",
- "VectorType::get({::llvm::cast<VectorType>($_self).getShape()[0] * 2}, "
- "BFloat16Type::get($_self.getContext()))">]> {
+ IntrinsicOpInterface,
+ AllTypesMatch<["a", "b"]>,
+ AllTypesMatch<["src", "dst"]>,
+ TypesMatchWith<"`a` has twice an many elements as `src`",
+ "src", "a",
+ "VectorType::get({::llvm::cast<VectorType>($_self).getShape()[0] * 2}, "
+ "BFloat16Type::get($_self.getContext()))">
+ ]> {
let summary = "Dot BF16 op";
let description = [{
The `dot` op is an AVX512-BF16 specific op that can lower to the proper
@@ -286,8 +290,8 @@ def DotBF16Op : AVX512_Op<"dot", [Pure,
let assemblyFormat =
"$src `,` $a `,` $b attr-dict `:` type($a) `->` type($src)";
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
std::string intr = "llvm.x86.avx512bf16.dpbf16ps";
VectorType vecType = getSrc().getType();
unsigned elemBitWidth = vecType.getElementTypeBitWidth();
@@ -303,8 +307,9 @@ def DotBF16Op : AVX512_Op<"dot", [Pure,
//----------------------------------------------------------------------------//
def CvtPackedF32ToBF16Op : AVX512_Op<"cvt.packed.f32_to_bf16", [Pure,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>,
- AllElementCountsMatch<["a", "dst"]>]> {
+ IntrinsicOpInterface,
+ AllElementCountsMatch<["a", "dst"]>
+ ]> {
let summary = "Convert packed F32 to packed BF16 Data.";
let description = [{
The `convert_f32_to_bf16` op is an AVX512-BF16 specific op that can lower
@@ -326,8 +331,8 @@ def CvtPackedF32ToBF16Op : AVX512_Op<"cvt.packed.f32_to_bf16", [Pure,
let assemblyFormat =
"$a attr-dict `:` type($a) `->` type($dst)";
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
std::string intr = "llvm.x86.avx512bf16.cvtneps2bf16";
VectorType vecType = getA().getType();
unsigned elemBitWidth = vecType.getElementTypeBitWidth();
@@ -357,15 +362,16 @@ class AVX_LowOp<string mnemonic, list<Trait> traits = []> :
//----------------------------------------------------------------------------//
def RsqrtOp : AVX_Op<"rsqrt", [Pure,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>,
- SameOperandsAndResultType]> {
+ IntrinsicOpInterface,
+ SameOperandsAndResultType
+ ]> {
let summary = "Rsqrt";
let arguments = (ins VectorOfLengthAndType<[8], [F32]>:$a);
let results = (outs VectorOfLengthAndType<[8], [F32]>:$b);
let assemblyFormat = "$a attr-dict `:` type($a)";
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
return "llvm.x86.avx.rsqrt.ps.256";
}
}];
@@ -376,8 +382,9 @@ def RsqrtOp : AVX_Op<"rsqrt", [Pure,
//----------------------------------------------------------------------------//
def DotOp : AVX_LowOp<"dot", [Pure,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>,
- SameOperandsAndResultType]> {
+ IntrinsicOpInterface,
+ SameOperandsAndResultType
+ ]> {
let summary = "Dot";
let description = [{
Computes the 4-way dot products of the lower and higher parts of the source
@@ -400,13 +407,12 @@ def DotOp : AVX_LowOp<"dot", [Pure,
let results = (outs VectorOfLengthAndType<[8], [F32]>:$res);
let assemblyFormat = "$a `,` $b attr-dict `:` type($res)";
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
// Only one variant is supported right now - no extra mangling.
return "llvm.x86.avx.dp.ps.256";
}
- }];
- let extraClassDeclaration = [{
+
SmallVector<Value> getIntrinsicOperands(
::mlir::ArrayRef<Value> operands,
const ::mlir::LLVMTypeConverter &typeConverter,
@@ -418,8 +424,11 @@ def DotOp : AVX_LowOp<"dot", [Pure,
// AVX: Convert BF16/F16 to F32 and broadcast into packed F32
//----------------------------------------------------------------------------//
-def BcstToPackedF32Op : AVX_Op<"bcst_to_f32.packed", [MemoryEffects<[MemRead]>,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>]> {
+def BcstToPackedF32Op
+ : AVX_Op<"bcst_to_f32.packed", [
+ MemoryEffects<[MemRead]>,
+ IntrinsicOpInterface
+ ]> {
let summary = "AVX: Broadcasts BF16/F16 into packed F32 Data.";
let description = [{
#### From the Intel Intrinsics Guide:
@@ -440,8 +449,8 @@ def BcstToPackedF32Op : AVX_Op<"bcst_to_f32.packed", [MemoryEffects<[MemRead]>,
let assemblyFormat =
"$a attr-dict`:` type($a)`->` type($dst)";
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
auto elementType =
getA().getType().getElementType();
std::string intr = "llvm.x86.";
@@ -455,9 +464,7 @@ def BcstToPackedF32Op : AVX_Op<"bcst_to_f32.packed", [MemoryEffects<[MemRead]>,
intr += std::to_string(opBitWidth);
return intr;
}
- }];
- let extraClassDeclaration = [{
SmallVector<Value> getIntrinsicOperands(
::mlir::ArrayRef<Value> operands,
const ::mlir::LLVMTypeConverter &typeConverter,
@@ -470,8 +477,11 @@ def BcstToPackedF32Op : AVX_Op<"bcst_to_f32.packed", [MemoryEffects<[MemRead]>,
// AVX: Convert packed BF16/F16 even-indexed/odd-indexed elements into packed F32
//------------------------------------------------------------------------------//
-def CvtPackedEvenIndexedToF32Op : AVX_Op<"cvt.packed.even.indexed_to_f32", [MemoryEffects<[MemRead]>,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>]> {
+def CvtPackedEvenIndexedToF32Op
+ : AVX_Op<"cvt.packed.even.indexed_to_f32", [
+ MemoryEffects<[MemRead]>,
+ IntrinsicOpInterface
+ ]> {
let summary = "AVX: Convert packed BF16/F16 even-indexed elements into packed F32 Data.";
let description = [{
#### From the Intel Intrinsics Guide:
@@ -491,8 +501,8 @@ def CvtPackedEvenIndexedToF32Op : AVX_Op<"cvt.packed.even.indexed_to_f32", [Memo
let assemblyFormat =
"$a attr-dict`:` type($a)`->` type($dst)";
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
auto elementType =
getA().getType().getElementType();
std::string intr = "llvm.x86.";
@@ -506,9 +516,7 @@ def CvtPackedEvenIndexedToF32Op : AVX_Op<"cvt.packed.even.indexed_to_f32", [Memo
intr += std::to_string(opBitWidth);
return intr;
}
- }];
- let extraClassDeclaration = [{
SmallVector<Value> getIntrinsicOperands(
::mlir::ArrayRef<Value> operands,
const ::mlir::LLVMTypeConverter &typeConverter,
@@ -516,8 +524,11 @@ def CvtPackedEvenIndexedToF32Op : AVX_Op<"cvt.packed.even.indexed_to_f32", [Memo
}];
}
-def CvtPackedOddIndexedToF32Op : AVX_Op<"cvt.packed.odd.indexed_to_f32", [MemoryEffects<[MemRead]>,
- DeclareOpInterfaceMethods<OneToOneIntrinsicOpInterface>]> {
+def CvtPackedOddIndexedToF32Op
+ : AVX_Op<"cvt.packed.odd.indexed_to_f32", [
+ MemoryEffects<[MemRead]>,
+ IntrinsicOpInterface
+ ]> {
let summary = "AVX: Convert packed BF16/F16 odd-indexed elements into packed F32 Data.";
let description = [{
#### From the Intel Intrinsics Guide:
@@ -537,8 +548,8 @@ def CvtPackedOddIndexedToF32Op : AVX_Op<"cvt.packed.odd.indexed_to_f32", [Memory
let assemblyFormat =
"$a attr-dict`:` type($a)`->` type($dst)";
- let extraClassDefinition = [{
- std::string $cppClass::getIntrinsicName() {
+ let extraClassDeclaration = [{
+ std::string getIntrinsicName() {
auto elementType =
getA().getType().getElementType();
std::string intr = "llvm.x86.";
@@ -552,9 +563,7 @@ def CvtPackedOddIndexedToF32Op : AVX_Op<"cvt.packed.odd.indexed_to_f32", [Memory
intr += std::to_string(opBitWidth);
return intr;
}
- }];
- let extraClassDeclaration = [{
SmallVector<Value> getInt...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/140055
More information about the Mlir-commits
mailing list