[ir][spirv-writer] Implement all builtin

Special case the scalar overload to just passthrough.

Bug: tint:1906
Change-Id: I7f0995769574bc79a9b796c76a50020d7c29fa1c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/141440
Auto-Submit: James Price <jrprice@google.com>
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
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 a98cc79..4de9d85 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir.cc
@@ -1113,9 +1113,10 @@
         values_.Add(builtin->Result(), Value(builtin->Args()[0]));
         return;
     }
-    if (builtin->Func() == builtin::Function::kAny &&
+    if ((builtin->Func() == builtin::Function::kAll ||
+         builtin->Func() == builtin::Function::kAny) &&
         builtin->Args()[0]->Type()->Is<type::Bool>()) {
-        // any() is a passthrough for a scalar argument.
+        // all() and any() are passthroughs for scalar arguments.
         values_.Add(builtin->Result(), Value(builtin->Args()[0]));
         return;
     }
@@ -1147,6 +1148,9 @@
                 glsl_ext_inst(GLSLstd450SAbs);
             }
             break;
+        case builtin::Function::kAll:
+            op = spv::Op::OpAll;
+            break;
         case builtin::Function::kAny:
             op = spv::Op::OpAny;
             break;
diff --git a/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc b/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc
index 59a3cba..759ac00 100644
--- a/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc
+++ b/src/tint/writer/spirv/ir/generator_impl_ir_builtin_test.cc
@@ -152,7 +152,35 @@
 )");
 }
 
-// Test that any of an scalar just folds away.
+// Test that all of a scalar just folds away.
+TEST_F(SpvGeneratorImplTest, Builtin_All_Scalar) {
+    auto* arg = b.FunctionParam("arg", ty.bool_());
+    auto* func = b.Function("foo", ty.bool_());
+    func->SetParams({arg});
+    b.With(func->Block(), [&] {
+        auto* result = b.Call(ty.bool_(), builtin::Function::kAll, arg);
+        b.Return(func, result);
+    });
+
+    ASSERT_TRUE(Generate()) << Error() << output_;
+    EXPECT_INST("OpReturnValue %arg");
+}
+
+TEST_F(SpvGeneratorImplTest, Builtin_All_Vector) {
+    auto* arg = b.FunctionParam("arg", ty.vec4<bool>());
+    auto* func = b.Function("foo", ty.bool_());
+    func->SetParams({arg});
+    b.With(func->Block(), [&] {
+        auto* result = b.Call(ty.bool_(), builtin::Function::kAll, arg);
+        b.Return(func, result);
+        mod.SetName(result, "result");
+    });
+
+    ASSERT_TRUE(Generate()) << Error() << output_;
+    EXPECT_INST("%result = OpAll %bool %arg");
+}
+
+// Test that any of a scalar just folds away.
 TEST_F(SpvGeneratorImplTest, Builtin_Any_Scalar) {
     auto* arg = b.FunctionParam("arg", ty.bool_());
     auto* func = b.Function("foo", ty.bool_());