[wgsl] Add option to disable subgroup uniformity diagnostics

Tweak the IR to program test harness to allow tests to override
default options.

Fixed: 436822001
Change-Id: I324a55f7ca16db39ca2f47e9bc59b33e5e220fb4
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/256174
Commit-Queue: James Price <jrprice@google.com>
Reviewed-by: dan sinclair <dsinclair@chromium.org>
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
index 23a60d7..919ebb9 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
+++ b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
@@ -136,6 +136,11 @@
             // diagnostic directive to the module.
             b.DiagnosticDirective(wgsl::DiagnosticSeverity::kOff, "derivative_uniformity");
         }
+        if (options.allow_non_uniform_subgroup_operations) {
+            // Suppress errors regarding non-uniform subgroups operations if requested, by adding a
+            // diagnostic directive to the module.
+            b.DiagnosticDirective(wgsl::DiagnosticSeverity::kOff, "subgroup_uniformity");
+        }
 
         return Program{resolver::Resolve(b, options.allowed_features)};
     }
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
index 620e1ec..189a73f 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
+++ b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
@@ -51,8 +51,6 @@
 
     result.ir = str();
 
-    ProgramOptions options;
-    options.allowed_features = AllowedFeatures::Everything();
     auto output_program = IRToProgram(mod, options);
     if (!output_program.IsValid()) {
         result.err = output_program.Diagnostics().Str();
@@ -3602,6 +3600,37 @@
 )");
 }
 
+TEST_F(IRToProgramTest, AllowNonUniformSubgroups) {
+    auto non_uniform = Var<private_, bool>();
+    b.ir.root_block->Append(non_uniform);
+
+    auto* fn = b.Function("f", ty.void_());
+    b.Append(fn->Block(), [&] {  //
+        auto* if_ = b.If(b.Load(non_uniform));
+        b.Append(if_->True(), [&] {
+            b.Phony(b.Call<wgsl::ir::BuiltinCall>(ty.vec4<u32>(), wgsl::BuiltinFn::kSubgroupBallot,
+                                                  true));
+            b.ExitIf(if_);
+        });
+        b.Return(fn);
+    });
+
+    options.allow_non_uniform_subgroup_operations = true;
+    EXPECT_WGSL(R"(
+enable f16;
+enable subgroups;
+diagnostic(off, subgroup_uniformity);
+
+var<private> v : bool;
+
+fn f() {
+  if (v) {
+    _ = subgroupBallot(true);
+  }
+}
+)");
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // chromium_internal_graphite
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.h b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.h
index 1f481d1..4aab993 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.h
+++ b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.h
@@ -33,6 +33,7 @@
 
 #include "src/tint/lang/core/ir/ir_helper_test.h"
 #include "src/tint/lang/core/type/reference.h"
+#include "src/tint/lang/wgsl/writer/ir_to_program/program_options.h"
 
 namespace tint::wgsl::writer {
 
@@ -97,6 +98,11 @@
     core::ir::Var* Var(std::string_view name) {
         return b.Var(name, mod.Types().ref<SPACE, T, ACCESS>());
     }
+
+    /// The options to use when generating WGSL.
+    ProgramOptions options{
+        .allowed_features = AllowedFeatures::Everything(),
+    };
 };
 
 #define EXPECT_WGSL(expected_wgsl)                                                   \
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/program_options.h b/src/tint/lang/wgsl/writer/ir_to_program/program_options.h
index de3e72f..adb29a6 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/program_options.h
+++ b/src/tint/lang/wgsl/writer/ir_to_program/program_options.h
@@ -36,6 +36,8 @@
 struct ProgramOptions {
     /// Set to `true` to allow calls to derivative builtins in non-uniform control flow.
     bool allow_non_uniform_derivatives = false;
+    /// Set to `true` to insert a directive to disable uniformity checks for subgroup builtins.
+    bool allow_non_uniform_subgroup_operations = false;
     /// The extensions and language features that are allowed to be used in the generated WGSL.
     wgsl::AllowedFeatures allowed_features = {};
 };