[llvm-branch-commits] [mlir] 4086072 - Reland "[mlir][linalg] Support parsing attributes in named op spec"

2021-01-12 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-12T10:57:46-05:00
New Revision: 4086072f8a9200216088c435c9aa90a2d8ed74a5

URL: 
https://github.com/llvm/llvm-project/commit/4086072f8a9200216088c435c9aa90a2d8ed74a5
DIFF: 
https://github.com/llvm/llvm-project/commit/4086072f8a9200216088c435c9aa90a2d8ed74a5.diff

LOG: Reland "[mlir][linalg] Support parsing attributes in named op spec"

With this, now we can specify a list of attributes on named ops
generated from the spec. The format is defined as

```
attr-id ::= bare-id (`?`)?
attr-typedef ::= type (`[` `]`)?
attr-def ::= attr-id `:` attr-typedef

tc-attr-def ::= `attr` `(` attr-def-list `)`
tc-def ::= `def` bare-id
  `(`tensor-def-list`)` `->` `(` tensor-def-list`)`
  (tc-attr-def)?
```

For example,

```
ods_def
def some_op(...) -> (...)
attr(
  f32_attr: f32,
  i32_attr: i32,
  array_attr : f32[],
  optional_attr? : f32
)
```

where `?` means optional attribute and `[]` means array type.

Reviewed By: hanchung, nicolasvasilache

Differential Revision: https://reviews.llvm.org/D94240

Added: 


Modified: 
mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp

Removed: 




diff  --git a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc 
b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
index f81380f02bb3..1ef128760637 100644
--- a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
+++ b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
@@ -72,3 +72,25 @@ ods_def :
 def test3(A: f32(Batch, M, K), B: f32(K, N)) -> (C: f32(Batch, M, N)) {
   C(b, m, n) = std_addf(std_mulf(A(b, m, k), B(k, n)));
 }
+
+// Test attribute definitions
+// ODS-LABEL: def Test4Op
+// ODS: F32ArrayAttr:$array_attr,
+// ODS: F32:$f32_attr,
+// ODS: RankedF32ElementsAttr<[4]>:$fvec_attr,
+// ODS: I32:$i32_attr,
+// ODS: RankedI32ElementsAttr<[5, 6]>:$ivec_attr,
+// ODS: OptionalAttr:$optional_attr
+//
+ods_def :
+def test4(A: f32(Batch, M, K), B: f32(K, N)) -> (C: f32(Batch, M, N))
+attr(
+  f32_attr: f32,
+  i32_attr: i32,
+  fvec_attr: 4xf32,
+  ivec_attr: 5x6xi32,
+  array_attr : f32[],
+  optional_attr? : f32
+) {
+  C(b, m, n) = std_addf(std_mulf(A(b, m, k), B(k, n)));
+}

diff  --git a/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp 
b/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
index 592e6cb774fb..138c5a4e904e 100644
--- a/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
+++ b/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
@@ -20,11 +20,17 @@
 #include "mlir/Support/LLVM.h"
 #include "mlir/Support/LogicalResult.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/ToolOutputFile.h"
 
+#include 
+
 #define DEBUG_TYPE "linalg-ods-gen"
 
 static llvm::cl::OptionCategory ODSGenCat("Linalg ODS Gen");
@@ -79,11 +85,14 @@ class Token {
 gt,
 l_brace,
 l_paren,
+l_square,
 lt,
 minus,
 plus,
+question,
 r_brace,
 r_paren,
+r_square,
 semicolon,
 star,
 
@@ -91,6 +100,7 @@ class Token {
 kw_def,
 FIRST_KEYWORD = kw_def,
 kw_ods_def,
+kw_attr_def,
 kw_floordiv,
 kw_ceildiv,
 kw_mod,
@@ -151,6 +161,10 @@ class Lexer {
   Token emitError(llvm::SMLoc loc, const Twine &msg);
   Token emitError(const char *loc, const Twine &msg);
 
+  /// Change the position of the lexer cursor. The next token we lex will start
+  /// at the designated point in the input.
+  void resetPointer(const char *newPtr) { curPtr = newPtr; }
+
 private:
   Token formToken(Token::Kind kind, const char *tokStart) {
 return Token(kind, StringRef(tokStart, curPtr - tokStart));
@@ -247,10 +261,14 @@ Token Lexer::lexToken() {
   return formToken(Token::Kind::l_brace, tokStart);
 case '(':
   return formToken(Token::Kind::l_paren, tokStart);
+case '[':
+  return formToken(Token::Kind::l_square, tokStart);
 case '}':
   return formToken(Token::Kind::r_brace, tokStart);
 case ')':
   return formToken(Token::Kind::r_paren, tokStart);
+case ']':
+  return formToken(Token::Kind::r_square, tokStart);
 case '<':
   return formToken(Token::Kind::lt, tokStart);
 case '>':
@@ -263,6 +281,8 @@ Token Lexer::lexToken() {
   return formToken(Token::Kind::semicolon, tokStart);
 case '*':
   return formToken(Token::Kind::star, tokStart);
+case '?':
+  return formToken(Token::Kind::question, tokStart);
 case '/':
   if (*curPtr == '/') {
 skipComment();
@@ -289,6 +309,7 @@ Token Lexer::lexIdentifier(const char *tokStart) {
   // Check to see if this identifier is a keyword.
   StringRef str(tokStart, curPtr - tokStart);
   Token::Kind kind = S

[llvm-branch-commits] [mlir] 3bc7555 - [mlir][linalg] Use attributes in named ops' indexing maps

2021-01-13 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-13T10:04:49-05:00
New Revision: 3bc7555ffac0a803e44c4b1462e0c4c5eee865ea

URL: 
https://github.com/llvm/llvm-project/commit/3bc7555ffac0a803e44c4b1462e0c4c5eee865ea
DIFF: 
https://github.com/llvm/llvm-project/commit/3bc7555ffac0a803e44c4b1462e0c4c5eee865ea.diff

LOG: [mlir][linalg] Use attributes in named ops' indexing maps

This commit adds support for parsing attribute uses in indexing
maps. These attribute uses are represented as affine symbols in
the resultant indexing maps because we can only know their
concrete value (which are coming from op attributes and are
constants) for specific op instances. The `indxing_maps()`
calls are synthesized to read these attributes and create affine
constants to replace the placeholder affine symbols and simplify.

Depends on D94240

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D94335

Added: 


Modified: 
mlir/docs/Dialects/Linalg.md
mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp

Removed: 




diff  --git a/mlir/docs/Dialects/Linalg.md b/mlir/docs/Dialects/Linalg.md
index 922455dddbda..1f8ef3c4021b 100644
--- a/mlir/docs/Dialects/Linalg.md
+++ b/mlir/docs/Dialects/Linalg.md
@@ -590,6 +590,12 @@ better adapt to Linalg:
 `i` (resp. `j`) is a parallel iterator encoded by affine dimension of
 position `0` (resp. `1`); `k` (resp. `l`) is a reduction iterator encoded 
by
 an affine dimension of position `2` (resp. `3`).
+1.  A list of attributes can be defined for the op with the format of `attr(
+strides: 2xi32)` and referenced in comprehension like `strides[0]`. These
+attribute uses will be parsed as affine symbols to generate op definition
+and implementation. For a concrete op instance, the runtime constant values
+from the attributes will be used to replace the affine symbols and simplify
+the indexing maps.
 
 These decisions and syntax are subject to evolution and change. In particular,
 op-specific attributes, dynamic ranks, some form of templating, shape

diff  --git a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc 
b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
index 1ef128760637..1ce2d2ac9418 100644
--- a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
+++ b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
@@ -10,9 +10,18 @@
 //   IMPL:  { {{.*}}Parallel{{.*}}, {{.*}}Reduction{{.*}} }
 //
 //   IMPL:  ArrayAttr Test1Op::indexing_maps() {
-//   IMPL:  AffineMap::get(2, 0, {d0, d1}, context),
-//  IMPL-NEXT:  AffineMap::get(2, 0, {d1}, context),
-//  IMPL-NEXT:  AffineMap::get(2, 0, {d0}, context) });
+//   IMPL: auto s0 = getAffineSymbolExpr(0, context); (void)s0;
+//  IMPL-NEXT: auto s1 = getAffineSymbolExpr(1, context); (void)s1;
+//  IMPL-NEXT: auto map0 = AffineMap::get(2, 2, {d0, d1}, context);
+//  IMPL-NEXT: map0 = map0.replaceDimsAndSymbols({}, { s0, s1 }, 2, 0);
+//  IMPL-NEXT: map0 = simplifyAffineMap(map0);
+//  IMPL-NEXT: auto map1 = AffineMap::get(2, 2, {d1}, context);
+//  IMPL-NEXT: map1 = map1.replaceDimsAndSymbols({}, { s0, s1 }, 2, 0);
+//  IMPL-NEXT: map1 = simplifyAffineMap(map1);
+//  IMPL-NEXT: auto map2 = AffineMap::get(2, 2, {d0}, context);
+//  IMPL-NEXT: map2 = map2.replaceDimsAndSymbols({}, { s0, s1 }, 2, 0);
+//  IMPL-NEXT: map2 = simplifyAffineMap(map2);
+//  IMPL-NEXT: return {{.+}}.getAffineMapArrayAttr({ map0, map1, map2 });
 //
 //   IMPL:  void Test1Op::regionBuilder(Block &block) {
 //   IMPL:  Value [[a:.*]](args[0]), [[b:.*]](args[1]), [[c:.*]](args[2]);
@@ -34,9 +43,9 @@ def test1(A: f32(M, K), B: f32(K)) -> (C: f32(M)) {
 //   IMPL:  { {{.*}}Parallel{{.*}}, {{.*}}Parallel{{.*}}, 
{{.*}}Reduction{{.*}} }
 //
 //   IMPL:  ArrayAttr Test2Op::indexing_maps() {
-//   IMPL:  AffineMap::get(3, 0, {d0, d2}, context),
-//  IMPL-NEXT:  AffineMap::get(3, 0, {d2, d1}, context),
-//  IMPL-NEXT:  AffineMap::get(3, 0, {d0, d1}, context) });
+//   IMPL:  AffineMap::get(3, 3, {d0, d2}, context)
+//   IMPL:  AffineMap::get(3, 3, {d2, d1}, context)
+//   IMPL:  AffineMap::get(3, 3, {d0, d1}, context)
 //
 //   IMPL:  Test2Op::regionBuilder(Block &block) {
 //   IMPL:  Value [[a:.*]](args[0]), [[b:.*]](args[1]), [[c:.*]](args[2]);
@@ -58,9 +67,9 @@ def test2(A: f32(M, K), B: f32(K, N)) -> (C: f32(M, N)) {
 //   IMPL:  { {{.*}}Parallel{{.*}}, {{.*}}Parallel{{.*}}, 
{{.*}}Reduction{{.*}} }
 //
 //   IMPL:  ArrayAttr Test3Op::indexing_maps() {
-//   IMPL:  AffineMap::get(4, 0, {d0, d1, d3}, context),
-//  IMPL-NEXT:  AffineMap::get(4, 0, {d3, d2}, context),
-//  IMPL-NEXT:  AffineMap::get(4, 0, {d0, d1, d2}, context) });
+//   IMPL:  AffineMap::get(4, 4, {d0, d1, d3}, context)
+//   IMPL:  AffineMap::get(4, 4, {d3, d2}, context)
+//   IMPL:  AffineMap::get(4, 4, {d0, d1, d2}, context)
 //

[llvm-branch-commits] [mlir] 6b9fa8a - [mlir][linalg] Add docstring support for named op spec

2021-01-14 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-14T09:57:56-05:00
New Revision: 6b9fa8a50d0f9e1e54f238b1c50fee8ff7011218

URL: 
https://github.com/llvm/llvm-project/commit/6b9fa8a50d0f9e1e54f238b1c50fee8ff7011218
DIFF: 
https://github.com/llvm/llvm-project/commit/6b9fa8a50d0f9e1e54f238b1c50fee8ff7011218.diff

LOG: [mlir][linalg] Add docstring support for named op spec

Depends on D94335

Reviewed By: nicolasvasilache, hanchung

Differential Revision: https://reviews.llvm.org/D94548

Added: 


Modified: 
mlir/docs/Dialects/Linalg.md
mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp

Removed: 




diff  --git a/mlir/docs/Dialects/Linalg.md b/mlir/docs/Dialects/Linalg.md
index 1f8ef3c4021b..a5caabd212b4 100644
--- a/mlir/docs/Dialects/Linalg.md
+++ b/mlir/docs/Dialects/Linalg.md
@@ -608,10 +608,18 @@ semantics:
 perform multiple updates.
 2.  Each tensor may only be used with a single indexing expression.
 
+A `"""`-wrapped doc string can be attached to the named op. It should contain a
+oneliner for summary first, followed by lengthy description.
+
 The following specification may be used to define a named `batchmatmul` op:
 
 ```
-def batchmatmul(A: f32(Batch, M, K), B: f32(K, N)) -> (C: f32(Batch, M, N)) {
+def batchmatmul(A: f32(Batch, M, K), B: f32(K, N)) -> (C: f32(Batch, M, N))
+"""Batch matrix-multiply operation.
+
+This operation performs batch matrix-multiply over ...
+"""
+{
   C(b, m, n) = std_addf(std_mulf(A(b, m, k), B(k, n)));
 }
 ```

diff  --git a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc 
b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
index 1ce2d2ac9418..226a09669b1c 100644
--- a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
+++ b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
@@ -125,3 +125,22 @@ def test5(I: f32(N, H, W, C), K: f32(F, KH, KW, C)) -> (O: 
f32(N, H, W, F))
   O(n, h, w, f) = std_addf(std_mulf(
 I(n, h * strides[0] + kh, w * strides[1] + kw, c), K(f, kh, kw, c)));
 }
+
+// ODS-LABEL: def Test6Op
+// ODS:   let summary = [{ My magic op. }];
+// ODS-NEXT:  let description = [{
+// ODS-NEXT:It has two inputs.
+// ODS-NEXT:It has one output.
+// ODS-NEXT:  }];
+//
+ods_def:
+def test6(A: f32(M, K), B: f32(K)) -> (C: f32(M))
+"""
+My magic op.
+
+It has two inputs.
+It has one output.
+"""
+{
+  C(m) = std_addf(std_mulf(A(m, k), B(k)));
+}

diff  --git a/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp 
b/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
index cb7bfd2c9c4d..f4b7f9f9323a 100644
--- a/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
+++ b/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
@@ -30,6 +30,7 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/ToolOutputFile.h"
 
@@ -85,6 +86,7 @@ class Token {
 // Tokens with no info.
 colon,
 comma,
+doc_str,
 equal,
 gt,
 l_brace,
@@ -183,6 +185,9 @@ class Lexer {
   // Lex an integer.
   Token lexInteger(const char *tokStart);
 
+  // Lex a string.
+  Token lexString(const char *tokStart);
+
   // Skip a comment line, starting with a '//'.
   void skipComment();
 
@@ -287,6 +292,8 @@ Token Lexer::lexToken() {
   return formToken(Token::Kind::star, tokStart);
 case '?':
   return formToken(Token::Kind::question, tokStart);
+case '"':
+  return lexString(tokStart);
 case '/':
   if (*curPtr == '/') {
 skipComment();
@@ -333,6 +340,36 @@ Token Lexer::lexInteger(const char *tokStart) {
   return Token(Token::Kind::integer, str);
 }
 
+Token Lexer::lexString(const char *tokStart) {
+  assert(curPtr[-1] == '"');
+
+  if (*curPtr == '"' && *(curPtr + 1) == '"') {
+curPtr += 2;
+while (true) {
+  switch (*curPtr++) {
+  case '"':
+if (*curPtr == '"' && *(curPtr + 1) == '"') {
+  Token token(Token::Kind::doc_str,
+  StringRef(tokStart + 3, curPtr - tokStart - 4));
+  curPtr += 2;
+  return token;
+}
+continue;
+  case 0:
+// If this is a random nul character in the middle of the doc string,
+// just include it.  If it is the end of file, then it is an error.
+if (curPtr - 1 != curBuffer.end())
+  continue;
+return emitError(curPtr - 1, "expected '\"\"\"' to end doc string");
+  default:
+continue;
+  }
+}
+  }
+
+  return emitError(curPtr - 1, "expected '\"\"\"' to start doc string");
+}
+
 /// Skip a comment line, starting with a '//'.
 void Lexer::skipComment() {
   // Advance over the second '/' in a '//' comment.
@@ -1134,6 +1171,8 @@ class TCParser {
   /// Attributes are per TC def.
   std::map registeredAttrs;
 
+  StringRef docString;
+
   Parser &p

[llvm-branch-commits] [mlir] 0acc260 - [mlir][linalg] Support generating builders for named op attributes

2021-01-15 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-15T09:00:30-05:00
New Revision: 0acc260b574e28f5247e8ad4d8c9805b8005c841

URL: 
https://github.com/llvm/llvm-project/commit/0acc260b574e28f5247e8ad4d8c9805b8005c841
DIFF: 
https://github.com/llvm/llvm-project/commit/0acc260b574e28f5247e8ad4d8c9805b8005c841.diff

LOG: [mlir][linalg] Support generating builders for named op attributes

This commit adds support to generate an additional builder for
each named op that has attributes. This gives better experience
when creating the named ops.

Along the way adds support for i64.

Reviewed By: hanchung

Differential Revision: https://reviews.llvm.org/D94733

Added: 


Modified: 
mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp

Removed: 




diff  --git a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc 
b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
index 226a09669b1c..9bd6152f07da 100644
--- a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
+++ b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
@@ -88,6 +88,7 @@ def test3(A: f32(Batch, M, K), B: f32(K, N)) -> (C: 
f32(Batch, M, N)) {
 // ODS: F32:$f32_attr,
 // ODS: RankedF32ElementsAttr<[4]>:$fvec_attr,
 // ODS: I32:$i32_attr,
+// ODS: I64:$i64_attr,
 // ODS: RankedI32ElementsAttr<[5, 6]>:$ivec_attr,
 // ODS: OptionalAttr:$optional_attr
 //
@@ -96,6 +97,7 @@ def test4(A: f32(Batch, M, K), B: f32(K, N)) -> (C: 
f32(Batch, M, N))
 attr(
   f32_attr: f32,
   i32_attr: i32,
+  i64_attr: i64,
   fvec_attr: 4xf32,
   ivec_attr: 5x6xi32,
   array_attr : f32[],
@@ -126,6 +128,7 @@ def test5(I: f32(N, H, W, C), K: f32(F, KH, KW, C)) -> (O: 
f32(N, H, W, F))
 I(n, h * strides[0] + kh, w * strides[1] + kw, c), K(f, kh, kw, c)));
 }
 
+// Test documentation
 // ODS-LABEL: def Test6Op
 // ODS:   let summary = [{ My magic op. }];
 // ODS-NEXT:  let description = [{
@@ -144,3 +147,18 @@ It has one output.
 {
   C(m) = std_addf(std_mulf(A(m, k), B(k)));
 }
+
+// Test attribute builder
+// ODS-LABEL: def Test7Op
+// ODS: OpBuilderDAG<
+// ODS:   (ins "TypeRange":$resultTensorTypes, "ValueRange":$inputs,
+// ODS:"ValueRange":$outputs, "Attribute":$attr_a, 
"Attribute":$attr_b)
+// ODS:   $_state.addAttribute("attr_a", attr_a);
+// ODS:   $_state.addAttribute("attr_b", attr_b);
+//
+ods_def:
+def test7(A: f32(M, K), B: f32(K)) -> (C: f32(M))
+ attr(attr_a: f32, attr_b: 4xi32)
+{
+  C(m) = std_addf(std_mulf(A(m, k), B(k)));
+}

diff  --git a/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp 
b/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
index f4b7f9f9323a..47841c840fe5 100644
--- a/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
+++ b/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
@@ -1768,6 +1768,7 @@ void TCParser::printODS(llvm::raw_ostream &os, StringRef 
cppOpName,
 std::string odsType = llvm::StringSwitch(elementType)
   .Case("f32", "F32")
   .Case("i32", "I32")
+  .Case("i64", "I64")
   .Default("");
 if (odsType.empty()) {
   parser.emitError("unimplemented support for attribute element type: " +
@@ -1811,7 +1812,8 @@ void TCParser::printODS(llvm::raw_ostream &os, StringRef 
cppOpName,
   let regions = (region AnyRegion:$region);
 
   let skipDefaultBuilders = 1;
-  let builders = [ OpBuilderDAG<
+  let builders = [
+OpBuilderDAG<
 (ins "ValueRange":$inputs, "ValueRange":$outputs),
 [{{
   $_state.addOperands(inputs);
@@ -1826,7 +1828,8 @@ void TCParser::printODS(llvm::raw_ostream &os, StringRef 
cppOpName,
 $_state,
 TypeRange(inputs),
 TypeRange(outputs));
-}]>, OpBuilderDAG<
+}]>,
+OpBuilderDAG<
 (ins "TypeRange":$resultTensorTypes, "ValueRange":$inputs,
  "ValueRange":$outputs),
 [{{
@@ -1843,7 +1846,8 @@ void TCParser::printODS(llvm::raw_ostream &os, StringRef 
cppOpName,
 $_state,
 TypeRange(inputs),
 TypeRange(outputs));
-}]>, OpBuilderDAG<
+}]>,
+OpBuilderDAG<
 (ins "TypeRange":$resultTensorTypes, "ValueRange":$operands,
  CArg<"ArrayRef", "{{}">:$attributes),
 [{{
@@ -1852,6 +1856,7 @@ void TCParser::printODS(llvm::raw_ostream &os, StringRef 
cppOpName,
   $_state.addTypes(resultTensorTypes);
   (void)$_state.addRegion();
 }]>
+{5}
   ];
   let printer = [{{ return ::printNamedStructuredOp(p, *this); }];
   let parser = [{{ return ::parseNamedStructuredOp<{0}>(parser, result); 
}];
@@ -1873,8 +1878,8 @@ void TCParser::printODS(llvm::raw_ostream &os, StringRef 
cppOpName,
   }];
   })FMT";
 
+  // Generate documentation.
   std::strin

[llvm-branch-commits] [mlir] 3a56a96 - [mlir][spirv] Define spv.GLSL.Fma and add lowerings

2021-01-19 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-19T09:14:21-05:00
New Revision: 3a56a96664de955888d63c49a33808e3a1a294d9

URL: 
https://github.com/llvm/llvm-project/commit/3a56a96664de955888d63c49a33808e3a1a294d9
DIFF: 
https://github.com/llvm/llvm-project/commit/3a56a96664de955888d63c49a33808e3a1a294d9.diff

LOG: [mlir][spirv] Define spv.GLSL.Fma and add lowerings

Also changes some rewriter.create + rewriter.replaceOp calls
into rewriter.replaceOpWithNewOp calls.

Reviewed By: hanchung

Differential Revision: https://reviews.llvm.org/D94965

Added: 


Modified: 
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
mlir/lib/Conversion/VectorToSPIRV/VectorToSPIRV.cpp
mlir/test/Conversion/VectorToSPIRV/simple.mlir
mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir
mlir/test/Target/SPIRV/glsl-ops.mlir

Removed: 




diff  --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td 
b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
index a566b7503a15..c34cd98dbb39 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
@@ -972,4 +972,44 @@ def SPV_GLSLSClampOp : 
SPV_GLSLTernaryArithmeticOp<"SClamp", 45, SPV_SignedInt>
   }];
 }
 
+// -
+
+def SPV_GLSLFmaOp : SPV_GLSLTernaryArithmeticOp<"Fma", 50, SPV_Float> {
+  let summary = "Computes a * b + c.";
+
+  let description = [{
+In uses where this operation is decorated with NoContraction:
+
+- fma is considered a single operation, whereas the expression a * b + c
+  is considered two operations.
+- The precision of fma can 
diff er from the precision of the expression
+  a * b + c.
+- fma will be computed with the same precision as any other fma decorated
+  with NoContraction, giving invariant results for the same input values
+  of a, b, and c.
+
+Otherwise, in the absence of a NoContraction decoration, there are no
+special constraints on the number of operations or 
diff erence in precision
+between fma and the expression a * b +c.
+
+The operands must all be a scalar or vector whose component type is
+floating-point.
+
+Result Type and the type of all operands must be the same type. Results
+are computed per component.
+
+
+```
+fma-op ::= ssa-id `=` `spv.GLSL.Fma` ssa-use, ssa-use, ssa-use `:`
+   float-scalar-vector-type
+```
+ Example:
+
+```mlir
+%0 = spv.GLSL.Fma %a, %b, %c : f32
+%1 = spv.GLSL.Fma %a, %b, %c : vector<3xf16>
+```
+  }];
+}
+
 #endif // MLIR_DIALECT_SPIRV_IR_GLSL_OPS

diff  --git a/mlir/lib/Conversion/VectorToSPIRV/VectorToSPIRV.cpp 
b/mlir/lib/Conversion/VectorToSPIRV/VectorToSPIRV.cpp
index 1509836ef2e2..52a35a17869f 100644
--- a/mlir/lib/Conversion/VectorToSPIRV/VectorToSPIRV.cpp
+++ b/mlir/lib/Conversion/VectorToSPIRV/VectorToSPIRV.cpp
@@ -36,9 +36,8 @@ struct VectorBroadcastConvert final
 vector::BroadcastOp::Adaptor adaptor(operands);
 SmallVector source(broadcastOp.getVectorType().getNumElements(),
  adaptor.source());
-Value construct = rewriter.create(
-broadcastOp.getLoc(), broadcastOp.getVectorType(), source);
-rewriter.replaceOp(broadcastOp, construct);
+rewriter.replaceOpWithNewOp(
+broadcastOp, broadcastOp.getVectorType(), source);
 return success();
   }
 };
@@ -55,9 +54,23 @@ struct VectorExtractOpConvert final
   return failure();
 vector::ExtractOp::Adaptor adaptor(operands);
 int32_t id = extractOp.position().begin()->cast().getInt();
-Value newExtract = rewriter.create(
-extractOp.getLoc(), adaptor.vector(), id);
-rewriter.replaceOp(extractOp, newExtract);
+rewriter.replaceOpWithNewOp(
+extractOp, adaptor.vector(), id);
+return success();
+  }
+};
+
+struct VectorFmaOpConvert final : public OpConversionPattern {
+  using OpConversionPattern::OpConversionPattern;
+
+  LogicalResult
+  matchAndRewrite(vector::FMAOp fmaOp, ArrayRef operands,
+  ConversionPatternRewriter &rewriter) const override {
+if (!spirv::CompositeType::isValid(fmaOp.getVectorType()))
+  return failure();
+vector::FMAOp::Adaptor adaptor(operands);
+rewriter.replaceOpWithNewOp(
+fmaOp, fmaOp.getType(), adaptor.lhs(), adaptor.rhs(), adaptor.acc());
 return success();
   }
 };
@@ -74,9 +87,8 @@ struct VectorInsertOpConvert final
   return failure();
 vector::InsertOp::Adaptor adaptor(operands);
 int32_t id = insertOp.position().begin()->cast().getInt();
-Value newInsert = rewriter.create(
-insertOp.getLoc(), adaptor.source(), adaptor.dest(), id);
-rewriter.replaceOp(insertOp, newInsert);
+rewriter.replaceOpWithNewOp(
+insertOp, adaptor.source(), adaptor.dest(), id);
 return success();
   }
 };
@@ -92,10 +104,9 @@ struct VectorExtractElementOpConvert final
 if (!spirv::CompositeType::isVa

[llvm-branch-commits] [mlir] 167fb9b - [mlir][spirv] Fix script for availability autogen and refresh ops

2021-01-22 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-22T13:07:36-05:00
New Revision: 167fb9b4b4352cdea92ccfdfb205c7ed4470d3ef

URL: 
https://github.com/llvm/llvm-project/commit/167fb9b4b4352cdea92ccfdfb205c7ed4470d3ef
DIFF: 
https://github.com/llvm/llvm-project/commit/167fb9b4b4352cdea92ccfdfb205c7ed4470d3ef.diff

LOG: [mlir][spirv] Fix script for availability autogen and refresh ops

Previously we only autogen the availability for ops that are
direct instantiating `SPV_Op` and expected other subclasses of
`SPV_Op` to define aggregated availability for all ops. This is
quite error prone and we can miss capabilities for certain ops.
Also it's arguable to have multiple levels of subclasses and try
to deduplicate too much: having the availability directly in the
op can be quite explicit and clear. A few extra lines of
declarative code is fine.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D95236

Added: 


Modified: 
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBitOps.td
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVCompositeOps.td
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGroupOps.td
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMatrixOps.td
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVMemoryOps.td
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVNonUniformOps.td
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVStructureOps.td
mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir
mlir/utils/spirv/gen_spirv_dialect.py

Removed: 




diff  --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBitOps.td 
b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBitOps.td
index 5e3bf0b9eccd..c495650c77f1 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBitOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBitOps.td
@@ -92,13 +92,6 @@ def SPV_BitCountOp : SPV_BitUnaryOp<"BitCount", []> {
 %3 = spv.BitCount %1: vector<4xi32>
 ```
   }];
-
-  let availability = [
-MinVersion,
-MaxVersion,
-Extension<[]>,
-Capability<[]>
-  ];
 }
 
 // -
@@ -341,13 +334,6 @@ def SPV_BitwiseAndOp : SPV_BitBinaryOp<"BitwiseAnd",
 %2 = spv.BitwiseAnd %0, %1 : vector<4xi32>
 ```
   }];
-
-  let availability = [
-MinVersion,
-MaxVersion,
-Extension<[]>,
-Capability<[]>
-  ];
 }
 
 // -
@@ -383,13 +369,6 @@ def SPV_BitwiseOrOp : SPV_BitBinaryOp<"BitwiseOr",
 %2 = spv.BitwiseOr %0, %1 : vector<4xi32>
 ```
   }];
-
-  let availability = [
-MinVersion,
-MaxVersion,
-Extension<[]>,
-Capability<[]>
-  ];
 }
 
 // -
@@ -425,13 +404,6 @@ def SPV_BitwiseXorOp : SPV_BitBinaryOp<"BitwiseXor",
 %2 = spv.BitwiseXor %0, %1 : vector<4xi32>
 ```
   }];
-
-  let availability = [
-MinVersion,
-MaxVersion,
-Extension<[]>,
-Capability<[]>
-  ];
 }
 
 // -
@@ -440,7 +412,7 @@ def SPV_ShiftLeftLogicalOp : SPV_ShiftOp<"ShiftLeftLogical",
  [UsableInSpecConstantOp]> {
   let summary = [{
 Shift the bits in Base left by the number of bits specified in Shift.
-The least-significant bits will be zero filled.
+The least-significant bits are zero filled.
   }];
 
   let description = [{
@@ -477,13 +449,6 @@ def SPV_ShiftLeftLogicalOp : 
SPV_ShiftOp<"ShiftLeftLogical",
 %5 = spv.ShiftLeftLogical %3, %4 : vector<3xi32>, vector<3xi16>
 ```
   }];
-
-  let availability = [
-MinVersion,
-MaxVersion,
-Extension<[]>,
-Capability<[]>
-  ];
 }
 
 // -
@@ -492,7 +457,7 @@ def SPV_ShiftRightArithmeticOp : 
SPV_ShiftOp<"ShiftRightArithmetic",
  [UsableInSpecConstantOp]> {
   let summary = [{
 Shift the bits in Base right by the number of bits specified in Shift.
-The most-significant bits will be filled with the sign bit from Base.
+The most-significant bits are filled with the sign bit from Base.
   }];
 
   let description = [{
@@ -526,13 +491,6 @@ def SPV_ShiftRightArithmeticOp : 
SPV_ShiftOp<"ShiftRightArithmetic",
 %5 = spv.ShiftRightArithmetic %3, %4 : vector<3xi32>, vector<3xi16>
 ```
   }];
-
-  let availability = [
-MinVersion,
-MaxVersion,
-Extension<[]>,
-Capability<[]>
-  ];
 }
 
 // -
@@ -541,7 +499,7 @@ def SPV_ShiftRightLogicalOp : 
SPV_ShiftOp<"ShiftRightLogical",
   [UsableInSpecConstantOp]> {
   let summary = [{
 Shift the bits in Base right by the number of bits specified in Shift.
-The most-significant bits will be zero filled.
+The most-significant bits are zero filled.
   }];
 
   let description = [{
@@ -576,13 +534,6 @@ def SPV_ShiftRightLogicalOp : 
SPV_ShiftOp<"ShiftRightLogical",
 %5 = spv.ShiftRightLogical %3, %4 : vector<3xi32>, vector<3xi16>
 ```
   }];
-
-  let availability = [
-MinVersion,
-MaxVersion,
-Extension<[]>,
-Capability<[]>
-  ];
 }
 
 // -
@@ -595,7 

[llvm-branch-commits] [mlir] e27197f - [mlir][spirv] Define spv.IsNan/spv.IsInf and add lowerings

2021-01-22 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-22T13:09:33-05:00
New Revision: e27197f3605450c372ddc71922d0e9982b30e115

URL: 
https://github.com/llvm/llvm-project/commit/e27197f3605450c372ddc71922d0e9982b30e115
DIFF: 
https://github.com/llvm/llvm-project/commit/e27197f3605450c372ddc71922d0e9982b30e115.diff

LOG: [mlir][spirv] Define spv.IsNan/spv.IsInf and add lowerings

spv.Ordered/spv.Unordered are meant for OpenCL Kernel capability.
For Vulkan Shader capability, we should use spv.IsNan to check
whether a number is NaN.

Add a new pattern for converting `std.cmpf ord|uno` to spv.IsNan
and bumped the pattern converting to spv.Ordered/spv.Unordered
to a higher benefit. The SPIR-V target environment will properly
select between these two patterns.

Reviewed By: mravishankar

Differential Revision: https://reviews.llvm.org/D95237

Added: 


Modified: 
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
mlir/include/mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td
mlir/lib/Conversion/StandardToSPIRV/StandardToSPIRV.cpp
mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir
mlir/test/Dialect/SPIRV/IR/logical-ops.mlir
mlir/test/Target/SPIRV/logical-ops.mlir

Removed: 




diff  --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td 
b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
index c369304cf18b..347b65a7739e 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
@@ -3216,6 +3216,8 @@ def SPV_OC_OpFRem  : 
I32EnumAttrCase<"OpFRem", 140>;
 def SPV_OC_OpFMod  : I32EnumAttrCase<"OpFMod", 141>;
 def SPV_OC_OpMatrixTimesScalar : 
I32EnumAttrCase<"OpMatrixTimesScalar", 143>;
 def SPV_OC_OpMatrixTimesMatrix : 
I32EnumAttrCase<"OpMatrixTimesMatrix", 146>;
+def SPV_OC_OpIsNan : I32EnumAttrCase<"OpIsNan", 156>;
+def SPV_OC_OpIsInf : I32EnumAttrCase<"OpIsInf", 157>;
 def SPV_OC_OpOrdered   : I32EnumAttrCase<"OpOrdered", 162>;
 def SPV_OC_OpUnordered : I32EnumAttrCase<"OpUnordered", 163>;
 def SPV_OC_OpLogicalEqual  : I32EnumAttrCase<"OpLogicalEqual", 
164>;
@@ -3332,15 +3334,15 @@ def SPV_OpcodeAttr :
   SPV_OC_OpISub, SPV_OC_OpFSub, SPV_OC_OpIMul, SPV_OC_OpFMul, 
SPV_OC_OpUDiv,
   SPV_OC_OpSDiv, SPV_OC_OpFDiv, SPV_OC_OpUMod, SPV_OC_OpSRem, 
SPV_OC_OpSMod,
   SPV_OC_OpFRem, SPV_OC_OpFMod, SPV_OC_OpMatrixTimesScalar,
-  SPV_OC_OpMatrixTimesMatrix, SPV_OC_OpOrdered, SPV_OC_OpUnordered,
-  SPV_OC_OpLogicalEqual, SPV_OC_OpLogicalNotEqual, SPV_OC_OpLogicalOr,
-  SPV_OC_OpLogicalAnd, SPV_OC_OpLogicalNot, SPV_OC_OpSelect, 
SPV_OC_OpIEqual,
-  SPV_OC_OpINotEqual, SPV_OC_OpUGreaterThan, SPV_OC_OpSGreaterThan,
-  SPV_OC_OpUGreaterThanEqual, SPV_OC_OpSGreaterThanEqual, 
SPV_OC_OpULessThan,
-  SPV_OC_OpSLessThan, SPV_OC_OpULessThanEqual, SPV_OC_OpSLessThanEqual,
-  SPV_OC_OpFOrdEqual, SPV_OC_OpFUnordEqual, SPV_OC_OpFOrdNotEqual,
-  SPV_OC_OpFUnordNotEqual, SPV_OC_OpFOrdLessThan, SPV_OC_OpFUnordLessThan,
-  SPV_OC_OpFOrdGreaterThan, SPV_OC_OpFUnordGreaterThan,
+  SPV_OC_OpMatrixTimesMatrix, SPV_OC_OpIsNan, SPV_OC_OpIsInf, 
SPV_OC_OpOrdered,
+  SPV_OC_OpUnordered, SPV_OC_OpLogicalEqual, SPV_OC_OpLogicalNotEqual,
+  SPV_OC_OpLogicalOr, SPV_OC_OpLogicalAnd, SPV_OC_OpLogicalNot, 
SPV_OC_OpSelect,
+  SPV_OC_OpIEqual, SPV_OC_OpINotEqual, SPV_OC_OpUGreaterThan,
+  SPV_OC_OpSGreaterThan, SPV_OC_OpUGreaterThanEqual, 
SPV_OC_OpSGreaterThanEqual,
+  SPV_OC_OpULessThan, SPV_OC_OpSLessThan, SPV_OC_OpULessThanEqual,
+  SPV_OC_OpSLessThanEqual, SPV_OC_OpFOrdEqual, SPV_OC_OpFUnordEqual,
+  SPV_OC_OpFOrdNotEqual, SPV_OC_OpFUnordNotEqual, SPV_OC_OpFOrdLessThan,
+  SPV_OC_OpFUnordLessThan, SPV_OC_OpFOrdGreaterThan, 
SPV_OC_OpFUnordGreaterThan,
   SPV_OC_OpFOrdLessThanEqual, SPV_OC_OpFUnordLessThanEqual,
   SPV_OC_OpFOrdGreaterThanEqual, SPV_OC_OpFUnordGreaterThanEqual,
   SPV_OC_OpShiftRightLogical, SPV_OC_OpShiftRightArithmetic,

diff  --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td 
b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td
index 0516e70f87c4..019b63f3a582 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVLogicalOps.td
@@ -41,6 +41,11 @@ class SPV_LogicalUnaryOp {
   let parser = [{ return ::parseLogicalUnaryOp(parser, result); }];
   let printer = [{ return ::printLogicalOp(getOperation(), p); }];
+
+  let builders = [
+OpBuilderDAG<(ins "Value":$value),
+[{::buildLogicalUnaryOp($_builder, $_state, value);}]>
+  ];
 }
 
 // -
@@ -507,6 +512,70 @@ def SPV_INotEqualOp : SPV_LogicalBinaryOp<"INotEqual",
 
 // -
 
+def SPV_IsInfOp : SPV_LogicalUnaryOp<"IsInf", SPV_Float, []> {
+  let summary = "Result is true if x is an I

[llvm-branch-commits] [mlir] 25c78de - [mlir][spirv] Update pass docs

2021-01-06 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-06T10:28:55-05:00
New Revision: 25c78de6d2a50d6f90fd6cd3f0010eb3df157a6c

URL: 
https://github.com/llvm/llvm-project/commit/25c78de6d2a50d6f90fd6cd3f0010eb3df157a6c
DIFF: 
https://github.com/llvm/llvm-project/commit/25c78de6d2a50d6f90fd6cd3f0010eb3df157a6c.diff

LOG: [mlir][spirv] Update pass docs

Reviewed By: hanchung

Differential Revision: https://reviews.llvm.org/D94174

Added: 


Modified: 
mlir/include/mlir/Conversion/Passes.td

Removed: 




diff  --git a/mlir/include/mlir/Conversion/Passes.td 
b/mlir/include/mlir/Conversion/Passes.td
index 2dc438534a44..6a6ba6bbb371 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -144,6 +144,18 @@ def ConvertGpuOpsToROCDLOps : Pass<"convert-gpu-to-rocdl", 
"gpu::GPUModuleOp"> {
 
 def ConvertGPUToSPIRV : Pass<"convert-gpu-to-spirv", "ModuleOp"> {
   let summary = "Convert GPU dialect to SPIR-V dialect";
+  let description = [{
+This pass converts supported GPU device ops to SPIR-V ops. It does not
+handle GPU host ops.
+
+A `gpu.func` op can have parameters to pass in resources. But in SPIR-V
+entry functions cannot take parameters; they use descriptors to access
+resources. By default, parameters to a `gpu.func` op will be converted to
+global variables. These global variables will be assigned sequential 
binding
+numbers following their order in the original `gpu.func` op, starting from
+0, in set 0. One can attach `spv.interface_var_abi` to those parameters
+to control the set and binding if wanted.
+  }];
   let constructor = "mlir::createConvertGPUToSPIRVPass()";
   let dependentDialects = ["spirv::SPIRVDialect"];
 }
@@ -155,6 +167,9 @@ def ConvertGPUToSPIRV : Pass<"convert-gpu-to-spirv", 
"ModuleOp"> {
 def ConvertGpuLaunchFuncToVulkanLaunchFunc
 : Pass<"convert-gpu-launch-to-vulkan-launch", "ModuleOp"> {
   let summary = "Convert gpu.launch_func to vulkanLaunch external call";
+  let description = [{
+This pass is only intended for the mlir-vulkan-runner.
+  }];
   let constructor = "mlir::createConvertGpuLaunchFuncToVulkanLaunchFuncPass()";
   let dependentDialects = ["spirv::SPIRVDialect"];
 }
@@ -163,6 +178,9 @@ def ConvertVulkanLaunchFuncToVulkanCalls
 : Pass<"launch-func-to-vulkan", "ModuleOp"> {
   let summary = "Convert vulkanLaunch external call to Vulkan runtime external 
"
 "calls";
+  let description = [{
+This pass is only intended for the mlir-vulkan-runner.
+  }];
   let constructor = "mlir::createConvertVulkanLaunchFuncToVulkanCallsPass()";
   let dependentDialects = ["LLVM::LLVMDialect"];
 }
@@ -194,7 +212,11 @@ def ConvertLinalgToStandard : 
Pass<"convert-linalg-to-std", "ModuleOp"> {
 
//===--===//
 
 def ConvertLinalgToSPIRV : Pass<"convert-linalg-to-spirv", "ModuleOp"> {
-  let summary = "Convert Linalg ops to SPIR-V ops";
+  let summary = "Convert Linalg dialect to SPIR-V dialect";
+  let description = [{
+This pass converts supported Linalg ops to SPIR-V ops. It's quite
+experimental and are expected to migrate to other proper conversions.
+  }];
   let constructor = "mlir::createLinalgToSPIRVPass()";
   let dependentDialects = ["spirv::SPIRVDialect"];
 }
@@ -312,6 +334,10 @@ def ConvertShapeConstraints: 
Pass<"convert-shape-constraints", "FuncOp"> {
 
 def ConvertSPIRVToLLVM : Pass<"convert-spirv-to-llvm", "ModuleOp"> {
   let summary = "Convert SPIR-V dialect to LLVM dialect";
+  let description = [{
+See https://mlir.llvm.org/docs/SPIRVToLLVMDialectConversion/
+for more details.
+  }];
   let constructor = "mlir::createConvertSPIRVToLLVMPass()";
   let dependentDialects = ["LLVM::LLVMDialect"];
 }
@@ -375,12 +401,17 @@ def ConvertStandardToLLVM : Pass<"convert-std-to-llvm", 
"ModuleOp"> {
 
 def LegalizeStandardForSPIRV : Pass<"legalize-std-for-spirv"> {
   let summary = "Legalize standard ops for SPIR-V lowering";
+  let description = [{
+The pass contains certain intra standard op conversions that are meant for
+lowering to SPIR-V ops, e.g., folding subviews loads/stores to the original
+loads/stores from/to the original memref.
+  }];
   let constructor = "mlir::createLegalizeStdOpsForSPIRVLoweringPass()";
   let dependentDialects = ["spirv::SPIRVDialect"];
 }
 
 def ConvertStandardToSPIRV : Pass<"convert-std-to-spirv", "ModuleOp"> {
-  let summary = "Convert Standard Ops to SPIR-V dialect";
+  let summary = "Convert Standard dialect to SPIR-V dialect";
   let constructor = "mlir::createConvertStandardToSPIRVPass()";
   let dependentDialects = ["spirv::SPIRVDialect"];
 }
@@ -459,8 +490,7 @@ def ConvertVectorToROCDL : Pass<"convert-vector-to-rocdl", 
"ModuleOp"> {
 
//===--===//
 
 def ConvertVectorToSPIRV : Pass<"convert-vector-

[llvm-branch-commits] [mlir] 7c3ae48 - [mlir][spirv] Replace SPIRVOpLowering with OpConversionPattern

2021-01-09 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-09T08:04:53-05:00
New Revision: 7c3ae48fe85f535a5e35db9898c7bf2e3baeb6b4

URL: 
https://github.com/llvm/llvm-project/commit/7c3ae48fe85f535a5e35db9898c7bf2e3baeb6b4
DIFF: 
https://github.com/llvm/llvm-project/commit/7c3ae48fe85f535a5e35db9898c7bf2e3baeb6b4.diff

LOG: [mlir][spirv] Replace SPIRVOpLowering with OpConversionPattern

The dialect conversion framework was enhanced to handle type
conversion automatically. OpConversionPattern already contains
a pointer to the TypeConverter. There is no need to duplicate it
in a separate subclass. This removes the only reason for a
SPIRVOpLowering subclass. It adapts to use core infrastructure
and simplifies the code.

Also added a utility function to OpConversionPattern for getting
TypeConverter as a certain subclass.

Reviewed By: hanchung

Differential Revision: https://reviews.llvm.org/D94080

Added: 


Modified: 
mlir/include/mlir/Dialect/SPIRV/Transforms/SPIRVConversion.h
mlir/include/mlir/Transforms/DialectConversion.h
mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp
mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp
mlir/lib/Conversion/SCFToSPIRV/SCFToSPIRV.cpp
mlir/lib/Conversion/StandardToSPIRV/StandardToSPIRV.cpp
mlir/lib/Conversion/VectorToSPIRV/VectorToSPIRV.cpp
mlir/lib/Dialect/SPIRV/Transforms/LowerABIAttributesPass.cpp
mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp
mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir

Removed: 




diff  --git a/mlir/include/mlir/Dialect/SPIRV/Transforms/SPIRVConversion.h 
b/mlir/include/mlir/Dialect/SPIRV/Transforms/SPIRVConversion.h
index fddf84859bc2..4143091543d6 100644
--- a/mlir/include/mlir/Dialect/SPIRV/Transforms/SPIRVConversion.h
+++ b/mlir/include/mlir/Dialect/SPIRV/Transforms/SPIRVConversion.h
@@ -63,19 +63,6 @@ class SPIRVTypeConverter : public TypeConverter {
   spirv::TargetEnv targetEnv;
 };
 
-/// Base class to define a conversion pattern to lower `SourceOp` into SPIR-V.
-template 
-class SPIRVOpLowering : public OpConversionPattern {
-public:
-  SPIRVOpLowering(MLIRContext *context, SPIRVTypeConverter &typeConverter,
-  PatternBenefit benefit = 1)
-  : OpConversionPattern(context, benefit),
-typeConverter(typeConverter) {}
-
-protected:
-  SPIRVTypeConverter &typeConverter;
-};
-
 /// Appends to a pattern list additional patterns for translating the builtin
 /// `func` op to the SPIR-V dialect. These patterns do not handle shader
 /// interface/ABI; they convert function parameters to be of SPIR-V allowed

diff  --git a/mlir/include/mlir/Transforms/DialectConversion.h 
b/mlir/include/mlir/Transforms/DialectConversion.h
index e02cf8fe4c0a..51c7788ffb14 100644
--- a/mlir/include/mlir/Transforms/DialectConversion.h
+++ b/mlir/include/mlir/Transforms/DialectConversion.h
@@ -341,6 +341,13 @@ class ConversionPattern : public RewritePattern {
   /// does not require type conversion.
   TypeConverter *getTypeConverter() const { return typeConverter; }
 
+  template 
+  std::enable_if_t::value,
+   ConverterTy *>
+  getTypeConverter() const {
+return static_cast(typeConverter);
+  }
+
 protected:
   /// See `RewritePattern::RewritePattern` for information on the other
   /// available constructors.

diff  --git a/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp 
b/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp
index e84269e9418d..d66f9c66c1da 100644
--- a/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp
+++ b/mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp
@@ -17,6 +17,8 @@
 #include "mlir/Dialect/SPIRV/IR/TargetAndABI.h"
 #include "mlir/Dialect/SPIRV/Transforms/SPIRVConversion.h"
 #include "mlir/IR/BuiltinOps.h"
+#include "mlir/Transforms/DialectConversion.h"
+#include "llvm/ADT/StringSwitch.h"
 
 using namespace mlir;
 
@@ -26,9 +28,9 @@ namespace {
 /// Pattern lowering GPU block/thread size/id to loading SPIR-V invocation
 /// builtin variables.
 template 
-class LaunchConfigConversion : public SPIRVOpLowering {
+class LaunchConfigConversion : public OpConversionPattern {
 public:
-  using SPIRVOpLowering::SPIRVOpLowering;
+  using OpConversionPattern::OpConversionPattern;
 
   LogicalResult
   matchAndRewrite(SourceOp op, ArrayRef operands,
@@ -38,9 +40,9 @@ class LaunchConfigConversion : public 
SPIRVOpLowering {
 /// Pattern lowering subgroup size/id to loading SPIR-V invocation
 /// builtin variables.
 template 
-class SingleDimLaunchConfigConversion : public SPIRVOpLowering {
+class SingleDimLaunchConfigConversion : public OpConversionPattern {
 public:
-  using SPIRVOpLowering::SPIRVOpLowering;
+  using OpConversionPattern::OpConversionPattern;
 
   LogicalResult
   matchAndRewrite(SourceOp op, ArrayRef operands,
@@ -51,9 +53,9 @@ class SingleDimLaunchConfigConversion : public 
SPIRVOpLowering {
 /// a constant with WorkgroupSize decoration. So here we cannot generate a
 /// builtin variabl

[llvm-branch-commits] [mlir] df86f15 - [mlir][linalg] Support parsing attributes in named op spec

2021-01-11 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-11T09:05:20-05:00
New Revision: df86f15f0c53c395dac5a14aba08745bc12b9b9b

URL: 
https://github.com/llvm/llvm-project/commit/df86f15f0c53c395dac5a14aba08745bc12b9b9b
DIFF: 
https://github.com/llvm/llvm-project/commit/df86f15f0c53c395dac5a14aba08745bc12b9b9b.diff

LOG: [mlir][linalg] Support parsing attributes in named op spec

With this, now we can specify a list of attributes on named ops
generated from the spec. The format is defined as

```
attr-id ::= bare-id (`?`)?
attr-typedef ::= type (`[` `]`)?
attr-def ::= attr-id `:` attr-typedef

tc-attr-def ::= `attr` `(` attr-def-list `)`
tc-def ::= `def` bare-id
  `(`tensor-def-list`)` `->` `(` tensor-def-list`)`
  (tc-attr-def)?
```

For example,

```
ods_def
def some_op(...) -> (...)
attr(
  f32_attr: f32,
  i32_attr: i32,
  array_attr : f32[],
  optional_attr? : f32
)
```

where `?` means optional attribute and `[]` means array type.

Reviewed By: hanchung, nicolasvasilache

Differential Revision: https://reviews.llvm.org/D94240

Added: 


Modified: 
mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp

Removed: 




diff  --git a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc 
b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
index f81380f02bb3..1ef128760637 100644
--- a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
+++ b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc
@@ -72,3 +72,25 @@ ods_def :
 def test3(A: f32(Batch, M, K), B: f32(K, N)) -> (C: f32(Batch, M, N)) {
   C(b, m, n) = std_addf(std_mulf(A(b, m, k), B(k, n)));
 }
+
+// Test attribute definitions
+// ODS-LABEL: def Test4Op
+// ODS: F32ArrayAttr:$array_attr,
+// ODS: F32:$f32_attr,
+// ODS: RankedF32ElementsAttr<[4]>:$fvec_attr,
+// ODS: I32:$i32_attr,
+// ODS: RankedI32ElementsAttr<[5, 6]>:$ivec_attr,
+// ODS: OptionalAttr:$optional_attr
+//
+ods_def :
+def test4(A: f32(Batch, M, K), B: f32(K, N)) -> (C: f32(Batch, M, N))
+attr(
+  f32_attr: f32,
+  i32_attr: i32,
+  fvec_attr: 4xf32,
+  ivec_attr: 5x6xi32,
+  array_attr : f32[],
+  optional_attr? : f32
+) {
+  C(b, m, n) = std_addf(std_mulf(A(b, m, k), B(k, n)));
+}

diff  --git a/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp 
b/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
index 592e6cb774fb..e7ab5edc1118 100644
--- a/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
+++ b/mlir/tools/mlir-linalg-ods-gen/mlir-linalg-ods-gen.cpp
@@ -20,11 +20,17 @@
 #include "mlir/Support/LLVM.h"
 #include "mlir/Support/LogicalResult.h"
 #include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/Twine.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/ToolOutputFile.h"
 
+#include 
+
 #define DEBUG_TYPE "linalg-ods-gen"
 
 static llvm::cl::OptionCategory ODSGenCat("Linalg ODS Gen");
@@ -79,11 +85,14 @@ class Token {
 gt,
 l_brace,
 l_paren,
+l_square,
 lt,
 minus,
 plus,
+question,
 r_brace,
 r_paren,
+r_square,
 semicolon,
 star,
 
@@ -91,6 +100,7 @@ class Token {
 kw_def,
 FIRST_KEYWORD = kw_def,
 kw_ods_def,
+kw_attr_def,
 kw_floordiv,
 kw_ceildiv,
 kw_mod,
@@ -151,6 +161,10 @@ class Lexer {
   Token emitError(llvm::SMLoc loc, const Twine &msg);
   Token emitError(const char *loc, const Twine &msg);
 
+  /// Change the position of the lexer cursor. The next token we lex will start
+  /// at the designated point in the input.
+  void resetPointer(const char *newPtr) { curPtr = newPtr; }
+
 private:
   Token formToken(Token::Kind kind, const char *tokStart) {
 return Token(kind, StringRef(tokStart, curPtr - tokStart));
@@ -247,10 +261,14 @@ Token Lexer::lexToken() {
   return formToken(Token::Kind::l_brace, tokStart);
 case '(':
   return formToken(Token::Kind::l_paren, tokStart);
+case '[':
+  return formToken(Token::Kind::l_square, tokStart);
 case '}':
   return formToken(Token::Kind::r_brace, tokStart);
 case ')':
   return formToken(Token::Kind::r_paren, tokStart);
+case ']':
+  return formToken(Token::Kind::r_square, tokStart);
 case '<':
   return formToken(Token::Kind::lt, tokStart);
 case '>':
@@ -263,6 +281,8 @@ Token Lexer::lexToken() {
   return formToken(Token::Kind::semicolon, tokStart);
 case '*':
   return formToken(Token::Kind::star, tokStart);
+case '?':
+  return formToken(Token::Kind::question, tokStart);
 case '/':
   if (*curPtr == '/') {
 skipComment();
@@ -289,6 +309,7 @@ Token Lexer::lexIdentifier(const char *tokStart) {
   // Check to see if this identifier is a keyword.
   StringRef str(tokStart, curPtr - tokStart);
   Token::Kind kind = StringSwit

[llvm-branch-commits] [mlir] 5522547 - [mlir][linalg] Support permutation when lowering to loop nests

2021-01-11 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2021-01-11T09:13:06-05:00
New Revision: 55225471d9838e452cfb31e0edae6162b7226221

URL: 
https://github.com/llvm/llvm-project/commit/55225471d9838e452cfb31e0edae6162b7226221
DIFF: 
https://github.com/llvm/llvm-project/commit/55225471d9838e452cfb31e0edae6162b7226221.diff

LOG: [mlir][linalg] Support permutation when lowering to loop nests

Linalg ops are perfect loop nests. When materializing the concrete
loop nest, the default order specified by the Linalg op's iterators
may not be the best for further CodeGen: targets frequently need
to plan the loop order in order to gain better data access. And
different targets can have different preferences. So there should
exist a way to control the order.

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D91795

Added: 
mlir/test/Dialect/Linalg/loop-order.mlir

Modified: 
mlir/include/mlir/Dialect/Linalg/Passes.td
mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
mlir/lib/Dialect/Linalg/Transforms/Loops.cpp

Removed: 




diff  --git a/mlir/include/mlir/Dialect/Linalg/Passes.td 
b/mlir/include/mlir/Dialect/Linalg/Passes.td
index 14f845589a6f..a20289af3054 100644
--- a/mlir/include/mlir/Dialect/Linalg/Passes.td
+++ b/mlir/include/mlir/Dialect/Linalg/Passes.td
@@ -28,8 +28,8 @@ def LinalgFoldUnitExtentDims : 
FunctionPass<"linalg-fold-unit-extent-dims"> {
   let options = [
 Option<"foldOneTripLoopsOnly", "fold-one-trip-loops-only", "bool",
 /*default=*/"false",
-   "Only folds the one-trip loops from Linalg ops on tensors "
-   "(for testing purposes only)">
+   "Only folds the one-trip loops from Linalg ops on tensors "
+   "(for testing purposes only)">
   ];
   let dependentDialects = ["linalg::LinalgDialect"];
 }
@@ -52,12 +52,24 @@ def LinalgLowerToAffineLoops : 
FunctionPass<"convert-linalg-to-affine-loops"> {
   let summary = "Lower the operations from the linalg dialect into affine "
 "loops";
   let constructor = "mlir::createConvertLinalgToAffineLoopsPass()";
+  let options = [
+ListOption<"interchangeVector", "interchange-vector", "unsigned",
+   "Permute the loops in the nest following the given "
+   "interchange vector",
+   "llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
+  ];
   let dependentDialects = ["linalg::LinalgDialect", "AffineDialect"];
 }
 
 def LinalgLowerToLoops : FunctionPass<"convert-linalg-to-loops"> {
   let summary = "Lower the operations from the linalg dialect into loops";
   let constructor = "mlir::createConvertLinalgToLoopsPass()";
+  let options = [
+ListOption<"interchangeVector", "interchange-vector", "unsigned",
+   "Permute the loops in the nest following the given "
+   "interchange vector",
+   "llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
+  ];
   let dependentDialects = ["linalg::LinalgDialect", "scf::SCFDialect", 
"AffineDialect"];
 }
 
@@ -72,6 +84,12 @@ def LinalgLowerToParallelLoops
   let summary = "Lower the operations from the linalg dialect into parallel "
 "loops";
   let constructor = "mlir::createConvertLinalgToParallelLoopsPass()";
+  let options = [
+ListOption<"interchangeVector", "interchange-vector", "unsigned",
+   "Permute the loops in the nest following the given "
+   "interchange vector",
+   "llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">
+  ];
   let dependentDialects = ["AffineDialect", "linalg::LinalgDialect", 
"scf::SCFDialect"];
 }
 

diff  --git a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h 
b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
index dc82569aac38..d816414ef8b4 100644
--- a/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
+++ b/mlir/include/mlir/Dialect/Linalg/Transforms/Transforms.h
@@ -267,16 +267,28 @@ void vectorizeLinalgOp(OpBuilder &builder, Operation *op);
 
 /// Emits a loop nest of `LoopTy` with the proper body for `op`.
 template 
-Optional linalgLowerOpToLoops(OpBuilder &builder, Operation *op);
-
-/// Emits a loop nest of `scf.for` with the proper body for `op`.
-LogicalResult linalgOpToLoops(OpBuilder &builder, Operation *op);
-
-/// Emits a loop nest of `scf.parallel` with the proper body for `op`.
-LogicalResult linalgOpToParallelLoops(OpBuilder &builder, Operation *op);
+Optional
+linalgLowerOpToLoops(OpBuilder &builder, Operation *op,
+ ArrayRef interchangeVector = {});
+
+/// Emits a loop nest of `scf.for` with the proper body for `op`. The generated
+/// loop nest will follow the `interchangeVector`-permutated iterator order. If
+/// `interchangeVector` is empty, then no permutation happens.
+LogicalResult linalgOpToLoops(OpBuilder &builder, Operation *op,
+  ArrayRef interchangeVector = {});

[llvm-branch-commits] [mlir] ecab638 - [MLIR][SPIRV] Refactoring serialization and deserialization

2020-12-14 Thread Lei Zhang via llvm-branch-commits

Author: ergawy
Date: 2020-12-14T12:28:16-05:00
New Revision: ecab63894bb5aebcbbe694839779f346e6fbe9e2

URL: 
https://github.com/llvm/llvm-project/commit/ecab63894bb5aebcbbe694839779f346e6fbe9e2
DIFF: 
https://github.com/llvm/llvm-project/commit/ecab63894bb5aebcbbe694839779f346e6fbe9e2.diff

LOG: [MLIR][SPIRV] Refactoring serialization and deserialization

This commit splits SPIR-V's serialization and deserialization code
into separate libraries. The motiviation being that the serializer
is used more often the deserializer and therefore lumping them
together unnecessarily increases binary size for the most common
case.

This commit also moves these libraries into the Target/ directory
to follow MLIR convention.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D91548

Added: 
mlir/include/mlir/Target/SPIRV/Deserialization.h
mlir/include/mlir/Target/SPIRV/SPIRVBinaryUtils.h
mlir/include/mlir/Target/SPIRV/Serialization.h
mlir/lib/Target/SPIRV/Deserialization.cpp
mlir/lib/Target/SPIRV/SPIRVBinaryUtils.cpp
mlir/lib/Target/SPIRV/Serialization.cpp
mlir/lib/Target/SPIRV/TranslateRegistration.cpp

Modified: 
mlir/lib/Conversion/GPUToVulkan/ConvertGPULaunchFuncToVulkanLaunchFunc.cpp
mlir/lib/Dialect/SPIRV/CMakeLists.txt
mlir/lib/Target/CMakeLists.txt
mlir/unittests/Dialect/SPIRV/CMakeLists.txt
mlir/unittests/Dialect/SPIRV/DeserializationTest.cpp
mlir/unittests/Dialect/SPIRV/SerializationTest.cpp

Removed: 
mlir/include/mlir/Dialect/SPIRV/SPIRVBinaryUtils.h
mlir/include/mlir/Dialect/SPIRV/Serialization.h
mlir/lib/Dialect/SPIRV/Serialization/CMakeLists.txt
mlir/lib/Dialect/SPIRV/Serialization/Deserializer.cpp
mlir/lib/Dialect/SPIRV/Serialization/SPIRVBinaryUtils.cpp
mlir/lib/Dialect/SPIRV/Serialization/Serializer.cpp
mlir/lib/Dialect/SPIRV/Serialization/TranslateRegistration.cpp



diff  --git a/mlir/include/mlir/Dialect/SPIRV/Serialization.h 
b/mlir/include/mlir/Target/SPIRV/Deserialization.h
similarity index 65%
rename from mlir/include/mlir/Dialect/SPIRV/Serialization.h
rename to mlir/include/mlir/Target/SPIRV/Deserialization.h
index 2c91286ca158..207f506b17ad 100644
--- a/mlir/include/mlir/Dialect/SPIRV/Serialization.h
+++ b/mlir/include/mlir/Target/SPIRV/Deserialization.h
@@ -6,13 +6,12 @@
 //
 
//===--===//
 //
-// This file declares the entry points for serialize and deserialize SPIR-V
-// binary modules.
+// This file declares the entry points for deserializing SPIR-V binary modules.
 //
 
//===--===//
 
-#ifndef MLIR_DIALECT_SPIRV_SERIALIZATION_H_
-#define MLIR_DIALECT_SPIRV_SERIALIZATION_H_
+#ifndef MLIR_TARGET_SPIRV_DESERIALIZATION_H
+#define MLIR_TARGET_SPIRV_DESERIALIZATION_H
 
 #include "mlir/Support/LLVM.h"
 
@@ -21,15 +20,8 @@ struct LogicalResult;
 class MLIRContext;
 
 namespace spirv {
-class ModuleOp;
 class OwningSPIRVModuleRef;
 
-/// Serializes the given SPIR-V `module` and writes to `binary`. On failure,
-/// reports errors to the error handler registered with the MLIR context for
-/// `module`.
-LogicalResult serialize(ModuleOp module, SmallVectorImpl &binary,
-bool emitDebugInfo = false);
-
 /// Deserializes the given SPIR-V `binary` module and creates a MLIR ModuleOp
 /// in the given `context`. Returns the ModuleOp on success; otherwise, reports
 /// errors to the error handler registered with `context` and returns a null
@@ -40,4 +32,4 @@ OwningSPIRVModuleRef deserialize(ArrayRef binary,
 } // end namespace spirv
 } // end namespace mlir
 
-#endif // MLIR_DIALECT_SPIRV_SERIALIZATION_H_
+#endif // MLIR_TARGET_SPIRV_DESERIALIZATION_H

diff  --git a/mlir/include/mlir/Dialect/SPIRV/SPIRVBinaryUtils.h 
b/mlir/include/mlir/Target/SPIRV/SPIRVBinaryUtils.h
similarity index 91%
rename from mlir/include/mlir/Dialect/SPIRV/SPIRVBinaryUtils.h
rename to mlir/include/mlir/Target/SPIRV/SPIRVBinaryUtils.h
index 6baafdb9d9e9..cdfadb02fe5c 100644
--- a/mlir/include/mlir/Dialect/SPIRV/SPIRVBinaryUtils.h
+++ b/mlir/include/mlir/Target/SPIRV/SPIRVBinaryUtils.h
@@ -10,8 +10,8 @@
 //
 
//===--===//
 
-#ifndef MLIR_DIALECT_SPIRV_SPIRV_BINARY_UTILS_H_
-#define MLIR_DIALECT_SPIRV_SPIRV_BINARY_UTILS_H_
+#ifndef MLIR_TARGET_SPIRV_BINARY_UTILS_H_
+#define MLIR_TARGET_SPIRV_BINARY_UTILS_H_
 
 #include "mlir/Dialect/SPIRV/SPIRVOps.h"
 #include "mlir/Support/LogicalResult.h"
@@ -44,4 +44,4 @@ LogicalResult 
encodeStringLiteralInto(SmallVectorImpl &binary,
 } // end namespace spirv
 } // end namespace mlir
 
-#endif // MLIR_DIALECT_SPIRV_SPIRV_BINARY_UTILS_H_
+#endif // MLIR_TARGET_SPIRV_BINARY_UTILS_H_

diff  --git a/mlir/include/mlir/Target/SPIRV/Serialization.h 
b/mlir/include/mlir/Target/SPIRV/Serialization.h
ne

[llvm-branch-commits] [mlir] 6551c9a - [mlir][spirv] Add parsing and printing support for SpecConstantOperation

2020-12-16 Thread Lei Zhang via llvm-branch-commits

Author: ergawy
Date: 2020-12-16T08:26:48-05:00
New Revision: 6551c9ac365ca46e83354703d1a63c671a50258a

URL: 
https://github.com/llvm/llvm-project/commit/6551c9ac365ca46e83354703d1a63c671a50258a
DIFF: 
https://github.com/llvm/llvm-project/commit/6551c9ac365ca46e83354703d1a63c671a50258a.diff

LOG: [mlir][spirv] Add parsing and printing support for SpecConstantOperation

Adds more support for `SpecConstantOperation` by defining a custom
syntax for the op and implementing its parsing and printing.

Reviewed By: mravishankar, antiagainst

Differential Revision: https://reviews.llvm.org/D92919

Added: 


Modified: 
mlir/include/mlir/Dialect/SPIRV/SPIRVStructureOps.td
mlir/lib/Dialect/SPIRV/SPIRVOps.cpp
mlir/test/Dialect/SPIRV/structure-ops.mlir

Removed: 




diff  --git a/mlir/include/mlir/Dialect/SPIRV/SPIRVStructureOps.td 
b/mlir/include/mlir/Dialect/SPIRV/SPIRVStructureOps.td
index b8e76c3662ec..1ae7d285cd93 100644
--- a/mlir/include/mlir/Dialect/SPIRV/SPIRVStructureOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/SPIRVStructureOps.td
@@ -608,9 +608,12 @@ def SPV_SpecConstantCompositeOp : 
SPV_Op<"specConstantComposite", [InModuleScope
   let autogenSerialization = 0;
 }
 
-def SPV_YieldOp : SPV_Op<"mlir.yield", [NoSideEffect, Terminator]> {
-  let summary = "Yields the result computed in `spv.SpecConstantOperation`'s"
-"region back to the parent op.";
+def SPV_YieldOp : SPV_Op<"mlir.yield", [
+HasParent<"SpecConstantOperationOp">, NoSideEffect, Terminator]> {
+  let summary = [{
+Yields the result computed in `spv.SpecConstantOperation`'s
+region back to the parent op.
+  }];
 
   let description = [{
 This op is a special terminator whose only purpose is to terminate
@@ -639,12 +642,16 @@ def SPV_YieldOp : SPV_Op<"mlir.yield", [NoSideEffect, 
Terminator]> {
   let autogenSerialization = 0;
 
   let assemblyFormat = "attr-dict $operand `:` type($operand)";
+
+  let verifier = [{ return success(); }];
 }
 
 def SPV_SpecConstantOperationOp : SPV_Op<"SpecConstantOperation", [
- InFunctionScope, NoSideEffect,
- IsolatedFromAbove]> {
-  let summary = "Declare a new specialization constant that results from doing 
an operation.";
+   NoSideEffect, InFunctionScope,
+   SingleBlockImplicitTerminator<"YieldOp">]> {
+  let summary = [{
+Declare a new specialization constant that results from doing an operation.
+  }];
 
   let description = [{
 This op declares a SPIR-V specialization constant that results from
@@ -653,12 +660,8 @@ def SPV_SpecConstantOperationOp : 
SPV_Op<"SpecConstantOperation", [
 In the `spv` dialect, this op is modelled as follows:
 
 ```
-spv-spec-constant-operation-op ::= `"spv.SpecConstantOperation"`
- `(`ssa-id (`, ` ssa-id)`)`
-   `({`
- ssa-id = spirv-op
- `spv.mlir.yield` ssa-id
-   `})` `:` function-type
+spv-spec-constant-operation-op ::= `spv.SpecConstantOperation` `wraps`
+ generic-spirv-op `:` function-type
 ```
 
 In particular, an `spv.SpecConstantOperation` contains exactly one
@@ -712,17 +715,15 @@ def SPV_SpecConstantOperationOp : 
SPV_Op<"SpecConstantOperation", [
  Example:
 ```mlir
 %0 = spv.constant 1: i32
+%1 = spv.constant 1: i32
 
-%1 = "spv.SpecConstantOperation"(%0) ({
-  %ret = spv.IAdd %0, %0 : i32
-  spv.mlir.yield %ret : i32
-}) : (i32) -> i32
+%2 = spv.SpecConstantOperation wraps "spv.IAdd"(%0, %1) : (i32, i32) -> i32
 ```
   }];
 
-  let arguments = (ins Variadic:$operands);
+  let arguments = (ins);
 
-  let results = (outs AnyType:$results);
+  let results = (outs AnyType:$result);
 
   let regions = (region SizedRegion<1>:$body);
 

diff  --git a/mlir/lib/Dialect/SPIRV/SPIRVOps.cpp 
b/mlir/lib/Dialect/SPIRV/SPIRVOps.cpp
index 03e416e95441..43b3c517a4c6 100644
--- a/mlir/lib/Dialect/SPIRV/SPIRVOps.cpp
+++ b/mlir/lib/Dialect/SPIRV/SPIRVOps.cpp
@@ -3396,35 +3396,39 @@ static LogicalResult 
verify(spirv::SpecConstantCompositeOp constOp) {
 }
 
 
//===--===//
-// spv.mlir.yield
+// spv.SpecConstantOperation
 
//===--===//
 
-static LogicalResult verify(spirv::YieldOp yieldOp) {
-  Operation *parentOp = yieldOp->getParentOp();
+static ParseResult parseSpecConstantOperationOp(OpAsmParser &parser,
+OperationState &state) {
+  Region *body = state.addRegion();
 
-  if (!parentOp || !isa(parentOp))
-return yieldOp.emitOpError(
-"expected parent op to be 'spv.SpecC

[llvm-branch-commits] [mlir] 42980a7 - [mlir][spirv] Convert functions returning one value

2020-12-23 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2020-12-23T13:27:31-05:00
New Revision: 42980a789d2212f774dbb12c2555452d328089a6

URL: 
https://github.com/llvm/llvm-project/commit/42980a789d2212f774dbb12c2555452d328089a6
DIFF: 
https://github.com/llvm/llvm-project/commit/42980a789d2212f774dbb12c2555452d328089a6.diff

LOG: [mlir][spirv] Convert functions returning one value

Reviewed By: hanchung, ThomasRaoux

Differential Revision: https://reviews.llvm.org/D93468

Added: 


Modified: 
mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.cpp
mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp
mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir

Removed: 




diff  --git a/mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.cpp 
b/mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.cpp
index d15623568212..470f4143f2c5 100644
--- a/mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.cpp
+++ b/mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.cpp
@@ -924,10 +924,14 @@ LoadOpPattern::matchAndRewrite(LoadOp loadOp, 
ArrayRef operands,
 LogicalResult
 ReturnOpPattern::matchAndRewrite(ReturnOp returnOp, ArrayRef operands,
  ConversionPatternRewriter &rewriter) const {
-  if (returnOp.getNumOperands()) {
+  if (returnOp.getNumOperands() > 1)
 return failure();
+
+  if (returnOp.getNumOperands() == 1) {
+rewriter.replaceOpWithNewOp(returnOp, operands[0]);
+  } else {
+rewriter.replaceOpWithNewOp(returnOp);
   }
-  rewriter.replaceOpWithNewOp(returnOp);
   return success();
 }
 

diff  --git a/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp 
b/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp
index b310d5df7b26..9393f3df6425 100644
--- a/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp
+++ b/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp
@@ -473,23 +473,27 @@ LogicalResult
 FuncOpConversion::matchAndRewrite(FuncOp funcOp, ArrayRef operands,
   ConversionPatternRewriter &rewriter) const {
   auto fnType = funcOp.getType();
-  // TODO: support converting functions with one result.
-  if (fnType.getNumResults())
+  if (fnType.getNumResults() > 1)
 return failure();
 
   TypeConverter::SignatureConversion signatureConverter(fnType.getNumInputs());
-  for (auto argType : enumerate(funcOp.getType().getInputs())) {
+  for (auto argType : enumerate(fnType.getInputs())) {
 auto convertedType = typeConverter.convertType(argType.value());
 if (!convertedType)
   return failure();
 signatureConverter.addInputs(argType.index(), convertedType);
   }
 
+  Type resultType;
+  if (fnType.getNumResults() == 1)
+resultType = typeConverter.convertType(fnType.getResult(0));
+
   // Create the converted spv.func op.
   auto newFuncOp = rewriter.create(
   funcOp.getLoc(), funcOp.getName(),
   rewriter.getFunctionType(signatureConverter.getConvertedTypes(),
-   llvm::None));
+   resultType ? TypeRange(resultType)
+  : TypeRange()));
 
   // Copy over all attributes other than the function name and type.
   for (const auto &namedAttr : funcOp.getAttrs()) {

diff  --git a/mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir 
b/mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir
index 10e43ef4acd7..850e22465d44 100644
--- a/mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir
+++ b/mlir/test/Conversion/StandardToSPIRV/std-ops-to-spirv.mlir
@@ -954,3 +954,29 @@ func @store_i16(%arg0: memref<10xi16>, %index: index, 
%value: i16) {
 }
 
 } // end module
+
+// -
+
+//===--===//
+// std.return
+//===--===//
+
+module attributes {
+  spv.target_env = #spv.target_env<#spv.vce, {}>
+} {
+
+// CHECK-LABEL: spv.func @return_one_val
+//  CHECK-SAME: (%[[ARG:.+]]: f32)
+func @return_one_val(%arg0: f32) -> f32 {
+  // CHECK: spv.ReturnValue %[[ARG]] : f32
+  return %arg0: f32
+}
+
+// Check that multiple-return functions are not converted.
+// CHECK-LABEL: func @return_multi_val
+func @return_multi_val(%arg0: f32) -> (f32, f32) {
+  // CHECK: return
+  return %arg0, %arg0: f32, f32
+}
+
+}



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] a16fbff - [mlir][spirv] Create a pass for testing SCFToSPIRV patterns

2020-12-23 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2020-12-23T14:31:55-05:00
New Revision: a16fbff17d329c3f2cc1e49d501f61b3996e9b8a

URL: 
https://github.com/llvm/llvm-project/commit/a16fbff17d329c3f2cc1e49d501f61b3996e9b8a
DIFF: 
https://github.com/llvm/llvm-project/commit/a16fbff17d329c3f2cc1e49d501f61b3996e9b8a.diff

LOG: [mlir][spirv] Create a pass for testing SCFToSPIRV patterns

Previously all SCF to SPIR-V conversion patterns were tested as
the -convert-gpu-to-spirv pass. That obscured the structure we
want. This commit fixed it.

Reviewed By: ThomasRaoux, hanchung

Differential Revision: https://reviews.llvm.org/D93488

Added: 
mlir/include/mlir/Conversion/SCFToSPIRV/SCFToSPIRVPass.h
mlir/lib/Conversion/SCFToSPIRV/SCFToSPIRVPass.cpp
mlir/test/Conversion/GPUToSPIRV/entry-point.mlir
mlir/test/Conversion/SCFToSPIRV/for.mlir
mlir/test/Conversion/SCFToSPIRV/if.mlir

Modified: 
mlir/include/mlir/Conversion/Passes.h
mlir/include/mlir/Conversion/Passes.td
mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp
mlir/lib/Conversion/SCFToSPIRV/CMakeLists.txt

Removed: 
mlir/test/Conversion/GPUToSPIRV/if.mlir
mlir/test/Conversion/GPUToSPIRV/loop.mlir
mlir/test/Conversion/GPUToSPIRV/test_spirv_entry_point.mlir



diff  --git a/mlir/include/mlir/Conversion/Passes.h 
b/mlir/include/mlir/Conversion/Passes.h
index cc4f59c12496..21b35804ab36 100644
--- a/mlir/include/mlir/Conversion/Passes.h
+++ b/mlir/include/mlir/Conversion/Passes.h
@@ -23,6 +23,7 @@
 #include "mlir/Conversion/PDLToPDLInterp/PDLToPDLInterp.h"
 #include "mlir/Conversion/SCFToGPU/SCFToGPUPass.h"
 #include "mlir/Conversion/SCFToOpenMP/SCFToOpenMP.h"
+#include "mlir/Conversion/SCFToSPIRV/SCFToSPIRVPass.h"
 #include "mlir/Conversion/SCFToStandard/SCFToStandard.h"
 #include "mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h"
 #include "mlir/Conversion/ShapeToStandard/ShapeToStandard.h"

diff  --git a/mlir/include/mlir/Conversion/Passes.td 
b/mlir/include/mlir/Conversion/Passes.td
index b364700bd849..2dc438534a44 100644
--- a/mlir/include/mlir/Conversion/Passes.td
+++ b/mlir/include/mlir/Conversion/Passes.td
@@ -230,6 +230,23 @@ def ConvertSCFToOpenMP : 
FunctionPass<"convert-scf-to-openmp"> {
   let dependentDialects = ["omp::OpenMPDialect"];
 }
 
+//===--===//
+// SCFToSPIRV
+//===--===//
+
+def SCFToSPIRV : Pass<"convert-scf-to-spirv", "ModuleOp"> {
+  let summary = "Convert SCF dialect to SPIR-V dialect.";
+  let description = [{
+This pass converts SCF ops into SPIR-V structured control flow ops.
+SPIR-V structured control flow ops does not support yielding values.
+So for SCF ops yielding values, SPIR-V variables are created for
+holding the values and load/store operations are emitted for updating
+them.
+  }];
+  let constructor = "mlir::createConvertSCFToSPIRVPass()";
+  let dependentDialects = ["spirv::SPIRVDialect"];
+}
+
 
//===--===//
 // SCFToStandard
 
//===--===//

diff  --git a/mlir/include/mlir/Conversion/SCFToSPIRV/SCFToSPIRVPass.h 
b/mlir/include/mlir/Conversion/SCFToSPIRV/SCFToSPIRVPass.h
new file mode 100644
index ..94705d2200c4
--- /dev/null
+++ b/mlir/include/mlir/Conversion/SCFToSPIRV/SCFToSPIRVPass.h
@@ -0,0 +1,21 @@
+//===- SCFToSPIRVPass.h - SCF to SPIR-V Conversion Pass -*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#ifndef MLIR_CONVERSION_SCFTOSPIRV_SCFTOSPIRVPASS_H
+#define MLIR_CONVERSION_SCFTOSPIRV_SCFTOSPIRVPASS_H
+
+#include "mlir/Pass/Pass.h"
+
+namespace mlir {
+
+/// Creates a pass to convert SCF ops into SPIR-V ops.
+std::unique_ptr> createConvertSCFToSPIRVPass();
+
+} // namespace mlir
+
+#endif // MLIR_CONVERSION_SCFTOSPIRV_SCFTOSPIRVPASS_H

diff  --git a/mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp 
b/mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp
index 973aa3d79bd8..2c2a47fcc5ed 100644
--- a/mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp
+++ b/mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp
@@ -12,12 +12,11 @@
 
//===--===//
 
 #include "mlir/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.h"
+
 #include "../PassDetail.h"
 #include "mlir/Conversion/GPUToSPIRV/ConvertGPUToSPIRV.h"
-#include "mlir/Conversion/SCFToSPIRV/SCFToSPIRV.h"
 #include "mlir/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.h"
 #include "mlir/Dialect/GPU/GPUDialec

[llvm-branch-commits] [mlir] 930c74f - [mlir][spirv] NFC: rename SPIR-V conversion files for consistency

2020-12-23 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2020-12-23T14:36:46-05:00
New Revision: 930c74f12d799c95e37a107bb692148b36493806

URL: 
https://github.com/llvm/llvm-project/commit/930c74f12d799c95e37a107bb692148b36493806
DIFF: 
https://github.com/llvm/llvm-project/commit/930c74f12d799c95e37a107bb692148b36493806.diff

LOG: [mlir][spirv] NFC: rename SPIR-V conversion files for consistency

This commit renames various SPIR-V related conversion files for
consistency. It drops the "Convert" prefix to various files and
fixes various comment headers.

Reviewed By: hanchung, ThomasRaoux

Differential Revision: https://reviews.llvm.org/D93489

Added: 
mlir/include/mlir/Conversion/GPUToSPIRV/GPUToSPIRV.h
mlir/include/mlir/Conversion/GPUToSPIRV/GPUToSPIRVPass.h
mlir/include/mlir/Conversion/SPIRVToLLVM/SPIRVToLLVM.h
mlir/include/mlir/Conversion/SPIRVToLLVM/SPIRVToLLVMPass.h
mlir/include/mlir/Conversion/StandardToSPIRV/StandardToSPIRV.h
mlir/include/mlir/Conversion/StandardToSPIRV/StandardToSPIRVPass.h
mlir/include/mlir/Conversion/VectorToSPIRV/VectorToSPIRV.h
mlir/include/mlir/Conversion/VectorToSPIRV/VectorToSPIRVPass.h
mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRV.cpp
mlir/lib/Conversion/GPUToSPIRV/GPUToSPIRVPass.cpp
mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVM.cpp
mlir/lib/Conversion/SPIRVToLLVM/SPIRVToLLVMPass.cpp
mlir/lib/Conversion/StandardToSPIRV/StandardToSPIRV.cpp
mlir/lib/Conversion/StandardToSPIRV/StandardToSPIRVPass.cpp
mlir/lib/Conversion/VectorToSPIRV/VectorToSPIRVPass.cpp

Modified: 
mlir/docs/Dialects/SPIR-V.md
mlir/include/mlir/Conversion/LinalgToSPIRV/LinalgToSPIRV.h
mlir/include/mlir/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.h
mlir/include/mlir/Conversion/Passes.h
mlir/include/mlir/Conversion/SCFToSPIRV/SCFToSPIRV.h
mlir/include/mlir/Conversion/SCFToSPIRV/SCFToSPIRVPass.h
mlir/lib/Conversion/GPUToSPIRV/CMakeLists.txt
mlir/lib/Conversion/LinalgToSPIRV/CMakeLists.txt
mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRV.cpp
mlir/lib/Conversion/LinalgToSPIRV/LinalgToSPIRVPass.cpp
mlir/lib/Conversion/SCFToSPIRV/CMakeLists.txt
mlir/lib/Conversion/SCFToSPIRV/SCFToSPIRV.cpp
mlir/lib/Conversion/SCFToSPIRV/SCFToSPIRVPass.cpp
mlir/lib/Conversion/SPIRVToLLVM/CMakeLists.txt
mlir/lib/Conversion/SPIRVToLLVM/ConvertLaunchFuncToLLVMCalls.cpp
mlir/lib/Conversion/StandardToSPIRV/CMakeLists.txt
mlir/lib/Conversion/StandardToSPIRV/LegalizeStandardForSPIRV.cpp
mlir/lib/Conversion/VectorToSPIRV/CMakeLists.txt
mlir/lib/Conversion/VectorToSPIRV/VectorToSPIRV.cpp
mlir/tools/mlir-spirv-cpu-runner/mlir-spirv-cpu-runner.cpp
mlir/tools/mlir-vulkan-runner/mlir-vulkan-runner.cpp

Removed: 
mlir/include/mlir/Conversion/GPUToSPIRV/ConvertGPUToSPIRV.h
mlir/include/mlir/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.h
mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.h
mlir/include/mlir/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.h
mlir/include/mlir/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.h
mlir/include/mlir/Conversion/StandardToSPIRV/ConvertStandardToSPIRVPass.h
mlir/include/mlir/Conversion/VectorToSPIRV/ConvertVectorToSPIRV.h
mlir/include/mlir/Conversion/VectorToSPIRV/ConvertVectorToSPIRVPass.h
mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRV.cpp
mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRVPass.cpp
mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVMPass.cpp
mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRV.cpp
mlir/lib/Conversion/StandardToSPIRV/ConvertStandardToSPIRVPass.cpp



diff  --git a/mlir/docs/Dialects/SPIR-V.md b/mlir/docs/Dialects/SPIR-V.md
index f30d82fd2810..acace47c2c6f 100644
--- a/mlir/docs/Dialects/SPIR-V.md
+++ b/mlir/docs/Dialects/SPIR-V.md
@@ -1145,7 +1145,7 @@ in a few places:
 are at [lib/Conversion/StandardToSPIRV][MlirStdToSpirvLibs].
 
 These dialect to dialect conversions have their dedicated libraries,
-`MLIRGPUToSPIRVTransforms` and `MLIRStandardToSPIRVTransforms`, respectively.
+`MLIRGPUToSPIRV` and `MLIRStandardToSPIRV`, respectively.
 
 There are also common utilities when targeting SPIR-V from any dialect:
 

diff  --git a/mlir/include/mlir/Conversion/GPUToSPIRV/ConvertGPUToSPIRV.h 
b/mlir/include/mlir/Conversion/GPUToSPIRV/GPUToSPIRV.h
similarity index 73%
rename from mlir/include/mlir/Conversion/GPUToSPIRV/ConvertGPUToSPIRV.h
rename to mlir/include/mlir/Conversion/GPUToSPIRV/GPUToSPIRV.h
index 8bdb228c9ccc..ad5dac003897 100644
--- a/mlir/include/mlir/Conversion/GPUToSPIRV/ConvertGPUToSPIRV.h
+++ b/mlir/include/mlir/Conversion/GPUToSPIRV/GPUToSPIRV.h
@@ -1,4 +1,4 @@
-//===- ConvertGPUToSPIRV.h - GPU Ops to SPIR-V dialect patterns C++ 
-*-===//
+//===- GPUToSPIRV.h - GPU to SPIR-V Patterns *- C++ 
-*-===//
 //
 // Part of the LLVM Project, under 

[llvm-branch-commits] [mlir] ae895ac - [mlir][spirv] De-template deserialization

2020-12-23 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2020-12-23T14:45:46-05:00
New Revision: ae895ac4b9fa86b9471617357f66c0cd6cdb70b8

URL: 
https://github.com/llvm/llvm-project/commit/ae895ac4b9fa86b9471617357f66c0cd6cdb70b8
DIFF: 
https://github.com/llvm/llvm-project/commit/ae895ac4b9fa86b9471617357f66c0cd6cdb70b8.diff

LOG: [mlir][spirv] De-template deserialization

Previously for each op we generate a separate deserialization
method for it. Those deserialization methods duplicate the logic
of parsing operands/results/attributes and such.

This commit creates a generic method and let suitable op-specific
deserialization method to call into it.

wc -l SPIRVSerialization.inc: before 13290; after: 8304 (So -4986)

Reviewed By: hanchung, ThomasRaoux

Differential Revision: https://reviews.llvm.org/D93504

Added: 


Modified: 
mlir/lib/Target/SPIRV/Deserialization.cpp
mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp

Removed: 




diff  --git a/mlir/lib/Target/SPIRV/Deserialization.cpp 
b/mlir/lib/Target/SPIRV/Deserialization.cpp
index 94ea19f94123..30f46f6fc605 100644
--- a/mlir/lib/Target/SPIRV/Deserialization.cpp
+++ b/mlir/lib/Target/SPIRV/Deserialization.cpp
@@ -34,6 +34,10 @@ using namespace mlir;
 
 #define DEBUG_TYPE "spirv-deserialization"
 
+//===--===//
+// Utility Functions
+//===--===//
+
 /// Decodes a string literal in `words` starting at `wordIndex`. Update the
 /// latter to point to the position in words after the string literal.
 static inline StringRef decodeStringLiteral(ArrayRef words,
@@ -55,6 +59,10 @@ static inline bool isFnEntryBlock(Block *block) {
 }
 
 namespace {
+//===--===//
+// Utility Definitions
+//===--===//
+
 /// A struct for containing a header block's merge and continue targets.
 ///
 /// This struct is used to track original structured control flow info from
@@ -124,6 +132,10 @@ struct DeferredStructTypeInfo {
   SmallVector 
memberDecorationsInfo;
 };
 
+//===--===//
+// Deserializer Declaration
+//===--===//
+
 /// A SPIR-V module serializer.
 ///
 /// A SPIR-V binary module is a single linear stream of instructions; each
@@ -423,6 +435,14 @@ class Deserializer {
ArrayRef operands,
bool deferInstructions = true);
 
+  /// Processes a SPIR-V instruction from the given `operands`. It should
+  /// deserialize into an op with the given `opName` and `numOperands`.
+  /// This method is a generic one for dispatching any SPIR-V ops without
+  /// variadic operands and attributes in TableGen definitions.
+  LogicalResult processOpWithoutGrammarAttr(ArrayRef words,
+StringRef opName, bool hasResult,
+unsigned numOperands);
+
   /// Processes a OpUndef instruction. Adds a spv.Undef operation at the 
current
   /// insertion point.
   LogicalResult processUndef(ArrayRef operands);
@@ -580,6 +600,10 @@ class Deserializer {
 };
 } // namespace
 
+//===--===//
+// Deserializer Method Definitions
+//===--===//
+
 Deserializer::Deserializer(ArrayRef binary, MLIRContext *context)
 : binary(binary), context(context), unknownLoc(UnknownLoc::get(context)),
   module(createModuleOp()), opBuilder(module->body()) {}
@@ -2497,6 +2521,87 @@ LogicalResult 
Deserializer::processInstruction(spirv::Opcode opcode,
   return dispatchToAutogenDeserialization(opcode, operands);
 }
 
+LogicalResult
+Deserializer::processOpWithoutGrammarAttr(ArrayRef words,
+  StringRef opName, bool hasResult,
+  unsigned numOperands) {
+  SmallVector resultTypes;
+  uint32_t valueID = 0;
+
+  size_t wordIndex= 0;
+  if (hasResult) {
+if (wordIndex >= words.size())
+  return emitError(unknownLoc,
+   "expected result type  while deserializing for ")
+ << opName;
+
+// Decode the type 
+auto type = getType(words[wordIndex]);
+if (!type)
+  return emitError(unknownLoc, "unknown type result : ")
+ << words[wordIndex];
+resultTypes.push_back(type);
+++wordIndex;
+
+// Decode the result 
+if (wordIndex >= words.size())
+  return emitError(unknownLoc,
+   "expected result  while deserializing for ")
+ << opName;
+valueID = words[wordIndex];
+++wordIndex;
+  }
+

[llvm-branch-commits] [mlir] fc41777 - [mlir][spirv] De-template serialization

2020-12-23 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2020-12-23T14:54:26-05:00
New Revision: fc4102aae1cb88512a6aa45382736766fadf

URL: 
https://github.com/llvm/llvm-project/commit/fc4102aae1cb88512a6aa45382736766fadf
DIFF: 
https://github.com/llvm/llvm-project/commit/fc4102aae1cb88512a6aa45382736766fadf.diff

LOG: [mlir][spirv] De-template serialization

Previously for each op we generate a separate serialization
method for it. Those serialization methods duplicate the logic
of parsing operands/results/attributes and such.

This commit creates a generic method and let suitable op-specific
serialization method to call into it.

wc -l SPIRVSerialization.inc: before 8304; after: 5597 (So -2707)

Reviewed By: hanchung, ThomasRaoux

Differential Revision: https://reviews.llvm.org/D93535

Added: 


Modified: 
mlir/lib/Target/SPIRV/Serialization.cpp
mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp

Removed: 




diff  --git a/mlir/lib/Target/SPIRV/Serialization.cpp 
b/mlir/lib/Target/SPIRV/Serialization.cpp
index db00f5ecf899..c530cccd4232 100644
--- a/mlir/lib/Target/SPIRV/Serialization.cpp
+++ b/mlir/lib/Target/SPIRV/Serialization.cpp
@@ -364,15 +364,23 @@ class Serializer {
   /// Main dispatch method for serializing an operation.
   LogicalResult processOperation(Operation *op);
 
-  /// Method to dispatch to the serialization function for an operation in
-  /// SPIR-V dialect that is a mirror of an instruction in the SPIR-V spec.
-  /// This is auto-generated from ODS. Dispatch is handled for all operations
-  /// in SPIR-V dialect that have hasOpcode == 1.
+  /// Serializes an operation `op` as core instruction with `opcode` if
+  /// `extInstSet` is empty. Otherwise serializes it as an extended instruction
+  /// with `opcode` from `extInstSet`.
+  /// This method is a generic one for dispatching any SPIR-V ops that has no
+  /// variadic operands and attributes in TableGen definitions.
+  LogicalResult processOpWithoutGrammarAttr(Operation *op, StringRef 
extInstSet,
+uint32_t opcode);
+
+  /// Dispatches to the serialization function for an operation in SPIR-V
+  /// dialect that is a mirror of an instruction in the SPIR-V spec. This is
+  /// auto-generated from ODS. Dispatch is handled for all operations in SPIR-V
+  /// dialect that have hasOpcode == 1.
   LogicalResult dispatchToAutogenSerialization(Operation *op);
 
-  /// Method to serialize an operation in the SPIR-V dialect that is a mirror 
of
-  /// an instruction in the SPIR-V spec. This is auto generated if hasOpcode ==
-  /// 1 and autogenSerialization == 1 in ODS.
+  /// Serializes an operation in the SPIR-V dialect that is a mirror of an
+  /// instruction in the SPIR-V spec. This is auto generated if hasOpcode == 1
+  /// and autogenSerialization == 1 in ODS.
   template 
   LogicalResult processOp(OpTy op) {
 return op.emitError("unsupported op serialization");
@@ -1930,6 +1938,46 @@ LogicalResult Serializer::processOperation(Operation 
*opInst) {
   [&](Operation *op) { return dispatchToAutogenSerialization(op); });
 }
 
+LogicalResult Serializer::processOpWithoutGrammarAttr(Operation *op,
+  StringRef extInstSet,
+  uint32_t opcode) {
+  SmallVector operands;
+  Location loc = op->getLoc();
+
+  uint32_t resultID = 0;
+  if (op->getNumResults() != 0) {
+uint32_t resultTypeID = 0;
+if (failed(processType(loc, op->getResult(0).getType(), resultTypeID)))
+  return failure();
+operands.push_back(resultTypeID);
+
+resultID = getNextID();
+operands.push_back(resultID);
+valueIDMap[op->getResult(0)] = resultID;
+  };
+
+  for (Value operand : op->getOperands())
+operands.push_back(getValueID(operand));
+
+  emitDebugLine(functionBody, loc);
+
+  if (extInstSet.empty()) {
+encodeInstructionInto(functionBody, static_cast(opcode),
+  operands);
+  } else {
+encodeExtensionInstruction(op, extInstSet, opcode, operands);
+  }
+
+  if (op->getNumResults() != 0) {
+for (auto attr : op->getAttrs()) {
+  if (failed(processDecoration(loc, resultID, attr)))
+return failure();
+}
+  }
+
+  return success();
+}
+
 namespace {
 template <>
 LogicalResult

diff  --git a/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp 
b/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
index ab520114e7f5..74fe1e0fdb08 100644
--- a/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
+++ b/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
@@ -647,8 +647,7 @@ static void emitDecorationSerialization(const Operator &op, 
StringRef tabs,
 // All non-argument attributes translated into OpDecorate instruction
 os << tabs << formatv("for (auto attr : {0}->getAttrs()) {{\n", opVar);
 os << tabs
-   << formatv("  if (llvm::any_of({0}, [&](StringRef elided)", 
elidedAttrs);
-os << " {return 

[llvm-branch-commits] [mlir] f2a0687 - Wrap CfgTraitsFor in namespace llvm to please GCC 5

2020-10-20 Thread Lei Zhang via llvm-branch-commits

Author: Lei Zhang
Date: 2020-10-20T13:04:02-04:00
New Revision: f2a06875b604c00cbe96e54363f4f5d28935d610

URL: 
https://github.com/llvm/llvm-project/commit/f2a06875b604c00cbe96e54363f4f5d28935d610
DIFF: 
https://github.com/llvm/llvm-project/commit/f2a06875b604c00cbe96e54363f4f5d28935d610.diff

LOG: Wrap CfgTraitsFor in namespace llvm to please GCC 5

Added: 


Modified: 
mlir/include/mlir/IR/Dominance.h

Removed: 




diff  --git a/mlir/include/mlir/IR/Dominance.h 
b/mlir/include/mlir/IR/Dominance.h
index 24d718362e13..7b41f8b0896d 100644
--- a/mlir/include/mlir/IR/Dominance.h
+++ b/mlir/include/mlir/IR/Dominance.h
@@ -45,10 +45,11 @@ class CfgTraits : public llvm::CfgTraits {
 
 } // namespace mlir
 
-template <>
-struct llvm::CfgTraitsFor {
+namespace llvm {
+template <> struct CfgTraitsFor {
   using CfgTraits = mlir::CfgTraits;
 };
+} // namespace llvm
 
 extern template class llvm::DominatorTreeBase;
 extern template class llvm::DominatorTreeBase;



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] 6c69d3d - [MLIR][SPIRV] Add initial support for OpSpecConstantOp.

2020-12-08 Thread Lei Zhang via llvm-branch-commits

Author: ergawy
Date: 2020-12-08T09:07:52-05:00
New Revision: 6c69d3d68e9a4438b47422e49c0f2d69e2b8e1b7

URL: 
https://github.com/llvm/llvm-project/commit/6c69d3d68e9a4438b47422e49c0f2d69e2b8e1b7
DIFF: 
https://github.com/llvm/llvm-project/commit/6c69d3d68e9a4438b47422e49c0f2d69e2b8e1b7.diff

LOG: [MLIR][SPIRV] Add initial support for OpSpecConstantOp.

This commit adds initial support for SPIR-V OpSpecConstantOp
instruction. The following is introdcued:

- A new `spv.specConstantOperation` operation consisting of a single
region and of 2 operations within that regions (more details in the
docs of the op itself).
- A new `spv.yield` instruction that acts a terminator for
`spv.specConstantOperation`.

For now, the generic form of the new op is supported (i.e. no custom
parsing or printing). This will be done in a follow up patch.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D92232

Added: 


Modified: 
mlir/include/mlir/Dialect/SPIRV/SPIRVStructureOps.td
mlir/lib/Dialect/SPIRV/SPIRVOps.cpp
mlir/test/Dialect/SPIRV/structure-ops.mlir

Removed: 




diff  --git a/mlir/include/mlir/Dialect/SPIRV/SPIRVStructureOps.td 
b/mlir/include/mlir/Dialect/SPIRV/SPIRVStructureOps.td
index 0b1f6d294ac0..b8e76c3662ec 100644
--- a/mlir/include/mlir/Dialect/SPIRV/SPIRVStructureOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/SPIRVStructureOps.td
@@ -607,6 +607,130 @@ def SPV_SpecConstantCompositeOp : 
SPV_Op<"specConstantComposite", [InModuleScope
 
   let autogenSerialization = 0;
 }
+
+def SPV_YieldOp : SPV_Op<"mlir.yield", [NoSideEffect, Terminator]> {
+  let summary = "Yields the result computed in `spv.SpecConstantOperation`'s"
+"region back to the parent op.";
+
+  let description = [{
+This op is a special terminator whose only purpose is to terminate
+an `spv.SpecConstantOperation`'s enclosed region. It accepts a
+single operand produced by the preceeding (and only other) instruction
+in its parent block (see SPV_SpecConstantOperation for further
+details). This op has no corresponding SPIR-V instruction.
+
+```
+spv.mlir.yield ::= `spv.mlir.yield` ssa-id : spirv-type
+```
+
+ Example:
+```mlir
+%0 = ... (some op supported by SPIR-V OpSpecConstantOp)
+spv.mlir.yield %0
+```
+  }];
+
+  let arguments = (ins AnyType:$operand);
+
+  let results = (outs);
+
+  let hasOpcode = 0;
+
+  let autogenSerialization = 0;
+
+  let assemblyFormat = "attr-dict $operand `:` type($operand)";
+}
+
+def SPV_SpecConstantOperationOp : SPV_Op<"SpecConstantOperation", [
+ InFunctionScope, NoSideEffect,
+ IsolatedFromAbove]> {
+  let summary = "Declare a new specialization constant that results from doing 
an operation.";
+
+  let description = [{
+This op declares a SPIR-V specialization constant that results from
+doing an operation on other constants (specialization or otherwise).
+
+In the `spv` dialect, this op is modelled as follows:
+
+```
+spv-spec-constant-operation-op ::= `"spv.SpecConstantOperation"`
+ `(`ssa-id (`, ` ssa-id)`)`
+   `({`
+ ssa-id = spirv-op
+ `spv.mlir.yield` ssa-id
+   `})` `:` function-type
+```
+
+In particular, an `spv.SpecConstantOperation` contains exactly one
+region. In turn, that region, contains exactly 2 instructions:
+- One of SPIR-V's instructions that are allowed within an
+OpSpecConstantOp.
+- An `spv.mlir.yield` instruction as the terminator.
+
+The following SPIR-V instructions are valid:
+- OpSConvert,
+- OpUConvert,
+- OpFConvert,
+- OpSNegate,
+- OpNot,
+- OpIAdd,
+- OpISub,
+- OpIMul,
+- OpUDiv,
+- OpSDiv,
+- OpUMod,
+- OpSRem,
+- OpSMod
+- OpShiftRightLogical,
+- OpShiftRightArithmetic,
+- OpShiftLeftLogical
+- OpBitwiseOr,
+- OpBitwiseXor,
+- OpBitwiseAnd
+- OpVectorShuffle,
+- OpCompositeExtract,
+- OpCompositeInsert
+- OpLogicalOr,
+- OpLogicalAnd,
+- OpLogicalNot,
+- OpLogicalEqual,
+- OpLogicalNotEqual
+- OpSelect
+- OpIEqual,
+- OpINotEqual
+- OpULessThan,
+- OpSLessThan
+- OpUGreaterThan,
+- OpSGreaterThan
+- OpULessThanEqual,
+- OpSLessThanEqual
+- OpUGreaterThanEqual,
+- OpSGreaterThanEqual
+
+TODO Add capability-specific ops when supported.
+
+ Example:
+```mlir
+%0 = spv.constant 1: i32
+
+%1 = "spv.SpecConstantOperation"(%0) ({
+  %ret = spv.IAdd %0, %0 : i32
+  spv.mlir.yield %ret : i32
+}) : (i32) -> i32
+```
+  }];
+
+  let arguments = (ins Variadic:$operands);
+
+  let results = (ou

[llvm-branch-commits] [mlir] 076f87a - [MLIR][SPIRV] Add support for GLSL F/U/SClamp.

2020-12-13 Thread Lei Zhang via llvm-branch-commits

Author: ergawy
Date: 2020-12-13T09:56:46-05:00
New Revision: 076f87a86741f96c076cea9f9f2af17de55122a3

URL: 
https://github.com/llvm/llvm-project/commit/076f87a86741f96c076cea9f9f2af17de55122a3
DIFF: 
https://github.com/llvm/llvm-project/commit/076f87a86741f96c076cea9f9f2af17de55122a3.diff

LOG: [MLIR][SPIRV] Add support for GLSL F/U/SClamp.

Adds support for 3 ternary ops from SPIR-V extended instructions for
GLSL. Namely, adds support for FClamp, UClamp, and SClamp.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D92859

Added: 


Modified: 
mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td
mlir/include/mlir/Dialect/SPIRV/SPIRVGLSLOps.td
mlir/test/Dialect/SPIRV/Serialization/glsl-ops.mlir
mlir/test/Dialect/SPIRV/glslops.mlir

Removed: 




diff  --git a/mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td 
b/mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td
index 54e5efe5f295..0d80ecc8ddda 100644
--- a/mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td
+++ b/mlir/include/mlir/Dialect/SPIRV/SPIRVBase.td
@@ -3075,6 +3075,7 @@ def SPV_Type : AnyTypeOf<[
 SPV_AnyCooperativeMatrix, SPV_AnyMatrix
   ]>;
 
+def SPV_SignedInt : SignedIntOfWidths<[8, 16, 32, 64]>;
 def SPV_SignlessOrUnsignedInt : SignlessOrUnsignedIntOfWidths<[8, 16, 32, 64]>;
 
 class SPV_CoopMatrixOfType allowedTypes> :

diff  --git a/mlir/include/mlir/Dialect/SPIRV/SPIRVGLSLOps.td 
b/mlir/include/mlir/Dialect/SPIRV/SPIRVGLSLOps.td
index 10cafd825116..73745fe4694e 100644
--- a/mlir/include/mlir/Dialect/SPIRV/SPIRVGLSLOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/SPIRVGLSLOps.td
@@ -77,6 +77,28 @@ class SPV_GLSLBinaryArithmeticOp traits = []> :
   SPV_GLSLBinaryOp;
 
+// Base class for GLSL ternary ops.
+class SPV_GLSLTernaryArithmeticOp traits = []> :
+  SPV_GLSLOp {
+
+  let arguments = (ins
+SPV_ScalarOrVectorOf:$x,
+SPV_ScalarOrVectorOf:$y,
+SPV_ScalarOrVectorOf:$z
+  );
+
+  let results = (outs
+SPV_ScalarOrVectorOf:$result
+  );
+
+  let parser = [{ return impl::parseOneResultSameOperandTypeOp(parser, 
result); }];
+
+  let printer = [{ return impl::printOneResultOp(getOperation(), p); }];
+
+  let verifier = [{ return success(); }];
+}
+
 // -
 
 def SPV_GLSLFAbsOp : SPV_GLSLUnaryArithmeticOp<"FAbs", 4, SPV_Float> {
@@ -862,4 +884,92 @@ def SPV_GLSLTanhOp : SPV_GLSLUnaryArithmeticOp<"Tanh", 21, 
SPV_Float16or32> {
   }];
 }
 
+// -
+
+def SPV_GLSLFClampOp : SPV_GLSLTernaryArithmeticOp<"FClamp", 43, SPV_Float> {
+  let summary = "Clamp x between min and max values.";
+
+  let description = [{
+Result is min(max(x, minVal), maxVal). The resulting value is undefined if
+minVal > maxVal. The semantics used by min() and max() are those of FMin 
and
+FMax.
+
+The operands must all be a scalar or vector whose component type is
+floating-point.
+
+Result Type and the type of all operands must be the same type. Results are
+computed per component.
+
+
+```
+fclamp-op ::= ssa-id `=` `spv.GLSL.FClamp` ssa-use, ssa-use, ssa-use `:`
+   float-scalar-vector-type
+```
+ Example:
+
+```mlir
+%2 = spv.GLSL.FClamp %x, %min, %max : f32
+%3 = spv.GLSL.FClamp %x, %min, %max : vector<3xf16>
+```
+  }];
+}
+
+// -
+
+def SPV_GLSLUClampOp : SPV_GLSLTernaryArithmeticOp<"UClamp", 44, 
SPV_SignlessOrUnsignedInt> {
+  let summary = "Clamp x between min and max values.";
+
+  let description = [{
+Result is min(max(x, minVal), maxVal), where x, minVal and maxVal are
+interpreted as unsigned integers. The resulting value is undefined if
+minVal > maxVal.
+
+Result Type and the type of the operands must both be integer scalar or
+integer vector types. Result Type and operand types must have the same 
number
+of components with the same component width. Results are computed per
+component.
+
+
+```
+uclamp-op ::= ssa-id `=` `spv.GLSL.UClamp` ssa-use, ssa-use, ssa-use `:`
+   unsgined-signless-scalar-vector-type
+```
+ Example:
+
+```mlir
+%2 = spv.GLSL.UClamp %x, %min, %max : i32
+%3 = spv.GLSL.UClamp %x, %min, %max : vector<3xui16>
+```
+  }];
+}
+
+// -
+
+def SPV_GLSLSClampOp : SPV_GLSLTernaryArithmeticOp<"SClamp", 45, 
SPV_SignedInt> {
+  let summary = "Clamp x between min and max values.";
+
+  let description = [{
+Result is min(max(x, minVal), maxVal), where x, minVal and maxVal are
+interpreted as signed integers. The resulting value is undefined if
+minVal > maxVal.
+
+Result Type and the type of the operands must both be integer scalar or
+integer vector types. Result Type and operand types must have the same 
number
+of components with the same component width. Results are computed per
+component.
+
+
+```
+uclamp-op ::= ssa-id `=` `spv.GLSL.UClamp` ssa-use, ssa-use, ssa-use `:`
+   sgined-scalar-vector-type
+