Add spv.Undef op to support OpUndef instruction in SPIR-V.

Adding support for OpUndef instruction. Updating the dialect
generation script to fix a few bugs in the instruction spec
generation.

PiperOrigin-RevId: 272975685
This commit is contained in:
Mahesh Ravishankar 2019-10-04 15:59:54 -07:00 committed by A. Unique TensorFlower
parent 77a809d7a1
commit 3f8bde40cb
6 changed files with 101 additions and 4 deletions

View File

@ -73,6 +73,7 @@ class SPV_OpCode<string name, int val> {
// Begin opcode section. Generated from SPIR-V spec; DO NOT MODIFY!
def SPV_OC_OpNop : I32EnumAttrCase<"OpNop", 0>;
def SPV_OC_OpUndef : I32EnumAttrCase<"OpUndef", 1>;
def SPV_OC_OpSourceContinued : I32EnumAttrCase<"OpSourceContinued", 2>;
def SPV_OC_OpSource : I32EnumAttrCase<"OpSource", 3>;
def SPV_OC_OpSourceExtension : I32EnumAttrCase<"OpSourceExtension", 4>;
@ -173,7 +174,7 @@ def SPV_OC_OpModuleProcessed : I32EnumAttrCase<"OpModuleProcessed", 330>;
def SPV_OpcodeAttr :
I32EnumAttr<"Opcode", "valid SPIR-V instructions", [
SPV_OC_OpNop, SPV_OC_OpSourceContinued, SPV_OC_OpSource,
SPV_OC_OpNop, SPV_OC_OpUndef, SPV_OC_OpSourceContinued, SPV_OC_OpSource,
SPV_OC_OpSourceExtension, SPV_OC_OpName, SPV_OC_OpMemberName, SPV_OC_OpString,
SPV_OC_OpExtension, SPV_OC_OpExtInstImport, SPV_OC_OpExtInst,
SPV_OC_OpMemoryModel, SPV_OC_OpEntryPoint, SPV_OC_OpExecutionMode,

View File

@ -485,6 +485,41 @@ def SPV_StoreOp : SPV_Op<"Store", []> {
// -----
def SPV_UndefOp : SPV_Op<"Undef", []> {
let summary = "Make an intermediate object whose value is undefined.";
let description = [{
Result Type is the type of object to make.
Each consumption of Result <id> yields an arbitrary, possibly different
bit pattern or abstract value resulting in possibly different concrete,
abstract, or opaque values.
### Custom assembly form
``` {.ebnf}
undef-op ::= `spv.Undef` `:` sprirv-type
```
For example:
```
%0 = spv.Undef : f32
%1 = spv.Undef : !spv.struct<!spv.array<4 x vector<4xi32>>>
```
}];
let arguments = (ins);
let results = (outs
SPV_Type:$result
);
let verifier = [{ return success(); }];
}
// -----
def SPV_VariableOp : SPV_Op<"Variable", []> {
let summary = [{
Allocate an object in memory, resulting in a pointer to it, which can be

View File

@ -2032,6 +2032,23 @@ static LogicalResult verify(spirv::StoreOp storeOp) {
return verifyMemoryAccessAttribute(storeOp);
}
//===----------------------------------------------------------------------===//
// spv.Undef
//===----------------------------------------------------------------------===//
static ParseResult parseUndefOp(OpAsmParser &parser, OperationState &state) {
Type type;
if (parser.parseColonType(type)) {
return failure();
}
state.addTypes(type);
return success();
}
static void print(spirv::UndefOp undefOp, OpAsmPrinter &printer) {
printer << spirv::UndefOp::getOperationName() << " : " << undefOp.getType();
}
//===----------------------------------------------------------------------===//
// spv.Variable
//===----------------------------------------------------------------------===//

View File

@ -0,0 +1,15 @@
// RUN: mlir-translate -test-spirv-roundtrip %s | FileCheck %s
spv.module "Logical" "GLSL450" {
func @foo() -> () {
// CHECK: {{%.*}} = spv.Undef : f32
%0 = spv.Undef : f32
// CHECK: {{%.*}} = spv.Undef : vector<4xi32>
%1 = spv.Undef : vector<4xi32>
// CHECK: {{%.*}} = spv.Undef : !spv.array<4 x !spv.array<4 x i32>>
%2 = spv.Undef : !spv.array<4x!spv.array<4xi32>>
// CHECK: {{%.*}} = spv.Undef : !spv.ptr<!spv.struct<f32>, StorageBuffer>
%3 = spv.Undef : !spv.ptr<!spv.struct<f32>, StorageBuffer>
spv.Return
}
}

View File

@ -967,6 +967,35 @@ spv.module "Logical" "GLSL450" {
// -----
//===----------------------------------------------------------------------===//
// spv.Undef
//===----------------------------------------------------------------------===//
func @undef() -> () {
%0 = spv.Undef : f32
%1 = spv.Undef : vector<4xf32>
spv.Return
}
// -----
func @undef() -> () {
// expected-error @+2{{expected non-function type}}
%0 = spv.Undef :
spv.Return
}
// -----
func @undef() -> () {
// expected-error @+2{{expected ':'}}
%0 = spv.Undef
spv.Return
}
// -----
//===----------------------------------------------------------------------===//
// spv.Variable
//===----------------------------------------------------------------------===//

View File

@ -385,7 +385,7 @@ def get_description(text, assembly):
Returns:
- A string that corresponds to the description of the Tablegen op.
"""
fmt_str = ('{text}\n\n ### Custom assembly ' 'form\n{assembly}}}];\n')
fmt_str = ('{text}\n\n ### Custom assembly ' 'form\n{assembly}\n ')
return fmt_str.format(
text=text, assembly=assembly)
@ -466,8 +466,8 @@ def get_op_definition(instruction, doc, existing_info):
' ```\n\n'\
' For example:\n\n'\
' ```\n'\
' [TODO]\n'\
' ```\n '
' [TODO]\n' \
' ```'
description = get_description(text, assembly)
return fmt_str.format(