[Mlir-commits] [mlir] [mlir][spirv] Add missing group non-uniform bitwise and logical ops (PR #73475)

Jakub Kuderski llvmlistbot at llvm.org
Sun Nov 26 19:29:01 PST 2023


https://github.com/kuhar created https://github.com/llvm/llvm-project/pull/73475

This covers the following ops:
`spirv.GroupNonUniform` x {`Bitwise`, `Logical`} x {`And`, `Or`, `Xor`}

We need these to efficiently lower from the `gpu.subgroup_reduce` op.

>From e64a5e349ce7cefef99985a5ac6b02c7698f9f1d Mon Sep 17 00:00:00 2001
From: Jakub Kuderski <jakub at nod-labs.com>
Date: Sun, 26 Nov 2023 22:26:05 -0500
Subject: [PATCH] [mlir][spirv] Add missing group non-uniform bitwise and
 logical ops

This covers the following ops:
`spirv.GroupNonUniform` x {`Bitwise`, `Logical`} x {`And`, `Or`, `Xor`}

We need these to efficiently lower from the `gpu.subgroup_reduce` op.
---
 .../mlir/Dialect/SPIRV/IR/SPIRVBase.td        |   9 +
 .../Dialect/SPIRV/IR/SPIRVNonUniformOps.td    | 300 ++++++++++++++++++
 mlir/lib/Dialect/SPIRV/IR/GroupOps.cpp        | 102 ++++++
 .../Dialect/SPIRV/IR/non-uniform-ops.mlir     | 126 ++++++++
 4 files changed, 537 insertions(+)

diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
index f315da356e0d2c6..ee1fbba1e2844e4 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
@@ -4462,6 +4462,12 @@ def SPIRV_OC_OpGroupNonUniformFMin        : I32EnumAttrCase<"OpGroupNonUniformFM
 def SPIRV_OC_OpGroupNonUniformSMax        : I32EnumAttrCase<"OpGroupNonUniformSMax", 356>;
 def SPIRV_OC_OpGroupNonUniformUMax        : I32EnumAttrCase<"OpGroupNonUniformUMax", 357>;
 def SPIRV_OC_OpGroupNonUniformFMax        : I32EnumAttrCase<"OpGroupNonUniformFMax", 358>;
+def SPIRV_OC_OpGroupNonUniformBitwiseAnd  : I32EnumAttrCase<"OpGroupNonUniformBitwiseAnd", 359>;
+def SPIRV_OC_OpGroupNonUniformBitwiseOr   : I32EnumAttrCase<"OpGroupNonUniformBitwiseOr", 360>;
+def SPIRV_OC_OpGroupNonUniformBitwiseXor  : I32EnumAttrCase<"OpGroupNonUniformBitwiseXor", 361>;
+def SPIRV_OC_OpGroupNonUniformLogicalAnd  : I32EnumAttrCase<"OpGroupNonUniformLogicalAnd", 362>;
+def SPIRV_OC_OpGroupNonUniformLogicalOr   : I32EnumAttrCase<"OpGroupNonUniformLogicalOr", 363>;
+def SPIRV_OC_OpGroupNonUniformLogicalXor  : I32EnumAttrCase<"OpGroupNonUniformLogicalXor", 364>;
 def SPIRV_OC_OpSubgroupBallotKHR          : I32EnumAttrCase<"OpSubgroupBallotKHR", 4421>;
 def SPIRV_OC_OpSDot                       : I32EnumAttrCase<"OpSDot", 4450>;
 def SPIRV_OC_OpUDot                       : I32EnumAttrCase<"OpUDot", 4451>;
@@ -4570,6 +4576,9 @@ def SPIRV_OpcodeAttr :
       SPIRV_OC_OpGroupNonUniformSMin, SPIRV_OC_OpGroupNonUniformUMin,
       SPIRV_OC_OpGroupNonUniformFMin, SPIRV_OC_OpGroupNonUniformSMax,
       SPIRV_OC_OpGroupNonUniformUMax, SPIRV_OC_OpGroupNonUniformFMax,
+      SPIRV_OC_OpGroupNonUniformBitwiseAnd, SPIRV_OC_OpGroupNonUniformBitwiseOr,
+      SPIRV_OC_OpGroupNonUniformBitwiseXor, SPIRV_OC_OpGroupNonUniformLogicalAnd,
+      SPIRV_OC_OpGroupNonUniformLogicalOr, SPIRV_OC_OpGroupNonUniformLogicalXor,
       SPIRV_OC_OpSubgroupBallotKHR, SPIRV_OC_OpSDot, SPIRV_OC_OpUDot,
       SPIRV_OC_OpSUDot, SPIRV_OC_OpSDotAccSat, SPIRV_OC_OpUDotAccSat,
       SPIRV_OC_OpSUDotAccSat,
diff --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVNonUniformOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVNonUniformOps.td
index df29b632f958e5e..4d717b6b7a551eb 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVNonUniformOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVNonUniformOps.td
@@ -997,4 +997,304 @@ def SPIRV_GroupNonUniformUMinOp : SPIRV_GroupNonUniformArithmeticOp<"GroupNonUni
 
 // -----
 
+def SPIRV_GroupNonUniformBitwiseAndOp :
+  SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformBitwiseAnd",
+    SPIRV_Integer, []> {
+  let summary = [{
+    A bitwise `and` group operation of all Value operands contributed by active
+    invocations in the group.
+  }];
+
+  let description = [{
+    Result Type must be a scalar or vector of integer type.
+
+    Execution is a Scope. It must be either Workgroup or Subgroup.
+
+    The identity I for Operation is ~0. If Operation is ClusteredReduce,
+    ClusterSize must be present.
+
+    The type of Value must be the same as Result Type.
+
+    ClusterSize is the size of cluster to use. ClusterSize must be a scalar
+    of integer type, whose Signedness operand is 0. ClusterSize must come
+    from a constant instruction. ClusterSize must be at least 1, and must be
+    a power of 2. If ClusterSize is greater than the declared SubGroupSize,
+    executing this instruction results in undefined behavior.
+
+    <!-- End of AutoGen section -->
+
+    #### Example:
+
+    ```mlir
+    %four = spirv.Constant 4 : i32
+    %scalar = ... : i32
+    %vector = ... : vector<4xi32>
+    %0 = spirv.GroupNonUniformBitwiseAnd "Workgroup" "Reduce" %scalar : i32
+    %1 = spirv.GroupNonUniformBitwiseAnd "Subgroup" "ClusteredReduce"
+           %vector cluster_size(%four) : vector<4xi32>
+    ```
+  }];
+
+  let availability = [
+    MinVersion<SPIRV_V_1_3>,
+    MaxVersion<SPIRV_V_1_6>,
+    Extension<[]>,
+    Capability<[SPIRV_C_GroupNonUniformArithmetic,
+                SPIRV_C_GroupNonUniformClustered,
+                SPIRV_C_GroupNonUniformPartitionedNV]>
+  ];
+}
+
+// -----
+
+def SPIRV_GroupNonUniformBitwiseOrOp :
+  SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformBitwiseOr",
+    SPIRV_Integer, []> {
+  let summary = [{
+    A bitwise `or` group operation of all Value operands contributed by active
+    invocations in the group.
+  }];
+
+  let description = [{
+    Result Type must be a scalar or vector of integer type.
+
+    Execution is a Scope. It must be either Workgroup or Subgroup.
+
+    The identity I for Operation is 0. If Operation is ClusteredReduce,
+    ClusterSize must be present.
+
+    The type of Value must be the same as Result Type.
+
+    ClusterSize is the size of cluster to use. ClusterSize must be a scalar
+    of integer type, whose Signedness operand is 0. ClusterSize must come
+    from a constant instruction. ClusterSize must be at least 1, and must be
+    a power of 2. If ClusterSize is greater than the declared SubGroupSize,
+    executing this instruction results in undefined behavior.
+
+    <!-- End of AutoGen section -->
+
+    #### Example:
+
+    ```mlir
+    %four = spirv.Constant 4 : i32
+    %scalar = ... : i32
+    %vector = ... : vector<4xi32>
+    %0 = spirv.GroupNonUniformBitwiseOr "Workgroup" "Reduce" %scalar : i32
+    %1 = spirv.GroupNonUniformBitwiseOr "Subgroup" "ClusteredReduce"
+           %vector cluster_size(%four) : vector<4xi32>
+    ```
+  }];
+
+  let availability = [
+    MinVersion<SPIRV_V_1_3>,
+    MaxVersion<SPIRV_V_1_6>,
+    Extension<[]>,
+    Capability<[SPIRV_C_GroupNonUniformArithmetic,
+                SPIRV_C_GroupNonUniformClustered,
+                SPIRV_C_GroupNonUniformPartitionedNV]>
+  ];
+}
+
+// -----
+
+def SPIRV_GroupNonUniformBitwiseXorOp :
+  SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformBitwiseXor",
+    SPIRV_Integer, []> {
+  let summary = [{
+    A bitwise `xor` group operation of all Value operands contributed by active
+    invocations in the group.
+  }];
+
+  let description = [{
+    Result Type must be a scalar or vector of integer type.
+
+    Execution is a Scope. It must be either Workgroup or Subgroup.
+
+    The identity I for Operation is 0. If Operation is ClusteredReduce,
+    ClusterSize must be present.
+
+    The type of Value must be the same as Result Type.
+
+    ClusterSize is the size of cluster to use. ClusterSize must be a scalar
+    of integer type, whose Signedness operand is 0. ClusterSize must come
+    from a constant instruction. ClusterSize must be at least 1, and must be
+    a power of 2. If ClusterSize is greater than the declared SubGroupSize,
+    executing this instruction results in undefined behavior.
+
+    <!-- End of AutoGen section -->
+
+    #### Example:
+
+    ```mlir
+    %four = spirv.Constant 4 : i32
+    %scalar = ... : i32
+    %vector = ... : vector<4xi32>
+    %0 = spirv.GroupNonUniformBitwiseXor "Workgroup" "Reduce" %scalar : i32
+    %1 = spirv.GroupNonUniformBitwiseXor "Subgroup" "ClusteredReduce"
+           %vector cluster_size(%four) : vector<4xi32>
+    ```
+  }];
+
+  let availability = [
+    MinVersion<SPIRV_V_1_3>,
+    MaxVersion<SPIRV_V_1_6>,
+    Extension<[]>,
+    Capability<[SPIRV_C_GroupNonUniformArithmetic,
+                SPIRV_C_GroupNonUniformClustered,
+                SPIRV_C_GroupNonUniformPartitionedNV]>
+  ];
+}
+
+// -----
+
+def SPIRV_GroupNonUniformLogicalAndOp :
+  SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformLogicalAnd",
+    SPIRV_Bool, []> {
+  let summary = [{
+    A logical `and` group operation of all Value operands contributed by active
+    invocations in the group.
+  }];
+
+  let description = [{
+    Result Type must be a scalar or vector of Boolean type.
+
+    Execution is a Scope. It must be either Workgroup or Subgroup.
+
+    The identity I for Operation is ~0. If Operation is ClusteredReduce,
+    ClusterSize must be present.
+
+    The type of Value must be the same as Result Type.
+
+    ClusterSize is the size of cluster to use. ClusterSize must be a scalar
+    of integer type, whose Signedness operand is 0. ClusterSize must come
+    from a constant instruction. ClusterSize must be at least 1, and must be
+    a power of 2. If ClusterSize is greater than the declared SubGroupSize,
+    executing this instruction results in undefined behavior.
+
+    <!-- End of AutoGen section -->
+
+    #### Example:
+
+    ```mlir
+    %four = spirv.Constant 4 : i32
+    %scalar = ... : i1
+    %vector = ... : vector<4xi1>
+    %0 = spirv.GroupNonUniformLogicalAnd "Workgroup" "Reduce" %scalar : i1
+    %1 = spirv.GroupNonUniformLogicalAnd "Subgroup" "ClusteredReduce"
+           %vector cluster_size(%four) : vector<4xi1>
+    ```
+  }];
+
+  let availability = [
+    MinVersion<SPIRV_V_1_3>,
+    MaxVersion<SPIRV_V_1_6>,
+    Extension<[]>,
+    Capability<[SPIRV_C_GroupNonUniformArithmetic,
+                SPIRV_C_GroupNonUniformClustered,
+                SPIRV_C_GroupNonUniformPartitionedNV]>
+  ];
+}
+
+// -----
+
+def SPIRV_GroupNonUniformLogicalOrOp :
+  SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformLogicalOr",
+    SPIRV_Bool, []> {
+  let summary = [{
+    A logical `or` group operation of all Value operands contributed by active
+    invocations in the group.
+  }];
+
+  let description = [{
+    Result Type must be a scalar or vector of Boolean type.
+
+    Execution is a Scope. It must be either Workgroup or Subgroup.
+
+    The identity I for Operation is 0. If Operation is ClusteredReduce,
+    ClusterSize must be present.
+
+    The type of Value must be the same as Result Type.
+
+    ClusterSize is the size of cluster to use. ClusterSize must be a scalar
+    of integer type, whose Signedness operand is 0. ClusterSize must come
+    from a constant instruction. ClusterSize must be at least 1, and must be
+    a power of 2. If ClusterSize is greater than the declared SubGroupSize,
+    executing this instruction results in undefined behavior.
+
+    <!-- End of AutoGen section -->
+
+    #### Example:
+
+    ```mlir
+    %four = spirv.Constant 4 : i32
+    %scalar = ... : i1
+    %vector = ... : vector<4xi1>
+    %0 = spirv.GroupNonUniformLogicalOr "Workgroup" "Reduce" %scalar : i1
+    %1 = spirv.GroupNonUniformLogicalOr "Subgroup" "ClusteredReduce"
+           %vector cluster_size(%four) : vector<4xi1>
+    ```
+  }];
+
+  let availability = [
+    MinVersion<SPIRV_V_1_3>,
+    MaxVersion<SPIRV_V_1_6>,
+    Extension<[]>,
+    Capability<[SPIRV_C_GroupNonUniformArithmetic,
+                SPIRV_C_GroupNonUniformClustered,
+                SPIRV_C_GroupNonUniformPartitionedNV]>
+  ];
+}
+
+// -----
+
+def SPIRV_GroupNonUniformLogicalXorOp :
+  SPIRV_GroupNonUniformArithmeticOp<"GroupNonUniformLogicalXor",
+    SPIRV_Bool, []> {
+  let summary = [{
+    A logical `xor` group operation of all Value operands contributed by active
+    invocations in the group.
+  }];
+
+  let description = [{
+    Result Type must be a scalar or vector of Boolean type.
+
+    Execution is a Scope. It must be either Workgroup or Subgroup.
+
+    The identity I for Operation is 0. If Operation is ClusteredReduce,
+    ClusterSize must be present.
+
+    The type of Value must be the same as Result Type.
+
+    ClusterSize is the size of cluster to use. ClusterSize must be a scalar
+    of integer type, whose Signedness operand is 0. ClusterSize must come
+    from a constant instruction. ClusterSize must be at least 1, and must be
+    a power of 2. If ClusterSize is greater than the declared SubGroupSize,
+    executing this instruction results in undefined behavior.
+
+    <!-- End of AutoGen section -->
+
+    #### Example:
+
+    ```mlir
+    %four = spirv.Constant 4 : i32
+    %scalar = ... : i1
+    %vector = ... : vector<4xi1>
+    %0 = spirv.GroupNonUniformLogicalXor "Workgroup" "Reduce" %scalar : i1
+    %1 = spirv.GroupNonUniformLogicalXor "Subgroup" "ClusteredReduce"
+           %vector cluster_size(%four) : vector<4xi>
+    ```
+  }];
+
+  let availability = [
+    MinVersion<SPIRV_V_1_3>,
+    MaxVersion<SPIRV_V_1_6>,
+    Extension<[]>,
+    Capability<[SPIRV_C_GroupNonUniformArithmetic,
+                SPIRV_C_GroupNonUniformClustered,
+                SPIRV_C_GroupNonUniformPartitionedNV]>
+  ];
+}
+
+// -----
+
 #endif // MLIR_DIALECT_SPIRV_IR_NON_UNIFORM_OPS
diff --git a/mlir/lib/Dialect/SPIRV/IR/GroupOps.cpp b/mlir/lib/Dialect/SPIRV/IR/GroupOps.cpp
index 84bf3de2f43aab7..ac29ab0db586cf7 100644
--- a/mlir/lib/Dialect/SPIRV/IR/GroupOps.cpp
+++ b/mlir/lib/Dialect/SPIRV/IR/GroupOps.cpp
@@ -371,6 +371,108 @@ void GroupNonUniformUMinOp::print(OpAsmPrinter &p) {
   printGroupNonUniformArithmeticOp(*this, p);
 }
 
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformBitwiseAnd
+//===----------------------------------------------------------------------===//
+
+LogicalResult GroupNonUniformBitwiseAndOp::verify() {
+  return verifyGroupNonUniformArithmeticOp(*this);
+}
+
+ParseResult GroupNonUniformBitwiseAndOp::parse(OpAsmParser &parser,
+                                               OperationState &result) {
+  return parseGroupNonUniformArithmeticOp(parser, result);
+}
+
+void GroupNonUniformBitwiseAndOp::print(OpAsmPrinter &p) {
+  printGroupNonUniformArithmeticOp(*this, p);
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformBitwiseOr
+//===----------------------------------------------------------------------===//
+
+LogicalResult GroupNonUniformBitwiseOrOp::verify() {
+  return verifyGroupNonUniformArithmeticOp(*this);
+}
+
+ParseResult GroupNonUniformBitwiseOrOp::parse(OpAsmParser &parser,
+                                              OperationState &result) {
+  return parseGroupNonUniformArithmeticOp(parser, result);
+}
+
+void GroupNonUniformBitwiseOrOp::print(OpAsmPrinter &p) {
+  printGroupNonUniformArithmeticOp(*this, p);
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformBitwiseXor
+//===----------------------------------------------------------------------===//
+
+LogicalResult GroupNonUniformBitwiseXorOp::verify() {
+  return verifyGroupNonUniformArithmeticOp(*this);
+}
+
+ParseResult GroupNonUniformBitwiseXorOp::parse(OpAsmParser &parser,
+                                               OperationState &result) {
+  return parseGroupNonUniformArithmeticOp(parser, result);
+}
+
+void GroupNonUniformBitwiseXorOp::print(OpAsmPrinter &p) {
+  printGroupNonUniformArithmeticOp(*this, p);
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformLogicalAnd
+//===----------------------------------------------------------------------===//
+
+LogicalResult GroupNonUniformLogicalAndOp::verify() {
+  return verifyGroupNonUniformArithmeticOp(*this);
+}
+
+ParseResult GroupNonUniformLogicalAndOp::parse(OpAsmParser &parser,
+                                               OperationState &result) {
+  return parseGroupNonUniformArithmeticOp(parser, result);
+}
+
+void GroupNonUniformLogicalAndOp::print(OpAsmPrinter &p) {
+  printGroupNonUniformArithmeticOp(*this, p);
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformLogicalOr
+//===----------------------------------------------------------------------===//
+
+LogicalResult GroupNonUniformLogicalOrOp::verify() {
+  return verifyGroupNonUniformArithmeticOp(*this);
+}
+
+ParseResult GroupNonUniformLogicalOrOp::parse(OpAsmParser &parser,
+                                              OperationState &result) {
+  return parseGroupNonUniformArithmeticOp(parser, result);
+}
+
+void GroupNonUniformLogicalOrOp::print(OpAsmPrinter &p) {
+  printGroupNonUniformArithmeticOp(*this, p);
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformLogicalXor
+//===----------------------------------------------------------------------===//
+
+LogicalResult GroupNonUniformLogicalXorOp::verify() {
+  return verifyGroupNonUniformArithmeticOp(*this);
+}
+
+ParseResult GroupNonUniformLogicalXorOp::parse(OpAsmParser &parser,
+                                               OperationState &result) {
+  return parseGroupNonUniformArithmeticOp(parser, result);
+}
+
+void GroupNonUniformLogicalXorOp::print(OpAsmPrinter &p) {
+  printGroupNonUniformArithmeticOp(*this, p);
+}
+
 //===----------------------------------------------------------------------===//
 // Group op verification
 //===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/SPIRV/IR/non-uniform-ops.mlir b/mlir/test/Dialect/SPIRV/IR/non-uniform-ops.mlir
index 11a8614a89d2599..f7fd05b36bae062 100644
--- a/mlir/test/Dialect/SPIRV/IR/non-uniform-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/non-uniform-ops.mlir
@@ -422,3 +422,129 @@ func.func @group_non_uniform_umin_reduce(%val: i32) -> i32 {
   %0 = spirv.GroupNonUniformUMin "Workgroup" "Reduce" %val : i32
   return %0: i32
 }
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformBitwiseAnd
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @group_non_uniform_bitwise_and
+func.func @group_non_uniform_bitwise_and(%val: i32) -> i32 {
+  // CHECK: %{{.+}} = spirv.GroupNonUniformBitwiseAnd "Workgroup" "Reduce" %{{.+}} : i32
+  %0 = spirv.GroupNonUniformBitwiseAnd "Workgroup" "Reduce" %val : i32
+  return %0: i32
+}
+
+// -----
+
+func.func @group_non_uniform_bitwise_and(%val: i1) -> i1 {
+  // expected-error @+1 {{operand #0 must be 8/16/32/64-bit integer or vector of 8/16/32/64-bit integer values of length 2/3/4/8/16, but got 'i1'}}
+  %0 = spirv.GroupNonUniformBitwiseAnd "Workgroup" "Reduce" %val : i1
+  return %0: i1
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformBitwiseOr
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @group_non_uniform_bitwise_or
+func.func @group_non_uniform_bitwise_or(%val: i32) -> i32 {
+  // CHECK: %{{.+}} = spirv.GroupNonUniformBitwiseOr "Workgroup" "Reduce" %{{.+}} : i32
+  %0 = spirv.GroupNonUniformBitwiseOr "Workgroup" "Reduce" %val : i32
+  return %0: i32
+}
+
+// -----
+
+func.func @group_non_uniform_bitwise_or(%val: i1) -> i1 {
+  // expected-error @+1 {{operand #0 must be 8/16/32/64-bit integer or vector of 8/16/32/64-bit integer values of length 2/3/4/8/16, but got 'i1'}}
+  %0 = spirv.GroupNonUniformBitwiseOr "Workgroup" "Reduce" %val : i1
+  return %0: i1
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformBitwiseXor
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @group_non_uniform_bitwise_xor
+func.func @group_non_uniform_bitwise_xor(%val: i32) -> i32 {
+  // CHECK: %{{.+}} = spirv.GroupNonUniformBitwiseXor "Workgroup" "Reduce" %{{.+}} : i32
+  %0 = spirv.GroupNonUniformBitwiseXor "Workgroup" "Reduce" %val : i32
+  return %0: i32
+}
+
+// -----
+
+func.func @group_non_uniform_bitwise_xor(%val: i1) -> i1 {
+  // expected-error @+1 {{operand #0 must be 8/16/32/64-bit integer or vector of 8/16/32/64-bit integer values of length 2/3/4/8/16, but got 'i1'}}
+  %0 = spirv.GroupNonUniformBitwiseXor "Workgroup" "Reduce" %val : i1
+  return %0: i1
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformLogicalAnd
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @group_non_uniform_logical_and
+func.func @group_non_uniform_logical_and(%val: i1) -> i1 {
+  // CHECK: %{{.+}} = spirv.GroupNonUniformLogicalAnd "Workgroup" "Reduce" %{{.+}} : i1
+  %0 = spirv.GroupNonUniformLogicalAnd "Workgroup" "Reduce" %val : i1
+  return %0: i1
+}
+
+// -----
+
+func.func @group_non_uniform_logical_and(%val: i32) -> i32 {
+  // expected-error @+1 {{operand #0 must be bool or vector of bool values of length 2/3/4/8/16, but got 'i32'}}
+  %0 = spirv.GroupNonUniformLogicalAnd "Workgroup" "Reduce" %val : i32
+  return %0: i32
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformLogicalOr
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @group_non_uniform_logical_or
+func.func @group_non_uniform_logical_or(%val: i1) -> i1 {
+  // CHECK: %{{.+}} = spirv.GroupNonUniformLogicalOr "Workgroup" "Reduce" %{{.+}} : i1
+  %0 = spirv.GroupNonUniformLogicalOr "Workgroup" "Reduce" %val : i1
+  return %0: i1
+}
+
+// -----
+
+func.func @group_non_uniform_logical_or(%val: i32) -> i32 {
+  // expected-error @+1 {{operand #0 must be bool or vector of bool values of length 2/3/4/8/16, but got 'i32'}}
+  %0 = spirv.GroupNonUniformLogicalOr "Workgroup" "Reduce" %val : i32
+  return %0: i32
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.GroupNonUniformLogicalXor
+//===----------------------------------------------------------------------===//
+
+// CHECK-LABEL: @group_non_uniform_logical_xor
+func.func @group_non_uniform_logical_xor(%val: i1) -> i1 {
+  // CHECK: %{{.+}} = spirv.GroupNonUniformLogicalXor "Workgroup" "Reduce" %{{.+}} : i1
+  %0 = spirv.GroupNonUniformLogicalXor "Workgroup" "Reduce" %val : i1
+  return %0: i1
+}
+
+// -----
+
+func.func @group_non_uniform_logical_xor(%val: i32) -> i32 {
+  // expected-error @+1 {{operand #0 must be bool or vector of bool values of length 2/3/4/8/16, but got 'i32'}}
+  %0 = spirv.GroupNonUniformLogicalXor "Workgroup" "Reduce" %val : i32
+  return %0: i32
+}



More information about the Mlir-commits mailing list