-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[mlir][vector] Categorize Vector-to-LLVM conversion tests (nfc) #125918
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
[mlir][vector] Categorize Vector-to-LLVM conversion tests (nfc) #125918
Conversation
@llvm/pr-subscribers-mlir Author: Andrzej Warzyński (banach-space) Changes
Patch is 285.32 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/125918.diff 6 Files Affected:
diff --git a/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h b/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
index 5fda62e3584c79b..1e29bfeb9c3921a 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 ®istry);
+}
} // namespace mlir
#endif // MLIR_CONVERSION_VECTORTOLLVM_CONVERTVECTORTOLLVM_H_
diff --git a/mlir/include/mlir/InitAllExtensions.h b/mlir/include/mlir/InitAllExtensions.h
index 14a6a2787b3a5d1..887db344ed88b67 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 ®istry) {
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 d688d8e2ab65881..30eed1c849a7c6b 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 ®istry) {
+ 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 ae1cf95732336ac..b57d89f0a96c01d 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 000000000000000..ee3cb781708751c
--- /dev/null
+++ b/mlir/test/Conversion/VectorToLLVM/vector-to-llvm-interface.mlir
@@ -0,0 +1,2385 @@
+// RUN: mlir-opt --convert-to-llvm="filter-dialects=vector" --split-input-file %s | FileCheck %s --check-prefixes=CHECK,PARTIAL
+// RUN: mlir-opt %s -convert-vector-to-llvm -split-input-file | FileCheck %s --check-prefixes=CHECK,FULL
+
+//===========================================================================//
+// Basic tests for Vector-to-LLVM conversion
+//
+// These examples are meant to lower with:
+// * `populateVectorToLLVMConversionPatterns`
+// i.e. no other patterns should be required.
+//===========================================================================//
+
+//===----------------------------------------------------------------------===//
+// vector.bitcast
+//===----------------------------------------------------------------------===//
+
+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>
+
+// -----
+
+func.func @bitcast_f32_to_i32_vector(%arg0: vector<16xf32>) -> vector<16xi32> {
+ %0 = vector.bitcast %arg0 : vector<16xf32> to vector<16xi32>
+ return %0 : vector<16xi32>
+}
+
+
+// CHECK-LABEL: @bitcast_f32_to_i32_vector
+// CHECK-SAME: %[[ARG_0:.*]]: vector<16xf32>
+// CHECK: llvm.bitcast %[[ARG_0]] : vector<16xf32> to vector<16xi32>
+
+// -----
+
+func.func @bitcast_f32_to_i32_vector_scalable(%arg0: vector<[16]xf32>) -> vector<[16]xi32> {
+ %0 = vector.bitcast %arg0 : vector<[16]xf32> to vector<[16]xi32>
+ return %0 : vector<[16]xi32>
+}
+
+// CHECK-LABEL: @bitcast_f32_to_i32_vector_scalable
+// CHECK-SAME: %[[ARG_0:.*]]: vector<[16]xf32>
+// CHECK: llvm.bitcast %[[ARG_0]] : vector<[16]xf32> to vector<[16]xi32>
+
+// -----
+
+func.func @bitcast_i8_to_f32_vector(%arg0: vector<64xi8>) -> vector<16xf32> {
+ %0 = vector.bitcast %arg0 : vector<64xi8> to vector<16xf32>
+ return %0 : vector<16xf32>
+}
+
+// CHECK-LABEL: @bitcast_i8_to_f32_vector
+// CHECK-SAME: %[[ARG_0:.*]]: vector<64xi8>
+// CHECK: llvm.bitcast %[[ARG_0]] : vector<64xi8> to vector<16xf32>
+
+// -----
+
+func.func @bitcast_i8_to_f32_vector_scalable(%arg0: vector<[64]xi8>) -> vector<[16]xf32> {
+ %0 = vector.bitcast %arg0 : vector<[64]xi8> to vector<[16]xf32>
+ return %0 : vector<[16]xf32>
+}
+
+// CHECK-LABEL: @bitcast_i8_to_f32_vector_scalable
+// CHECK-SAME: %[[ARG_0:.*]]: vector<[64]xi8>
+// CHECK: llvm.bitcast %[[ARG_0]] : vector<[64]xi8> to vector<[16]xf32>
+
+// -----
+
+func.func @bitcast_index_to_i8_vector(%arg0: vector<16xindex>) -> vector<128xi8> {
+ %0 = vector.bitcast %arg0 : vector<16xindex> to vector<128xi8>
+ return %0 : vector<128xi8>
+}
+
+// CHECK-LABEL: @bitcast_index_to_i8_vector
+// CHECK-SAME: %[[ARG_0:.*]]: vector<16xindex>
+// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : vector<16xindex> to vector<16xi64>
+// CHECK: llvm.bitcast %[[T0]] : vector<16xi64> to vector<128xi8>
+
+// -----
+
+func.func @bitcast_index_to_i8_vector_scalable(%arg0: vector<[16]xindex>) -> vector<[128]xi8> {
+ %0 = vector.bitcast %arg0 : vector<[16]xindex> to vector<[128]xi8>
+ return %0 : vector<[128]xi8>
+}
+
+// CHECK-LABEL: @bitcast_index_to_i8_vector_scalable
+// CHECK-SAME: %[[ARG_0:.*]]: vector<[16]xindex>
+// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : vector<[16]xindex> to vector<[16]xi64>
+// CHECK: llvm.bitcast %[[T0]] : vector<[16]xi64> to vector<[128]xi8>
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// vector.broadcast
+//===----------------------------------------------------------------------===//
+
+func.func @broadcast_vec1d_from_vec1d(%arg0: vector<2xf32>) -> vector<2xf32> {
+ %0 = vector.broadcast %arg0 : vector<2xf32> to vector<2xf32>
+ return %0 : vector<2xf32>
+}
+// CHECK-LABEL: @broadcast_vec1d_from_vec1d(
+// CHECK-SAME: %[[A:.*]]: vector<2xf32>)
+// CHECK: return %[[A]] : vector<2xf32>
+
+// -----
+
+func.func @broadcast_vec1d_from_vec1d_scalable(%arg0: vector<[2]xf32>) -> vector<[2]xf32> {
+ %0 = vector.broadcast %arg0 : vector<[2]xf32> to vector<[2]xf32>
+ return %0 : vector<[2]xf32>
+}
+// CHECK-LABEL: @broadcast_vec1d_from_vec1d_scalable(
+// CHECK-SAME: %[[A:.*]]: vector<[2]xf32>)
+// CHECK: return %[[A]] : vector<[2]xf32>
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// vector.shuffle
+//===----------------------------------------------------------------------===//
+
+func.func @shuffle_0D_direct(%arg0: vector<f32>) -> vector<3xf32> {
+ %1 = vector.shuffle %arg0, %arg0 [0, 1, 0] : vector<f32>, vector<f32>
+ return %1 : vector<3xf32>
+}
+// CHECK-LABEL: @shuffle_0D_direct(
+// CHECK-SAME: %[[A:.*]]: vector<f32>
+// CHECK: %[[c:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<f32> to vector<1xf32>
+// CHECK: %[[s:.*]] = llvm.shufflevector %[[c]], %[[c]] [0, 1, 0] : vector<1xf32>
+// CHECK: return %[[s]] : vector<3xf32>
+
+// -----
+
+func.func @shuffle_1D_direct(%arg0: vector<2xf32>, %arg1: vector<2xf32>) -> vector<2xf32> {
+ %1 = vector.shuffle %arg0, %arg1 [0, 1] : vector<2xf32>, vector<2xf32>
+ return %1 : vector<2xf32>
+}
+// CHECK-LABEL: @shuffle_1D_direct(
+// CHECK-SAME: %[[A:.*]]: vector<2xf32>,
+// CHECK-SAME: %[[B:.*]]: vector<2xf32>)
+// CHECK: return %[[A:.*]]: vector<2xf32>
+
+// -----
+
+func.func @shuffle_1D_index_direct(%arg0: vector<2xindex>, %arg1: vector<2xindex>) -> vector<2xindex> {
+ %1 = vector.shuffle %arg0, %arg1 [0, 1] : vector<2xindex>, vector<2xindex>
+ return %1 : vector<2xindex>
+}
+// CHECK-LABEL: @shuffle_1D_index_direct(
+// CHECK-SAME: %[[A:.*]]: vector<2xindex>,
+// CHECK-SAME: %[[B:.*]]: vector<2xindex>)
+// CHECK: return %[[A:.*]]: vector<2xindex>
+
+// -----
+
+func.func @shuffle_1D(%arg0: vector<2xf32>, %arg1: vector<3xf32>) -> vector<5xf32> {
+ %1 = vector.shuffle %arg0, %arg1 [4, 3, 2, 1, 0] : vector<2xf32>, vector<3xf32>
+ return %1 : vector<5xf32>
+}
+// CHECK-LABEL: @shuffle_1D(
+// CHECK-SAME: %[[A:.*]]: vector<2xf32>,
+// CHECK-SAME: %[[B:.*]]: vector<3xf32>)
+// CHECK: %[[U0:.*]] = llvm.mlir.undef : vector<5xf32>
+// CHECK: %[[C2:.*]] = llvm.mlir.constant(2 : index) : i64
+// CHECK: %[[E1:.*]] = llvm.extractelement %[[B]][%[[C2]] : i64] : vector<3xf32>
+// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[I1:.*]] = llvm.insertelement %[[E1]], %[[U0]][%[[C0]] : i64] : vector<5xf32>
+// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[E2:.*]] = llvm.extractelement %[[B]][%[[C1]] : i64] : vector<3xf32>
+// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[I2:.*]] = llvm.insertelement %[[E2]], %[[I1]][%[[C1]] : i64] : vector<5xf32>
+// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[E3:.*]] = llvm.extractelement %[[B]][%[[C0]] : i64] : vector<3xf32>
+// CHECK: %[[C2:.*]] = llvm.mlir.constant(2 : index) : i64
+// CHECK: %[[I3:.*]] = llvm.insertelement %[[E3]], %[[I2]][%[[C2]] : i64] : vector<5xf32>
+// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[E4:.*]] = llvm.extractelement %[[A]][%[[C1]] : i64] : vector<2xf32>
+// CHECK: %[[C3:.*]] = llvm.mlir.constant(3 : index) : i64
+// CHECK: %[[I4:.*]] = llvm.insertelement %[[E4]], %[[I3]][%[[C3]] : i64] : vector<5xf32>
+// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[E5:.*]] = llvm.extractelement %[[A]][%[[C0]] : i64] : vector<2xf32>
+// CHECK: %[[C4:.*]] = llvm.mlir.constant(4 : index) : i64
+// CHECK: %[[I5:.*]] = llvm.insertelement %[[E5]], %[[I4]][%[[C4]] : i64] : vector<5xf32>
+// CHECK: return %[[I5]] : vector<5xf32>
+
+// -----
+
+func.func @shuffle_2D(%a: vector<1x4xf32>, %b: vector<2x4xf32>) -> vector<3x4xf32> {
+ %1 = vector.shuffle %a, %b[1, 0, 2] : vector<1x4xf32>, vector<2x4xf32>
+ return %1 : vector<3x4xf32>
+}
+// CHECK-LABEL: @shuffle_2D(
+// CHECK-SAME: %[[A:.*]]: vector<1x4xf32>,
+// CHECK-SAME: %[[B:.*]]: vector<2x4xf32>)
+// CHECK-DAG: %[[VAL_0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<1x4xf32> to !llvm.array<1 x vector<4xf32>>
+// CHECK-DAG: %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[B]] : vector<2x4xf32> to !llvm.array<2 x vector<4xf32>>
+// CHECK: %[[U0:.*]] = llvm.mlir.undef : !llvm.array<3 x vector<4xf32>>
+// CHECK: %[[E1:.*]] = llvm.extractvalue %[[VAL_1]][0] : !llvm.array<2 x vector<4xf32>>
+// CHECK: %[[I1:.*]] = llvm.insertvalue %[[E1]], %[[U0]][0] : !llvm.array<3 x vector<4xf32>>
+// CHECK: %[[E2:.*]] = llvm.extractvalue %[[VAL_0]][0] : !llvm.array<1 x vector<4xf32>>
+// CHECK: %[[I2:.*]] = llvm.insertvalue %[[E2]], %[[I1]][1] : !llvm.array<3 x vector<4xf32>>
+// CHECK: %[[E3:.*]] = llvm.extractvalue %[[VAL_1]][1] : !llvm.array<2 x vector<4xf32>>
+// CHECK: %[[I3:.*]] = llvm.insertvalue %[[E3]], %[[I2]][2] : !llvm.array<3 x vector<4xf32>>
+// CHECK: %[[VAL_3:.*]] = builtin.unrealized_conversion_cast %[[I3]] : !llvm.array<3 x vector<4xf32>> to vector<3x4xf32>
+// CHECK: return %[[VAL_3]] : vector<3x4xf32>
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// vector.extractelement
+//===----------------------------------------------------------------------===//
+
+func.func @extractelement_from_vec_0d_f32(%arg0: vector<f32>) -> f32 {
+ %1 = vector.extractelement %arg0[] : vector<f32>
+ return %1 : f32
+}
+// CHECK-LABEL: @extractelement_from_vec_0d_f32
+// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: llvm.extractelement %{{.*}}[%[[C0]] : {{.*}}] : vector<1xf32>
+
+// -----
+
+func.func @extractelement_from_vec_1d_f32_idx_as_i32(%arg0: vector<16xf32>) -> f32 {
+ %0 = arith.constant 15 : i32
+ %1 = vector.extractelement %arg0[%0 : i32]: vector<16xf32>
+ return %1 : f32
+}
+// CHECK-LABEL: @extractelement_from_vec_1d_f32_idx_as_i32(
+// CHECK-SAME: %[[A:.*]]: vector<16xf32>)
+// CHECK: %[[C:.*]] = arith.constant 15 : i32
+// CHECK: %[[X:.*]] = llvm.extractelement %[[A]][%[[C]] : i32] : vector<16xf32>
+// CHECK: return %[[X]] : f32
+
+// -----
+
+func.func @extractelement_from_vec_1d_f32_idx_as_i32_scalable(%arg0: vector<[16]xf32>) -> f32 {
+ %0 = arith.constant 15 : i32
+ %1 = vector.extractelement %arg0[%0 : i32]: vector<[16]xf32>
+ return %1 : f32
+}
+// CHECK-LABEL: @extractelement_from_vec_1d_f32_idx_as_i32_scalable(
+// CHECK-SAME: %[[A:.*]]: vector<[16]xf32>)
+// CHECK: %[[C:.*]] = arith.constant 15 : i32
+// CHECK: %[[X:.*]] = llvm.extractelement %[[A]][%[[C]] : i32] : vector<[16]xf32>
+// CHECK: return %[[X]] : f32
+
+// -----
+func.func @extractelement_from_vec_1d_f32_idx_as_index(%arg0: vector<16xf32>) -> f32 {
+ %0 = arith.constant 15 : index
+ %1 = vector.extractelement %arg0[%0 : index]: vector<16xf32>
+ return %1 : f32
+}
+// CHECK-LABEL: @extractelement_from_vec_1d_f32_idx_as_index(
+// CHECK-SAME: %[[A:.*]]: vector<16xf32>)
+// CHECK: %[[C:.*]] = arith.constant 15 : index
+// CHECK: %[[I:.*]] = builtin.unrealized_conversion_cast %[[C]] : index to i64
+// CHECK: %[[X:.*]] = llvm.extractelement %[[A]][%[[I]] : i64] : vector<16xf32>
+// CHECK: return %[[X]] : f32
+
+// -----
+
+func.func @extractelement_from_vec_1d_f32_idx_as_index_scalable(%arg0: vector<[16]xf32>) -> f32 {
+ %0 = arith.constant 15 : index
+ %1 = vector.extractelement %arg0[%0 : index]: vector<[16]xf32>
+ return %1 : f32
+}
+// CHECK-LABEL: @extractelement_from_vec_1d_f32_idx_as_index_scalable(
+// CHECK-SAME: %[[A:.*]]: vector<[16]xf32>)
+// CHECK: %[[C:.*]] = arith.constant 15 : index
+// CHECK: %[[I:.*]] = builtin.unrealized_conversion_cast %[[C]] : index to i64
+// CHECK: %[[X:.*]] = llvm.extractelement %[[A]][%[[I]] : i64] : vector<[16]xf32>
+// CHECK: return %[[X]] : f32
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// vector.extract
+//===----------------------------------------------------------------------===//
+
+func.func @extract_scalar_from_vec_1d_f32(%arg0: vector<16xf32>) -> f32 {
+ %0 = vector.extract %arg0[15]: f32 from vector<16xf32>
+ return %0 : f32
+}
+// CHECK-LABEL: @extract_scalar_from_vec_1d_f32
+// CHECK: llvm.mlir.constant(15 : i64) : i64
+// CHECK: llvm.extractelement {{.*}}[{{.*}} : i64] : vector<16xf32>
+// CHECK: return {{.*}} : f32
+
+// -----
+
+func.func @extract_scalar_from_vec_1d_f32_scalable(%arg0: vector<[16]xf32>) -> f32 {
+ %0 = vector.extract %arg0[15]: f32 from vector<[16]xf32>
+ return %0 : f32
+}
+// CHECK-LABEL: @extract_scalar_from_vec_1d_f32_scalable
+// CHECK: llvm.mlir.constant(15 : i64) : i64
+// CHECK: llvm.extractelement {{.*}}[{{.*}} : i64] : vector<[16]xf32>
+// CHECK: return {{.*}} : f32
+
+// -----
+
+func.func @extract_vec_1e_from_vec_1d_f32(%arg0: vector<16xf32>) -> vector<1xf32> {
+ %0 = vector.extract %arg0[15]: vector<1xf32> from vector<16xf32>
+ return %0 : vector<1xf32>
+}
+// CHECK-LABEL: @extract_vec_1e_from_vec_1d_f32(
+// CHECK-SAME: %[[A:.*]]: vector<16xf32>)
+// CHECK: %[[T0:.*]] = llvm.mlir.constant(15 : i64) : i64
+// CHECK: %[[T1:.*]] = llvm.extractelement %[[A]][%[[T0]] : i64] : vector<16xf32>
+// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : f32 to vector<1xf32>
+// CHECK: return %[[T2]] : vector<1xf32>
+
+// -----
+
+func.func @extract_vec_1e_from_vec_1d_f32_scalable(%arg0: vector<[16]xf32>) -> vector<1xf32> {
+ %0 = vector.extract %arg0[15]: vector<1xf32> from vector<[16]xf32>
+ return %0 : vector<1xf32>
+}
+// CHECK-LABEL: @extract_vec_1e_from_vec_1d_f32_scalable(
+// CHECK-SAME: %[[A:.*]]: vector<[16]xf32>)
+// CHECK: %[[T0:.*]] = llvm.mlir.constant(15 : i64) : i64
+// CHECK: %[[T1:.*]] = llvm.extractelement %[[A]][%[[T0]] : i64] : vector<[16]xf32>
+// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : f32 to vector<1xf32>
+// CHECK: return %[[T2]] : vector<1xf32>
+
+// -----
+
+func.func @extract_scalar_from_vec_1d_index(%arg0: vector<16xindex>) -> index {
+ %0 = vector.extract %arg0[15]: index from vector<16xindex>
+ return %0 : index
+}
+// CHECK-LABEL: @extract_scalar_from_vec_1d_index(
+// CHECK-SAME: %[[A:.*]]: vector<16xindex>)
+// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<16xindex> to vector<16xi64>
+// CHECK: %[[T1:.*]] = llvm.mlir.constant(15 : i64) : i64
+// CHECK: %[[T2:.*]] = llvm.extractelement %[[T0]][%[[T1]] : i64] : vector<16xi64>
+// CHECK: %[[T3:.*]] = builtin.unrealized_conversion_cast %[[T2]] : i64 to index
+// CHECK: return %[[T3]] : index
+
+// -----
+
+func.func @extract_scalar_from_vec_1d_index_scalable(%arg0: vector<[16]xindex>) -> index {
+ %0 = vector.extract %arg0...
[truncated]
|
@llvm/pr-subscribers-mlir-vector Author: Andrzej Warzyński (banach-space) Changes
Patch is 285.32 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/125918.diff 6 Files Affected:
diff --git a/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h b/mlir/include/mlir/Conversion/VectorToLLVM/ConvertVectorToLLVM.h
index 5fda62e3584c79b..1e29bfeb9c3921a 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 ®istry);
+}
} // namespace mlir
#endif // MLIR_CONVERSION_VECTORTOLLVM_CONVERTVECTORTOLLVM_H_
diff --git a/mlir/include/mlir/InitAllExtensions.h b/mlir/include/mlir/InitAllExtensions.h
index 14a6a2787b3a5d1..887db344ed88b67 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 ®istry) {
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 d688d8e2ab65881..30eed1c849a7c6b 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 ®istry) {
+ 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 ae1cf95732336ac..b57d89f0a96c01d 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 000000000000000..ee3cb781708751c
--- /dev/null
+++ b/mlir/test/Conversion/VectorToLLVM/vector-to-llvm-interface.mlir
@@ -0,0 +1,2385 @@
+// RUN: mlir-opt --convert-to-llvm="filter-dialects=vector" --split-input-file %s | FileCheck %s --check-prefixes=CHECK,PARTIAL
+// RUN: mlir-opt %s -convert-vector-to-llvm -split-input-file | FileCheck %s --check-prefixes=CHECK,FULL
+
+//===========================================================================//
+// Basic tests for Vector-to-LLVM conversion
+//
+// These examples are meant to lower with:
+// * `populateVectorToLLVMConversionPatterns`
+// i.e. no other patterns should be required.
+//===========================================================================//
+
+//===----------------------------------------------------------------------===//
+// vector.bitcast
+//===----------------------------------------------------------------------===//
+
+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>
+
+// -----
+
+func.func @bitcast_f32_to_i32_vector(%arg0: vector<16xf32>) -> vector<16xi32> {
+ %0 = vector.bitcast %arg0 : vector<16xf32> to vector<16xi32>
+ return %0 : vector<16xi32>
+}
+
+
+// CHECK-LABEL: @bitcast_f32_to_i32_vector
+// CHECK-SAME: %[[ARG_0:.*]]: vector<16xf32>
+// CHECK: llvm.bitcast %[[ARG_0]] : vector<16xf32> to vector<16xi32>
+
+// -----
+
+func.func @bitcast_f32_to_i32_vector_scalable(%arg0: vector<[16]xf32>) -> vector<[16]xi32> {
+ %0 = vector.bitcast %arg0 : vector<[16]xf32> to vector<[16]xi32>
+ return %0 : vector<[16]xi32>
+}
+
+// CHECK-LABEL: @bitcast_f32_to_i32_vector_scalable
+// CHECK-SAME: %[[ARG_0:.*]]: vector<[16]xf32>
+// CHECK: llvm.bitcast %[[ARG_0]] : vector<[16]xf32> to vector<[16]xi32>
+
+// -----
+
+func.func @bitcast_i8_to_f32_vector(%arg0: vector<64xi8>) -> vector<16xf32> {
+ %0 = vector.bitcast %arg0 : vector<64xi8> to vector<16xf32>
+ return %0 : vector<16xf32>
+}
+
+// CHECK-LABEL: @bitcast_i8_to_f32_vector
+// CHECK-SAME: %[[ARG_0:.*]]: vector<64xi8>
+// CHECK: llvm.bitcast %[[ARG_0]] : vector<64xi8> to vector<16xf32>
+
+// -----
+
+func.func @bitcast_i8_to_f32_vector_scalable(%arg0: vector<[64]xi8>) -> vector<[16]xf32> {
+ %0 = vector.bitcast %arg0 : vector<[64]xi8> to vector<[16]xf32>
+ return %0 : vector<[16]xf32>
+}
+
+// CHECK-LABEL: @bitcast_i8_to_f32_vector_scalable
+// CHECK-SAME: %[[ARG_0:.*]]: vector<[64]xi8>
+// CHECK: llvm.bitcast %[[ARG_0]] : vector<[64]xi8> to vector<[16]xf32>
+
+// -----
+
+func.func @bitcast_index_to_i8_vector(%arg0: vector<16xindex>) -> vector<128xi8> {
+ %0 = vector.bitcast %arg0 : vector<16xindex> to vector<128xi8>
+ return %0 : vector<128xi8>
+}
+
+// CHECK-LABEL: @bitcast_index_to_i8_vector
+// CHECK-SAME: %[[ARG_0:.*]]: vector<16xindex>
+// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : vector<16xindex> to vector<16xi64>
+// CHECK: llvm.bitcast %[[T0]] : vector<16xi64> to vector<128xi8>
+
+// -----
+
+func.func @bitcast_index_to_i8_vector_scalable(%arg0: vector<[16]xindex>) -> vector<[128]xi8> {
+ %0 = vector.bitcast %arg0 : vector<[16]xindex> to vector<[128]xi8>
+ return %0 : vector<[128]xi8>
+}
+
+// CHECK-LABEL: @bitcast_index_to_i8_vector_scalable
+// CHECK-SAME: %[[ARG_0:.*]]: vector<[16]xindex>
+// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[ARG_0]] : vector<[16]xindex> to vector<[16]xi64>
+// CHECK: llvm.bitcast %[[T0]] : vector<[16]xi64> to vector<[128]xi8>
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// vector.broadcast
+//===----------------------------------------------------------------------===//
+
+func.func @broadcast_vec1d_from_vec1d(%arg0: vector<2xf32>) -> vector<2xf32> {
+ %0 = vector.broadcast %arg0 : vector<2xf32> to vector<2xf32>
+ return %0 : vector<2xf32>
+}
+// CHECK-LABEL: @broadcast_vec1d_from_vec1d(
+// CHECK-SAME: %[[A:.*]]: vector<2xf32>)
+// CHECK: return %[[A]] : vector<2xf32>
+
+// -----
+
+func.func @broadcast_vec1d_from_vec1d_scalable(%arg0: vector<[2]xf32>) -> vector<[2]xf32> {
+ %0 = vector.broadcast %arg0 : vector<[2]xf32> to vector<[2]xf32>
+ return %0 : vector<[2]xf32>
+}
+// CHECK-LABEL: @broadcast_vec1d_from_vec1d_scalable(
+// CHECK-SAME: %[[A:.*]]: vector<[2]xf32>)
+// CHECK: return %[[A]] : vector<[2]xf32>
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// vector.shuffle
+//===----------------------------------------------------------------------===//
+
+func.func @shuffle_0D_direct(%arg0: vector<f32>) -> vector<3xf32> {
+ %1 = vector.shuffle %arg0, %arg0 [0, 1, 0] : vector<f32>, vector<f32>
+ return %1 : vector<3xf32>
+}
+// CHECK-LABEL: @shuffle_0D_direct(
+// CHECK-SAME: %[[A:.*]]: vector<f32>
+// CHECK: %[[c:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<f32> to vector<1xf32>
+// CHECK: %[[s:.*]] = llvm.shufflevector %[[c]], %[[c]] [0, 1, 0] : vector<1xf32>
+// CHECK: return %[[s]] : vector<3xf32>
+
+// -----
+
+func.func @shuffle_1D_direct(%arg0: vector<2xf32>, %arg1: vector<2xf32>) -> vector<2xf32> {
+ %1 = vector.shuffle %arg0, %arg1 [0, 1] : vector<2xf32>, vector<2xf32>
+ return %1 : vector<2xf32>
+}
+// CHECK-LABEL: @shuffle_1D_direct(
+// CHECK-SAME: %[[A:.*]]: vector<2xf32>,
+// CHECK-SAME: %[[B:.*]]: vector<2xf32>)
+// CHECK: return %[[A:.*]]: vector<2xf32>
+
+// -----
+
+func.func @shuffle_1D_index_direct(%arg0: vector<2xindex>, %arg1: vector<2xindex>) -> vector<2xindex> {
+ %1 = vector.shuffle %arg0, %arg1 [0, 1] : vector<2xindex>, vector<2xindex>
+ return %1 : vector<2xindex>
+}
+// CHECK-LABEL: @shuffle_1D_index_direct(
+// CHECK-SAME: %[[A:.*]]: vector<2xindex>,
+// CHECK-SAME: %[[B:.*]]: vector<2xindex>)
+// CHECK: return %[[A:.*]]: vector<2xindex>
+
+// -----
+
+func.func @shuffle_1D(%arg0: vector<2xf32>, %arg1: vector<3xf32>) -> vector<5xf32> {
+ %1 = vector.shuffle %arg0, %arg1 [4, 3, 2, 1, 0] : vector<2xf32>, vector<3xf32>
+ return %1 : vector<5xf32>
+}
+// CHECK-LABEL: @shuffle_1D(
+// CHECK-SAME: %[[A:.*]]: vector<2xf32>,
+// CHECK-SAME: %[[B:.*]]: vector<3xf32>)
+// CHECK: %[[U0:.*]] = llvm.mlir.undef : vector<5xf32>
+// CHECK: %[[C2:.*]] = llvm.mlir.constant(2 : index) : i64
+// CHECK: %[[E1:.*]] = llvm.extractelement %[[B]][%[[C2]] : i64] : vector<3xf32>
+// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[I1:.*]] = llvm.insertelement %[[E1]], %[[U0]][%[[C0]] : i64] : vector<5xf32>
+// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[E2:.*]] = llvm.extractelement %[[B]][%[[C1]] : i64] : vector<3xf32>
+// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[I2:.*]] = llvm.insertelement %[[E2]], %[[I1]][%[[C1]] : i64] : vector<5xf32>
+// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[E3:.*]] = llvm.extractelement %[[B]][%[[C0]] : i64] : vector<3xf32>
+// CHECK: %[[C2:.*]] = llvm.mlir.constant(2 : index) : i64
+// CHECK: %[[I3:.*]] = llvm.insertelement %[[E3]], %[[I2]][%[[C2]] : i64] : vector<5xf32>
+// CHECK: %[[C1:.*]] = llvm.mlir.constant(1 : index) : i64
+// CHECK: %[[E4:.*]] = llvm.extractelement %[[A]][%[[C1]] : i64] : vector<2xf32>
+// CHECK: %[[C3:.*]] = llvm.mlir.constant(3 : index) : i64
+// CHECK: %[[I4:.*]] = llvm.insertelement %[[E4]], %[[I3]][%[[C3]] : i64] : vector<5xf32>
+// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: %[[E5:.*]] = llvm.extractelement %[[A]][%[[C0]] : i64] : vector<2xf32>
+// CHECK: %[[C4:.*]] = llvm.mlir.constant(4 : index) : i64
+// CHECK: %[[I5:.*]] = llvm.insertelement %[[E5]], %[[I4]][%[[C4]] : i64] : vector<5xf32>
+// CHECK: return %[[I5]] : vector<5xf32>
+
+// -----
+
+func.func @shuffle_2D(%a: vector<1x4xf32>, %b: vector<2x4xf32>) -> vector<3x4xf32> {
+ %1 = vector.shuffle %a, %b[1, 0, 2] : vector<1x4xf32>, vector<2x4xf32>
+ return %1 : vector<3x4xf32>
+}
+// CHECK-LABEL: @shuffle_2D(
+// CHECK-SAME: %[[A:.*]]: vector<1x4xf32>,
+// CHECK-SAME: %[[B:.*]]: vector<2x4xf32>)
+// CHECK-DAG: %[[VAL_0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<1x4xf32> to !llvm.array<1 x vector<4xf32>>
+// CHECK-DAG: %[[VAL_1:.*]] = builtin.unrealized_conversion_cast %[[B]] : vector<2x4xf32> to !llvm.array<2 x vector<4xf32>>
+// CHECK: %[[U0:.*]] = llvm.mlir.undef : !llvm.array<3 x vector<4xf32>>
+// CHECK: %[[E1:.*]] = llvm.extractvalue %[[VAL_1]][0] : !llvm.array<2 x vector<4xf32>>
+// CHECK: %[[I1:.*]] = llvm.insertvalue %[[E1]], %[[U0]][0] : !llvm.array<3 x vector<4xf32>>
+// CHECK: %[[E2:.*]] = llvm.extractvalue %[[VAL_0]][0] : !llvm.array<1 x vector<4xf32>>
+// CHECK: %[[I2:.*]] = llvm.insertvalue %[[E2]], %[[I1]][1] : !llvm.array<3 x vector<4xf32>>
+// CHECK: %[[E3:.*]] = llvm.extractvalue %[[VAL_1]][1] : !llvm.array<2 x vector<4xf32>>
+// CHECK: %[[I3:.*]] = llvm.insertvalue %[[E3]], %[[I2]][2] : !llvm.array<3 x vector<4xf32>>
+// CHECK: %[[VAL_3:.*]] = builtin.unrealized_conversion_cast %[[I3]] : !llvm.array<3 x vector<4xf32>> to vector<3x4xf32>
+// CHECK: return %[[VAL_3]] : vector<3x4xf32>
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// vector.extractelement
+//===----------------------------------------------------------------------===//
+
+func.func @extractelement_from_vec_0d_f32(%arg0: vector<f32>) -> f32 {
+ %1 = vector.extractelement %arg0[] : vector<f32>
+ return %1 : f32
+}
+// CHECK-LABEL: @extractelement_from_vec_0d_f32
+// CHECK: %[[C0:.*]] = llvm.mlir.constant(0 : index) : i64
+// CHECK: llvm.extractelement %{{.*}}[%[[C0]] : {{.*}}] : vector<1xf32>
+
+// -----
+
+func.func @extractelement_from_vec_1d_f32_idx_as_i32(%arg0: vector<16xf32>) -> f32 {
+ %0 = arith.constant 15 : i32
+ %1 = vector.extractelement %arg0[%0 : i32]: vector<16xf32>
+ return %1 : f32
+}
+// CHECK-LABEL: @extractelement_from_vec_1d_f32_idx_as_i32(
+// CHECK-SAME: %[[A:.*]]: vector<16xf32>)
+// CHECK: %[[C:.*]] = arith.constant 15 : i32
+// CHECK: %[[X:.*]] = llvm.extractelement %[[A]][%[[C]] : i32] : vector<16xf32>
+// CHECK: return %[[X]] : f32
+
+// -----
+
+func.func @extractelement_from_vec_1d_f32_idx_as_i32_scalable(%arg0: vector<[16]xf32>) -> f32 {
+ %0 = arith.constant 15 : i32
+ %1 = vector.extractelement %arg0[%0 : i32]: vector<[16]xf32>
+ return %1 : f32
+}
+// CHECK-LABEL: @extractelement_from_vec_1d_f32_idx_as_i32_scalable(
+// CHECK-SAME: %[[A:.*]]: vector<[16]xf32>)
+// CHECK: %[[C:.*]] = arith.constant 15 : i32
+// CHECK: %[[X:.*]] = llvm.extractelement %[[A]][%[[C]] : i32] : vector<[16]xf32>
+// CHECK: return %[[X]] : f32
+
+// -----
+func.func @extractelement_from_vec_1d_f32_idx_as_index(%arg0: vector<16xf32>) -> f32 {
+ %0 = arith.constant 15 : index
+ %1 = vector.extractelement %arg0[%0 : index]: vector<16xf32>
+ return %1 : f32
+}
+// CHECK-LABEL: @extractelement_from_vec_1d_f32_idx_as_index(
+// CHECK-SAME: %[[A:.*]]: vector<16xf32>)
+// CHECK: %[[C:.*]] = arith.constant 15 : index
+// CHECK: %[[I:.*]] = builtin.unrealized_conversion_cast %[[C]] : index to i64
+// CHECK: %[[X:.*]] = llvm.extractelement %[[A]][%[[I]] : i64] : vector<16xf32>
+// CHECK: return %[[X]] : f32
+
+// -----
+
+func.func @extractelement_from_vec_1d_f32_idx_as_index_scalable(%arg0: vector<[16]xf32>) -> f32 {
+ %0 = arith.constant 15 : index
+ %1 = vector.extractelement %arg0[%0 : index]: vector<[16]xf32>
+ return %1 : f32
+}
+// CHECK-LABEL: @extractelement_from_vec_1d_f32_idx_as_index_scalable(
+// CHECK-SAME: %[[A:.*]]: vector<[16]xf32>)
+// CHECK: %[[C:.*]] = arith.constant 15 : index
+// CHECK: %[[I:.*]] = builtin.unrealized_conversion_cast %[[C]] : index to i64
+// CHECK: %[[X:.*]] = llvm.extractelement %[[A]][%[[I]] : i64] : vector<[16]xf32>
+// CHECK: return %[[X]] : f32
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// vector.extract
+//===----------------------------------------------------------------------===//
+
+func.func @extract_scalar_from_vec_1d_f32(%arg0: vector<16xf32>) -> f32 {
+ %0 = vector.extract %arg0[15]: f32 from vector<16xf32>
+ return %0 : f32
+}
+// CHECK-LABEL: @extract_scalar_from_vec_1d_f32
+// CHECK: llvm.mlir.constant(15 : i64) : i64
+// CHECK: llvm.extractelement {{.*}}[{{.*}} : i64] : vector<16xf32>
+// CHECK: return {{.*}} : f32
+
+// -----
+
+func.func @extract_scalar_from_vec_1d_f32_scalable(%arg0: vector<[16]xf32>) -> f32 {
+ %0 = vector.extract %arg0[15]: f32 from vector<[16]xf32>
+ return %0 : f32
+}
+// CHECK-LABEL: @extract_scalar_from_vec_1d_f32_scalable
+// CHECK: llvm.mlir.constant(15 : i64) : i64
+// CHECK: llvm.extractelement {{.*}}[{{.*}} : i64] : vector<[16]xf32>
+// CHECK: return {{.*}} : f32
+
+// -----
+
+func.func @extract_vec_1e_from_vec_1d_f32(%arg0: vector<16xf32>) -> vector<1xf32> {
+ %0 = vector.extract %arg0[15]: vector<1xf32> from vector<16xf32>
+ return %0 : vector<1xf32>
+}
+// CHECK-LABEL: @extract_vec_1e_from_vec_1d_f32(
+// CHECK-SAME: %[[A:.*]]: vector<16xf32>)
+// CHECK: %[[T0:.*]] = llvm.mlir.constant(15 : i64) : i64
+// CHECK: %[[T1:.*]] = llvm.extractelement %[[A]][%[[T0]] : i64] : vector<16xf32>
+// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : f32 to vector<1xf32>
+// CHECK: return %[[T2]] : vector<1xf32>
+
+// -----
+
+func.func @extract_vec_1e_from_vec_1d_f32_scalable(%arg0: vector<[16]xf32>) -> vector<1xf32> {
+ %0 = vector.extract %arg0[15]: vector<1xf32> from vector<[16]xf32>
+ return %0 : vector<1xf32>
+}
+// CHECK-LABEL: @extract_vec_1e_from_vec_1d_f32_scalable(
+// CHECK-SAME: %[[A:.*]]: vector<[16]xf32>)
+// CHECK: %[[T0:.*]] = llvm.mlir.constant(15 : i64) : i64
+// CHECK: %[[T1:.*]] = llvm.extractelement %[[A]][%[[T0]] : i64] : vector<[16]xf32>
+// CHECK: %[[T2:.*]] = builtin.unrealized_conversion_cast %[[T1]] : f32 to vector<1xf32>
+// CHECK: return %[[T2]] : vector<1xf32>
+
+// -----
+
+func.func @extract_scalar_from_vec_1d_index(%arg0: vector<16xindex>) -> index {
+ %0 = vector.extract %arg0[15]: index from vector<16xindex>
+ return %0 : index
+}
+// CHECK-LABEL: @extract_scalar_from_vec_1d_index(
+// CHECK-SAME: %[[A:.*]]: vector<16xindex>)
+// CHECK: %[[T0:.*]] = builtin.unrealized_conversion_cast %[[A]] : vector<16xindex> to vector<16xi64>
+// CHECK: %[[T1:.*]] = llvm.mlir.constant(15 : i64) : i64
+// CHECK: %[[T2:.*]] = llvm.extractelement %[[T0]][%[[T1]] : i64] : vector<16xi64>
+// CHECK: %[[T3:.*]] = builtin.unrealized_conversion_cast %[[T2]] : i64 to index
+// CHECK: return %[[T3]] : index
+
+// -----
+
+func.func @extract_scalar_from_vec_1d_index_scalable(%arg0: vector<[16]xindex>) -> index {
+ %0 = vector.extract %arg0...
[truncated]
|
6eec408
to
2401f2a
Compare
✅ With the latest revision this PR passed the undef deprecator. |
Moving to draft. The CI linter issues are mute as I'm only moving things around, but after re-base there seem to be some new errors as well. |
2401f2a
to
62a9f36
Compare
62a9f36
to
c8e455c
Compare
This is now ready for review. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool!
Following llvm#124308, this patch reorganizes the `vector-to-llvm.mlir` tests by splitting them into two categories: - **Basic conversion tests**: Tests that only require `populateVectorToLLVMConversionPatterns`, focusing on the minimal conversion from Vector to LLVM. These have been moved to `vector-to-llvm-interface.mlir`. - **Full pass tests**: Tests that require the complete `ConvertVectorToLLVMPass`, which includes `populateVectorToLLVMConversionPatterns` along with additional patterns. These remain in `vector-to-llvm.mlir`. This reorganization clarifies test coverage and helps avoid unnecessary duplication.
c8e455c
to
6fcafc3
Compare
…#125918) Following llvm#124308, this patch reorganizes the `vector-to-llvm.mlir` tests by splitting them into two categories: - **Basic conversion tests**: Tests that only require `populateVectorToLLVMConversionPatterns`, focusing on the minimal conversion from Vector to LLVM. These have been moved to `vector-to-llvm-interface.mlir`. - **Full pass tests**: Tests that require the complete `ConvertVectorToLLVMPass`, which includes `populateVectorToLLVMConversionPatterns` along with additional patterns. These remain in `vector-to-llvm.mlir`. This reorganization clarifies test coverage and helps avoid unnecessary duplication. NOTE: This is merely moving tests around between two files and adds some comments.
Following #124308, this patch
reorganizes the
vector-to-llvm.mlir
tests by splitting them into twocategories:
populateVectorToLLVMConversionPatterns
, focusing on the minimalconversion from Vector to LLVM. These have been moved to
vector-to-llvm-interface.mlir
.ConvertVectorToLLVMPass
, which includespopulateVectorToLLVMConversionPatterns
along with additionalpatterns. These remain in
vector-to-llvm.mlir
.This reorganization clarifies test coverage and helps avoid unnecessary
duplication.
NOTE: This is merely moving tests around between two files and adds
some comments.