Skip to content

[mlir][vector] Create VectorToLLVMDialectInterface #121440

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 5, 2025

Conversation

Hardcode84
Copy link
Contributor

Create VectorToLLVMDialectInterface which allows automatic conversion discovery by generic --convert-to-llvm pass. This only covers final dialect conversion step and not any previous preparation steps. Also, currently there is no way to pass any additional parameters through this conversion interface, but most users using default parameters anyway.

@llvmbot
Copy link
Member

llvmbot commented Jan 1, 2025

@llvm/pr-subscribers-mlir-vector

@llvm/pr-subscribers-mlir

Author: Ivan Butygin (Hardcode84)

Changes

Create VectorToLLVMDialectInterface which allows automatic conversion discovery by generic --convert-to-llvm pass. This only covers final dialect conversion step and not any previous preparation steps. Also, currently there is no way to pass any additional parameters through this conversion interface, but most users using default parameters anyway.


Full diff: https://github.com/llvm/llvm-project/pull/121440.diff

5 Files Affected:

  • (modified) mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h (+3)
  • (modified) mlir/include/mlir/InitAllExtensions.h (+2)
  • (modified) mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp (+25)
  • (modified) mlir/lib/Dialect/Vector/IR/VectorOps.cpp (+2)
  • (added) mlir/test/Conversion/VectorToLLVM/vector-to-llvm-interface.mlir (+14)
diff --git a/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h b/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
index 5fda62e3584c79..1e29bfeb9c3921 100644
--- a/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
+++ b/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
@@ -24,6 +24,9 @@ void populateVectorToLLVMConversionPatterns(
     const LLVMTypeConverter &converter, RewritePatternSet &patterns,
     bool reassociateFPReductions = false, bool force32BitVectorIndices = false);
 
+namespace vector {
+void registerConvertVectorToLLVMInterface(DialectRegistry &registry);
+}
 } // namespace mlir
 
 #endif // MLIR_CONVERSION_VECTORTOLLVM_CONVERTVECTORTOLLVM_H_
diff --git a/mlir/include/mlir/InitAllExtensions.h b/mlir/include/mlir/InitAllExtensions.h
index 14a6a2787b3a5d..887db344ed88b6 100644
--- a/mlir/include/mlir/InitAllExtensions.h
+++ b/mlir/include/mlir/InitAllExtensions.h
@@ -26,6 +26,7 @@
 #include "mlir/Conversion/NVVMToLLVM/NVVMToLLVM.h"
 #include "mlir/Conversion/OpenMPToLLVM/ConvertOpenMPToLLVM.h"
 #include "mlir/Conversion/UBToLLVM/UBToLLVM.h"
+#include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h"
 #include "mlir/Dialect/AMX/Transforms.h"
 #include "mlir/Dialect/Affine/TransformOps/AffineTransformOps.h"
 #include "mlir/Dialect/Bufferization/TransformOps/BufferizationTransformOps.h"
@@ -76,6 +77,7 @@ inline void registerAllExtensions(DialectRegistry &registry) {
   registerConvertAMXToLLVMInterface(registry);
   gpu::registerConvertGpuToLLVMInterface(registry);
   NVVM::registerConvertGpuToNVVMInterface(registry);
+  vector::registerConvertVectorToLLVMInterface(registry);
 
   // Register all transform dialect extensions.
   affine::registerTransformDialectExtension(registry);
diff --git a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
index 9657f583c375bb..a30f6479e8a705 100644
--- a/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
+++ b/mlir/lib/Conversion/VectorToLLVM/ConvertVectorToLLVM.cpp
@@ -9,6 +9,7 @@
 #include "mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h"
 
 #include "mlir/Conversion/ArithCommon/AttrToLLVMConverter.h"
+#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
 #include "mlir/Conversion/LLVMCommon/PrintCallHelper.h"
 #include "mlir/Conversion/LLVMCommon/TypeConverter.h"
 #include "mlir/Conversion/LLVMCommon/VectorPattern.h"
@@ -1933,3 +1934,27 @@ void mlir::populateVectorToLLVMMatrixConversionPatterns(
   patterns.add<VectorMatmulOpConversion>(converter);
   patterns.add<VectorFlatTransposeOpConversion>(converter);
 }
+
+namespace {
+struct VectorToLLVMDialectInterface : public ConvertToLLVMPatternInterface {
+  using ConvertToLLVMPatternInterface::ConvertToLLVMPatternInterface;
+  void loadDependentDialects(MLIRContext *context) const final {
+    context->loadDialect<LLVM::LLVMDialect>();
+  }
+
+  /// Hook for derived dialect interface to provide conversion patterns
+  /// and mark dialect legal for the conversion target.
+  void populateConvertToLLVMConversionPatterns(
+      ConversionTarget &target, LLVMTypeConverter &typeConverter,
+      RewritePatternSet &patterns) const final {
+    populateVectorToLLVMConversionPatterns(typeConverter, patterns);
+  }
+};
+} // namespace
+
+void mlir::vector::registerConvertVectorToLLVMInterface(
+    DialectRegistry &registry) {
+  registry.addExtension(+[](MLIRContext *ctx, vector::VectorDialect *dialect) {
+    dialect->addInterfaces<VectorToLLVMDialectInterface>();
+  });
+}
diff --git a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
index ae1cf95732336a..b57d89f0a96c01 100644
--- a/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
+++ b/mlir/lib/Dialect/Vector/IR/VectorOps.cpp
@@ -13,6 +13,7 @@
 
 #include "mlir/Dialect/Vector/IR/VectorOps.h"
 
+#include "mlir/Conversion/ConvertToLLVM/ToLLVMInterface.h"
 #include "mlir/Dialect/Affine/IR/ValueBoundsOpInterfaceImpl.h"
 #include "mlir/Dialect/Arith/IR/Arith.h"
 #include "mlir/Dialect/Arith/Utils/Utils.h"
@@ -429,6 +430,7 @@ void VectorDialect::initialize() {
                             TransferWriteOp>();
   declarePromisedInterface<SubsetExtractionOpInterface, TransferReadOp>();
   declarePromisedInterface<SubsetInsertionOpInterface, TransferWriteOp>();
+  declarePromisedInterface<ConvertToLLVMPatternInterface, VectorDialect>();
 }
 
 /// Materialize a single constant operation from a given attribute value with
diff --git a/mlir/test/Conversion/VectorToLLVM/vector-to-llvm-interface.mlir b/mlir/test/Conversion/VectorToLLVM/vector-to-llvm-interface.mlir
new file mode 100644
index 00000000000000..5252bb25ecab54
--- /dev/null
+++ b/mlir/test/Conversion/VectorToLLVM/vector-to-llvm-interface.mlir
@@ -0,0 +1,14 @@
+// Most of the vector lowering is tested in vector-to-llvm.mlir, this file only for the interface smoke test
+// RUN: mlir-opt --convert-to-llvm="filter-dialects=vector" --split-input-file %s | FileCheck %s
+
+func.func @bitcast_f32_to_i32_vector_0d(%arg0: vector<f32>) -> vector<i32> {
+  %0 = vector.bitcast %arg0 : vector<f32> to vector<i32>
+  return %0 : vector<i32>
+}
+
+// CHECK-LABEL: @bitcast_f32_to_i32_vector_0d
+// CHECK-SAME:  %[[ARG_0:.*]]: vector<f32>
+// CHECK:       %[[VEC_F32_1D:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : vector<f32> to vector<1xf32>
+// CHECK:       %[[VEC_I32_1D:.*]] = llvm.bitcast %[[VEC_F32_1D]] : vector<1xf32> to vector<1xi32>
+// CHECK:       %[[VEC_I32_0D:.*]] = builtin.unrealized_conversion_cast %[[VEC_I32_1D]] : vector<1xi32> to vector<i32>
+// CHECK:       return %[[VEC_I32_0D]] : vector<i32>

@Hardcode84
Copy link
Contributor Author

ping

1 similar comment
@Hardcode84
Copy link
Contributor Author

ping

@banach-space
Copy link
Contributor

Thanks! Could this be used as a separate RUN line in https://github.com/llvm/llvm-project/blob/main/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir? Otherwise, what's the benefit?

@Hardcode84
Copy link
Contributor Author

Hardcode84 commented Jan 22, 2025

Thanks! Could this be used as a separate RUN line in https://github.com/llvm/llvm-project/blob/main/mlir/test/Conversion/VectorToLLVM/vector-to-llvm.mlir? Otherwise, what's the benefit?

We cannot (easily) do this. These tests designed to work with convert-vector-to-llvm pass which includes some preparations patterns running through applyPatternsGreedily.
Also, this pass includes armNeon/armSVE/amx/x86Vector specific transforms (which should probably be handled through their own dedicated ToLLVMDialectInterfaces).

Motivation for this one is to unhardcode conversions from GPUtoROCDL/NVVM passes https://github.com/llvm/llvm-project/blob/main/mlir/lib/Conversion/GPUToROCDL/LowerGpuOpsToROCDLOps.cpp#L296

@banach-space
Copy link
Contributor

Thanks for getting back to me.

We cannot (easily) do this. These tests designed to work with convert-vector-to-llvm pass which includes some preparations patterns running through applyPatternsGreedily.

This doesn't sound right. The tests in "Conversion/VectorToLLVM" should exercise the dialect conversion, i.e.

void mlir::populateVectorToLLVMConversionPatterns(
const LLVMTypeConverter &converter, RewritePatternSet &patterns,
bool reassociateFPReductions, bool force32BitVectorIndices) {
// This function populates only ConversionPatterns, not RewritePatterns.
MLIRContext *ctx = converter.getDialect()->getContext();
patterns.add<VectorReductionOpConversion>(converter, reassociateFPReductions);
patterns.add<VectorCreateMaskOpConversion>(ctx, force32BitVectorIndices);
patterns.add<VectorBitCastOpConversion, VectorShuffleOpConversion,
VectorExtractElementOpConversion, VectorExtractOpConversion,
VectorFMAOp1DConversion, VectorInsertElementOpConversion,
VectorInsertOpConversion, VectorPrintOpConversion,
VectorTypeCastOpConversion, VectorScaleOpConversion,
VectorLoadStoreConversion<vector::LoadOp>,
VectorLoadStoreConversion<vector::MaskedLoadOp>,
VectorLoadStoreConversion<vector::StoreOp>,
VectorLoadStoreConversion<vector::MaskedStoreOp>,
VectorGatherOpConversion, VectorScatterOpConversion,
VectorExpandLoadOpConversion, VectorCompressStoreOpConversion,
VectorSplatOpLowering, VectorSplatNdOpLowering,
VectorScalableInsertOpLowering, VectorScalableExtractOpLowering,
MaskedReductionOpConversion, VectorInterleaveOpLowering,
VectorDeinterleaveOpLowering, VectorFromElementsLowering,
VectorScalableStepOpLowering>(converter);
}

That's exactly what the newly proposed VectorToLLVMDialectInterface is meant to run, right?

So, could you provide specific examples where things break (i.e. my assumption doesn't hold)? It's possible that "vector-to-llvm.mlir" contains tests that shouldn't be there. If that's the case, we should use this opportunity to fix that.

Also, this pass includes armNeon/armSVE/amx/x86Vector specific transforms (which should probably be handled through their own dedicated ToLLVMDialectInterfaces).

There's nothing architecture specific in "vector-to-llvm.mlir", so none of these should be required. If that's not the case, we should that file.

Motivation for this one is to unhardcode conversions from GPUtoROCDL/NVVM passes https://github.com/llvm/llvm-project/blob/main/mlir/lib/Conversion/GPUToROCDL/LowerGpuOpsToROCDLOps.cpp#L296

Right now it's not clear to me how that's connected, but if it's going to help, then we should make it happen. In fact, it would be good to make sure that this change unblocks something useful. So - why not include the changes for "LowerGpuOpsToROCDLOps.cpp" in this PR?

@Hardcode84
Copy link
Contributor Author

Hardcode84 commented Jan 24, 2025

So, could you provide specific examples where things break (i.e. my assumption doesn't hold)? It's possible that "vector-to-llvm.mlir" contains tests that shouldn't be there. If that's the case, we should use this opportunity to fix that.

There are a lot of them, full log: https://gist.github.com/Hardcode84/e1de4dc58ea7b47275e1aaff89e5567b

@Hardcode84
Copy link
Contributor Author

What we can probably do is to extract these initial transforms into dedicated pass and run it before generic convert-to-llvm for the vector-to-llvm.mlir.

@banach-space
Copy link
Contributor

What we can probably do is to extract these initial transforms into dedicated pass and run it before generic convert-to-llvm for the vector-to-llvm.mlir.

I think that we can move this discussion elsewhere:

As for this PR specifically, are you able to provide an example how it would benefit "LowerGpuOpsToROCDLOps.cpp"? To me that would be sufficient to unblock this.

@Hardcode84
Copy link
Contributor Author

As for this PR specifically, are you able to provide an example how it would benefit "LowerGpuOpsToROCDLOps.cpp"? To me that would be sufficient to unblock this.

#124439

Create `VectorToLLVMDialectInterface` which allows automatic conversion discovery by generic `--convert-to-llvm` pass.
This only covers final dialect conversion step and not any previous preparation steps.
Also, currently there is no way to pass any additional parameters through this conversion interface, but most users using default parameters anyway.
Copy link
Contributor

@banach-space banach-space left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Here's a follow-up to fully leverage the newly introduced flag:

(also a follow-up for #124308)

@Hardcode84 Hardcode84 merged commit 6e52a12 into llvm:main Feb 5, 2025
8 checks passed
@Hardcode84 Hardcode84 deleted the vector-translate branch February 5, 2025 20:21
rupprecht added a commit that referenced this pull request Feb 5, 2025
github-actions bot pushed a commit to arm/arm-toolchain that referenced this pull request Feb 5, 2025
Icohedron pushed a commit to Icohedron/llvm-project that referenced this pull request Feb 11, 2025
Create `VectorToLLVMDialectInterface` which allows automatic conversion
discovery by generic `--convert-to-llvm` pass. This only covers final
dialect conversion step and not any previous preparation steps. Also,
currently there is no way to pass any additional parameters through this
conversion interface, but most users using default parameters anyway.
Icohedron pushed a commit to Icohedron/llvm-project that referenced this pull request Feb 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants