[MLIR][SPIRVToLLVM] Conversion of SPIR-V struct type without offset

This patch introduces type conversion for SPIR-V structs. Since
handling offset case requires thorough testing, it was left out
for now. Hence, only structs with no offset are currently
supported. Also, structs containing member decorations cannot
be translated.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D83403
This commit is contained in:
George Mitenkov 2020-07-10 00:53:15 +03:00
parent 229dfb4728
commit eb6b7c5d4f
3 changed files with 56 additions and 0 deletions

View File

@ -165,6 +165,17 @@ static Value processCountOrOffset(Location loc, Value value, Type srcType,
return optionallyTruncateOrExtend(loc, broadcasted, dstType, rewriter);
}
/// Converts SPIR-V struct with no offset to packed LLVM struct.
static Type convertStructTypePacked(spirv::StructType type,
LLVMTypeConverter &converter) {
auto elementsVector = llvm::to_vector<8>(
llvm::map_range(type.getElementTypes(), [&](Type elementType) {
return converter.convertType(elementType).cast<LLVM::LLVMType>();
}));
return LLVM::LLVMType::getStructTy(converter.getDialect(), elementsVector,
/*isPacked=*/true);
}
//===----------------------------------------------------------------------===//
// Type conversion
//===----------------------------------------------------------------------===//
@ -202,6 +213,17 @@ static Optional<Type> convertRuntimeArrayType(spirv::RuntimeArrayType type,
return LLVM::LLVMType::getArrayTy(elementType, 0);
}
/// Converts SPIR-V struct to LLVM struct. There is no support of structs with
/// member decorations or with offset.
static Optional<Type> convertStructType(spirv::StructType type,
LLVMTypeConverter &converter) {
SmallVector<spirv::StructType::MemberDecorationInfo, 4> memberDecorations;
type.getMemberDecorations(memberDecorations);
if (type.hasOffset() || !memberDecorations.empty())
return llvm::None;
return convertStructTypePacked(type, converter);
}
//===----------------------------------------------------------------------===//
// Operation conversion
//===----------------------------------------------------------------------===//
@ -711,6 +733,9 @@ void mlir::populateSPIRVToLLVMTypeConversion(LLVMTypeConverter &typeConverter) {
typeConverter.addConversion([&](spirv::RuntimeArrayType type) {
return convertRuntimeArrayType(type, typeConverter);
});
typeConverter.addConversion([&](spirv::StructType type) {
return convertStructType(type, typeConverter);
});
}
void mlir::populateSPIRVToLLVMConversionPatterns(

View File

@ -4,3 +4,24 @@
spv.func @array_with_stride(%arg: !spv.array<4 x f32, stride=4>) -> () "None" {
spv.Return
}
// -----
// expected-error@+1 {{failed to legalize operation 'spv.func' that was explicitly marked illegal}}
spv.func @struct_with_offset1(%arg: !spv.struct<i32[0], i32[4]>) -> () "None" {
spv.Return
}
// -----
// expected-error@+1 {{failed to legalize operation 'spv.func' that was explicitly marked illegal}}
spv.func @struct_with_offset2(%arg: !spv.struct<i32[0], i32[8]>) -> () "None" {
spv.Return
}
// -----
// expected-error@+1 {{failed to legalize operation 'spv.func' that was explicitly marked illegal}}
spv.func @struct_with_decorations(%arg: !spv.struct<f32 [RelaxedPrecision]>) -> () "None" {
spv.Return
}

View File

@ -26,3 +26,13 @@ func @runtime_array_vector(!spv.rtarray< vector<4xf32> >) -> ()
// CHECK-LABEL: @runtime_array_scalar(!llvm<"[0 x float]">)
func @runtime_array_scalar(!spv.rtarray<f32>) -> ()
//===----------------------------------------------------------------------===//
// Struct type
//===----------------------------------------------------------------------===//
// CHECK-LABEL: @struct(!llvm<"<{ double }>">)
func @struct(!spv.struct<f64>) -> ()
// CHECK-LABEL: @struct_nested(!llvm<"<{ i32, <{ i64, i32 }> }>">)
func @struct_nested(!spv.struct<i32, !spv.struct<i64, i32>>)