Skip to content

[mlir][spirv] Add missing group non-uniform bitwise and logical ops #73475

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 27, 2023

Conversation

kuhar
Copy link
Member

@kuhar kuhar commented Nov 27, 2023

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.

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.
@llvmbot
Copy link
Member

llvmbot commented Nov 27, 2023

@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-mlir-spirv

Author: Jakub Kuderski (kuhar)

Changes

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.


Patch is 21.55 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/73475.diff

4 Files Affected:

  • (modified) mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td (+9)
  • (modified) mlir/include/mlir/Dialect/SPIRV/IR/SPIRVNonUniformOps.td (+300)
  • (modified) mlir/lib/Dialect/SPIRV/IR/GroupOps.cpp (+102)
  • (modified) mlir/test/Dialect/SPIRV/IR/non-uniform-ops.mlir (+126)
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
+ ...
[truncated]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants