[Mlir-commits] [mlir] 28cd3cb - [MLIR][SPIRVToLLVM] Conversion of SPIR-V array, runtime array, and pointer types
George Mitenkov
llvmlistbot at llvm.org
Thu Jul 9 08:12:24 PDT 2020
Author: George Mitenkov
Date: 2020-07-09T18:11:45+03:00
New Revision: 28cd3cbc12577fa44f9b15c2ffaf9fb1bc280590
URL: https://github.com/llvm/llvm-project/commit/28cd3cbc12577fa44f9b15c2ffaf9fb1bc280590
DIFF: https://github.com/llvm/llvm-project/commit/28cd3cbc12577fa44f9b15c2ffaf9fb1bc280590.diff
LOG: [MLIR][SPIRVToLLVM] Conversion of SPIR-V array, runtime array, and pointer types
This patch adds type conversion for 4 SPIR-V types: array, runtime array, pointer
and struct. This conversion is integrated using a separate function
`populateSPIRVToLLVMTypeConversion()` that adds new type conversions. At the moment,
this is a basic skeleton that allows to perfom conversion from SPIR-V array,
runtime array and pointer types to LLVM typesystem. There is no support of array
strides or storage classes. These will be supported on the case by case basis.
Reviewed By: antiagainst
Differential Revision: https://reviews.llvm.org/D83399
Added:
mlir/test/Conversion/SPIRVToLLVM/spirv-types-to-llvm.invalid.mlir
mlir/test/Conversion/SPIRVToLLVM/spirv-types-to-llvm.mlir
Modified:
mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h
mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp
mlir/test/Conversion/SPIRVToLLVM/cast-ops-to-llvm.mlir
Removed:
################################################################################
diff --git a/mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h b/mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h
index 17537232cc03..4092083f2607 100644
--- a/mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h
+++ b/mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h
@@ -32,6 +32,9 @@ class SPIRVToLLVMConversion : public OpConversionPattern<SPIRVOp> {
LLVMTypeConverter &typeConverter;
};
+/// Populates type conversions with additional SPIR-V types.
+void populateSPIRVToLLVMTypeConversion(LLVMTypeConverter &typeConverter);
+
/// Populates the given list with patterns that convert from SPIR-V to LLVM.
void populateSPIRVToLLVMConversionPatterns(MLIRContext *context,
LLVMTypeConverter &typeConverter,
diff --git a/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
index 6d0028b38ec2..7755656ea3b8 100644
--- a/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
+++ b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
@@ -165,6 +165,43 @@ static Value processCountOrOffset(Location loc, Value value, Type srcType,
return optionallyTruncateOrExtend(loc, broadcasted, dstType, rewriter);
}
+//===----------------------------------------------------------------------===//
+// Type conversion
+//===----------------------------------------------------------------------===//
+
+/// Converts SPIR-V array type to LLVM array. There is no modelling of array
+/// stride at the moment.
+static Optional<Type> convertArrayType(spirv::ArrayType type,
+ TypeConverter &converter) {
+ if (type.getArrayStride() != 0)
+ return llvm::None;
+ auto elementType =
+ converter.convertType(type.getElementType()).cast<LLVM::LLVMType>();
+ unsigned numElements = type.getNumElements();
+ return LLVM::LLVMType::getArrayTy(elementType, numElements);
+}
+
+/// Converts SPIR-V pointer type to LLVM pointer. Pointer's storage class is not
+/// modelled at the moment.
+static Type convertPointerType(spirv::PointerType type,
+ TypeConverter &converter) {
+ auto pointeeType =
+ converter.convertType(type.getPointeeType()).cast<LLVM::LLVMType>();
+ return pointeeType.getPointerTo();
+}
+
+/// Converts SPIR-V runtime array to LLVM array. Since LLVM allows indexing over
+/// the bounds, the runtime array is converted to a 0-sized LLVM array. There is
+/// no modelling of array stride at the moment.
+static Optional<Type> convertRuntimeArrayType(spirv::RuntimeArrayType type,
+ TypeConverter &converter) {
+ if (type.getArrayStride() != 0)
+ return llvm::None;
+ auto elementType =
+ converter.convertType(type.getElementType()).cast<LLVM::LLVMType>();
+ return LLVM::LLVMType::getArrayTy(elementType, 0);
+}
+
//===----------------------------------------------------------------------===//
// Operation conversion
//===----------------------------------------------------------------------===//
@@ -581,6 +618,8 @@ class FuncConversionPattern : public SPIRVToLLVMConversion<spirv::FuncOp> {
funcType.getNumInputs());
auto llvmType = this->typeConverter.convertFunctionSignature(
funcOp.getType(), /*isVariadic=*/false, signatureConverter);
+ if (!llvmType)
+ return failure();
// Create a new `LLVMFuncOp`
Location loc = funcOp.getLoc();
@@ -662,6 +701,18 @@ class ModuleEndConversionPattern
// Pattern population
//===----------------------------------------------------------------------===//
+void mlir::populateSPIRVToLLVMTypeConversion(LLVMTypeConverter &typeConverter) {
+ typeConverter.addConversion([&](spirv::ArrayType type) {
+ return convertArrayType(type, typeConverter);
+ });
+ typeConverter.addConversion([&](spirv::PointerType type) {
+ return convertPointerType(type, typeConverter);
+ });
+ typeConverter.addConversion([&](spirv::RuntimeArrayType type) {
+ return convertRuntimeArrayType(type, typeConverter);
+ });
+}
+
void mlir::populateSPIRVToLLVMConversionPatterns(
MLIRContext *context, LLVMTypeConverter &typeConverter,
OwningRewritePatternList &patterns) {
diff --git a/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp
index c5128782034c..1a806d04d9fc 100644
--- a/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp
+++ b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp
@@ -34,6 +34,9 @@ void ConvertSPIRVToLLVMPass::runOnOperation() {
LLVMTypeConverter converter(&getContext());
OwningRewritePatternList patterns;
+
+ populateSPIRVToLLVMTypeConversion(converter);
+
populateSPIRVToLLVMModuleConversionPatterns(context, converter, patterns);
populateSPIRVToLLVMConversionPatterns(context, converter, patterns);
populateSPIRVToLLVMFunctionConversionPatterns(context, converter, patterns);
diff --git a/mlir/test/Conversion/SPIRVToLLVM/cast-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/cast-ops-to-llvm.mlir
index 0d101f348a9f..29f43fadf933 100644
--- a/mlir/test/Conversion/SPIRVToLLVM/cast-ops-to-llvm.mlir
+++ b/mlir/test/Conversion/SPIRVToLLVM/cast-ops-to-llvm.mlir
@@ -34,6 +34,12 @@ func @bitcast_vector_to_vector(%arg0 : vector<4xf32>) {
return
}
+func @bitcast_pointer(%arg0: !spv.ptr<f32, Function>) {
+ // CHECK: %{{.*}} = llvm.bitcast %{{.*}} : !llvm<"float*"> to !llvm<"i32*">
+ %0 = spv.Bitcast %arg0 : !spv.ptr<f32, Function> to !spv.ptr<i32, Function>
+ return
+}
+
//===----------------------------------------------------------------------===//
// spv.ConvertFToS
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Conversion/SPIRVToLLVM/spirv-types-to-llvm.invalid.mlir b/mlir/test/Conversion/SPIRVToLLVM/spirv-types-to-llvm.invalid.mlir
new file mode 100644
index 000000000000..8115b973507b
--- /dev/null
+++ b/mlir/test/Conversion/SPIRVToLLVM/spirv-types-to-llvm.invalid.mlir
@@ -0,0 +1,6 @@
+// RUN: mlir-opt %s -convert-spirv-to-llvm -verify-diagnostics -split-input-file
+
+// expected-error at +1 {{failed to legalize operation 'spv.func' that was explicitly marked illegal}}
+spv.func @array_with_stride(%arg: !spv.array<4 x f32, stride=4>) -> () "None" {
+ spv.Return
+}
diff --git a/mlir/test/Conversion/SPIRVToLLVM/spirv-types-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/spirv-types-to-llvm.mlir
new file mode 100644
index 000000000000..d2bfdcd4c33d
--- /dev/null
+++ b/mlir/test/Conversion/SPIRVToLLVM/spirv-types-to-llvm.mlir
@@ -0,0 +1,28 @@
+// RUN: mlir-opt -split-input-file -convert-spirv-to-llvm -verify-diagnostics %s | FileCheck %s
+
+//===----------------------------------------------------------------------===//
+// Array type
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @array(!llvm<"[16 x float]">, !llvm<"[32 x <4 x float>]">)
+func @array(!spv.array<16xf32>, !spv.array< 32 x vector<4xf32> >) -> ()
+
+//===----------------------------------------------------------------------===//
+// Pointer type
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @pointer_scalar(!llvm<"i1*">, !llvm<"float*">)
+func @pointer_scalar(!spv.ptr<i1, Uniform>, !spv.ptr<f32, Private>) -> ()
+
+// CHECK-LABEL: @pointer_vector(!llvm<"<4 x i32>*">)
+func @pointer_vector(!spv.ptr<vector<4xi32>, Function>) -> ()
+
+//===----------------------------------------------------------------------===//
+// Runtime array type
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @runtime_array_vector(!llvm<"[0 x <4 x float>]">)
+func @runtime_array_vector(!spv.rtarray< vector<4xf32> >) -> ()
+
+// CHECK-LABEL: @runtime_array_scalar(!llvm<"[0 x float]">)
+func @runtime_array_scalar(!spv.rtarray<f32>) -> ()
More information about the Mlir-commits
mailing list