[ir][spirv-writer] Emit binary bitwise operators

Bug: tint:1906
Change-Id: Ica8436cd59aabe521df0445edc5a9f03c45cd1bf
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/134322
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir.cc b/src/tint/writer/spirv/ir/generator_impl_ir.cc
index b9ce817..05802f8 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir.cc
@@ -426,6 +426,19 @@
             break;
         }
 
+        case ir::Binary::Kind::kAnd: {
+            op = spv::Op::OpBitwiseAnd;
+            break;
+        }
+        case ir::Binary::Kind::kOr: {
+            op = spv::Op::OpBitwiseOr;
+            break;
+        }
+        case ir::Binary::Kind::kXor: {
+            op = spv::Op::OpBitwiseXor;
+            break;
+        }
+
         case ir::Binary::Kind::kEqual: {
             if (lhs_ty->is_bool_scalar_or_vector()) {
                 op = spv::Op::OpLogicalEqual;
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir_binary_test.cc b/src/tint/writer/spirv/ir/generator_impl_ir_binary_test.cc
index a139ad1..3caf528 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir_binary_test.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir_binary_test.cc
@@ -308,6 +308,45 @@
 )");
 }
 
+using Bitwise = BinaryInstructionTest;
+TEST_P(Bitwise, Scalar) {
+    auto params = GetParam();
+
+    auto* func = b.CreateFunction("foo", mod.Types().void_());
+    func->StartTarget()->SetInstructions(
+        utils::Vector{b.CreateBinary(params.kind, MakeScalarType(params.type),
+                                     MakeScalarValue(params.type), MakeScalarValue(params.type)),
+                      b.Branch(func->EndTarget())});
+
+    generator_.EmitFunction(func);
+    EXPECT_THAT(DumpModule(generator_.Module()), ::testing::HasSubstr(params.spirv_inst));
+}
+TEST_P(Bitwise, Vector) {
+    auto params = GetParam();
+
+    auto* func = b.CreateFunction("foo", mod.Types().void_());
+    func->StartTarget()->SetInstructions(
+        utils::Vector{b.CreateBinary(params.kind, MakeVectorType(params.type),
+                                     MakeVectorValue(params.type), MakeVectorValue(params.type)),
+
+                      b.Branch(func->EndTarget())});
+
+    generator_.EmitFunction(func);
+    EXPECT_THAT(DumpModule(generator_.Module()), ::testing::HasSubstr(params.spirv_inst));
+}
+INSTANTIATE_TEST_SUITE_P(
+    SpvGeneratorImplTest_Binary_I32,
+    Bitwise,
+    testing::Values(BinaryTestCase{kI32, ir::Binary::Kind::kAnd, "OpBitwiseAnd"},
+                    BinaryTestCase{kI32, ir::Binary::Kind::kOr, "OpBitwiseOr"},
+                    BinaryTestCase{kI32, ir::Binary::Kind::kXor, "OpBitwiseXor"}));
+INSTANTIATE_TEST_SUITE_P(
+    SpvGeneratorImplTest_Binary_U32,
+    Bitwise,
+    testing::Values(BinaryTestCase{kU32, ir::Binary::Kind::kAnd, "OpBitwiseAnd"},
+                    BinaryTestCase{kU32, ir::Binary::Kind::kOr, "OpBitwiseOr"},
+                    BinaryTestCase{kU32, ir::Binary::Kind::kXor, "OpBitwiseXor"}));
+
 using Comparison = BinaryInstructionTest;
 TEST_P(Comparison, Scalar) {
     auto params = GetParam();