diff --git a/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp --- a/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp +++ b/mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp @@ -177,6 +177,14 @@ /*isPacked=*/true); } +/// Creates LLVM dialect constant with the given value. +static Value createI32ConstantOf(Location loc, PatternRewriter &rewriter, + LLVMTypeConverter &converter, unsigned value) { + return rewriter.create( + loc, LLVM::LLVMType::getInt32Ty(converter.getDialect()), + rewriter.getIntegerAttr(rewriter.getI32Type(), value)); +} + //===----------------------------------------------------------------------===// // Type conversion //===----------------------------------------------------------------------===// @@ -733,6 +741,37 @@ } }; +class VariablePattern : public SPIRVToLLVMConversion { +public: + using SPIRVToLLVMConversion::SPIRVToLLVMConversion; + + LogicalResult + matchAndRewrite(spirv::VariableOp varOp, ArrayRef operands, + ConversionPatternRewriter &rewriter) const override { + auto srcType = varOp.getType(); + // Initialization is supported for scalars and vectors only. + auto pointerTo = srcType.cast().getPointeeType(); + auto init = varOp.initializer(); + if (init && !pointerTo.isIntOrFloat() && !pointerTo.isa()) + return failure(); + + auto dstType = typeConverter.convertType(srcType); + if (!dstType) + return failure(); + + Location loc = varOp.getLoc(); + Value size = createI32ConstantOf(loc, rewriter, typeConverter, 1); + if (!init) { + rewriter.replaceOpWithNewOp(varOp, dstType, size); + return success(); + } + Value allocated = rewriter.create(loc, dstType, size); + rewriter.create(loc, init, allocated); + rewriter.replaceOp(varOp, allocated); + return success(); + } +}; + //===----------------------------------------------------------------------===// // FuncOp conversion //===----------------------------------------------------------------------===// @@ -933,6 +972,9 @@ IComparePattern, NotPattern, + // Memory ops + VariablePattern, + // Miscellaneous ops DirectConversionPattern, DirectConversionPattern, diff --git a/mlir/test/Conversion/SPIRVToLLVM/memory-ops-to-llvm.mlir b/mlir/test/Conversion/SPIRVToLLVM/memory-ops-to-llvm.mlir new file mode 100644 --- /dev/null +++ b/mlir/test/Conversion/SPIRVToLLVM/memory-ops-to-llvm.mlir @@ -0,0 +1,49 @@ +// RUN: mlir-opt -convert-spirv-to-llvm %s | FileCheck %s + +//===----------------------------------------------------------------------===// +// spv.Variable +//===----------------------------------------------------------------------===// + +func @variable_scalar() { + // CHECK: %[[SIZE1:.*]] = llvm.mlir.constant(1 : i32) : !llvm.i32 + // CHECK: %{{.*}} = llvm.alloca %[[SIZE1]] x !llvm.float : (!llvm.i32) -> !llvm<"float*"> + %0 = spv.Variable : !spv.ptr + // CHECK: %[[SIZE2:.*]] = llvm.mlir.constant(1 : i32) : !llvm.i32 + // CHECK: %{{.*}} = llvm.alloca %[[SIZE2]] x !llvm.i8 : (!llvm.i32) -> !llvm<"i8*"> + %1 = spv.Variable : !spv.ptr + return +} + +func @variable_scalar_with_initialization() { + // CHECK: %[[VALUE:.*]] = llvm.mlir.constant(0 : i64) : !llvm.i64 + // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : !llvm.i32 + // CHECK: %[[ALLOCATED:.*]] = llvm.alloca %[[SIZE]] x !llvm.i64 : (!llvm.i32) -> !llvm<"i64*"> + // CHECK: llvm.store %[[VALUE]], %[[ALLOCATED]] : !llvm<"i64*"> + %c = spv.constant 0 : i64 + %0 = spv.Variable init(%c) : !spv.ptr + return +} + +func @variable_vector() { + // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : !llvm.i32 + // CHECK: %{{.*}} = llvm.alloca %[[SIZE]] x !llvm<"<3 x float>"> : (!llvm.i32) -> !llvm<"<3 x float>*"> + %0 = spv.Variable : !spv.ptr, Function> + return +} + +func @variable_vector_with_initialization() { + // CHECK: %[[VALUE:.*]] = llvm.mlir.constant(dense : vector<3xi1>) : !llvm<"<3 x i1>"> + // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : !llvm.i32 + // CHECK: %[[ALLOCATED:.*]] = llvm.alloca %[[SIZE]] x !llvm<"<3 x i1>"> : (!llvm.i32) -> !llvm<"<3 x i1>*"> + // CHECK: llvm.store %[[VALUE]], %[[ALLOCATED]] : !llvm<"<3 x i1>*"> + %c = spv.constant dense : vector<3xi1> + %0 = spv.Variable init(%c) : !spv.ptr, Function> + return +} + +func @variable_array() { + // CHECK: %[[SIZE:.*]] = llvm.mlir.constant(1 : i32) : !llvm.i32 + // CHECK: %{{.*}} = llvm.alloca %[[SIZE]] x !llvm<"[10 x i32]"> : (!llvm.i32) -> !llvm<"[10 x i32]*"> + %0 = spv.Variable : !spv.ptr, Function> + return +}