Import Tint changes from Dawn

Changes:
  - dd54f74de15dbee21d4e6071b6e4060309123034 tint/uniformity: Rework generation of diagnostics by James Price <jrprice@google.com>
  - a1eed91cb095b77755daf98569a3677abdd7f7bb tint: Use TINT_UNLIKELY() on TINT_ASSERT() condition by Ben Clayton <bclayton@google.com>
GitOrigin-RevId: dd54f74de15dbee21d4e6071b6e4060309123034
Change-Id: Id2aee26bcc00f7c10d5ec2c621acece44ceed127
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/116928
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/debug.h b/src/tint/debug.h
index 86186ac..43bc052 100644
--- a/src/tint/debug.h
+++ b/src/tint/debug.h
@@ -20,6 +20,7 @@
 #include "src/tint/diagnostic/diagnostic.h"
 #include "src/tint/diagnostic/formatter.h"
 #include "src/tint/diagnostic/printer.h"
+#include "src/tint/utils/compiler_macros.h"
 
 namespace tint {
 
@@ -111,7 +112,7 @@
 /// error handling.
 #define TINT_ASSERT(system, condition)                                                   \
     do {                                                                                 \
-        if (!(condition)) {                                                              \
+        if (TINT_UNLIKELY(!(condition))) {                                               \
             tint::diag::List diagnostics;                                                \
             TINT_ICE(system, diagnostics) << "TINT_ASSERT(" #system ", " #condition ")"; \
         }                                                                                \
diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc
index a5aa37d..5fed471 100644
--- a/src/tint/resolver/uniformity.cc
+++ b/src/tint/resolver/uniformity.cc
@@ -15,6 +15,7 @@
 #include "src/tint/resolver/uniformity.h"
 
 #include <limits>
+#include <sstream>
 #include <string>
 #include <utility>
 #include <vector>
@@ -1651,9 +1652,9 @@
     /// @param function the function being analyzed
     /// @param required_to_be_uniform the node to traverse from
     /// @param may_be_non_uniform the node to traverse to
-    void ShowCauseOfNonUniformity(FunctionInfo& function,
-                                  Node* required_to_be_uniform,
-                                  Node* may_be_non_uniform) {
+    void ShowControlFlowDivergence(FunctionInfo& function,
+                                   Node* required_to_be_uniform,
+                                   Node* may_be_non_uniform) {
         // Traverse the graph to generate a path from the node to the source of non-uniformity.
         function.ResetVisited();
         Traverse(required_to_be_uniform);
@@ -1667,7 +1668,7 @@
             non_uniform_source, [](Node* node) { return node->affects_control_flow; });
         if (control_flow) {
             diagnostics_.add_note(diag::System::Resolver,
-                                  "control flow depends on non-uniform value",
+                                  "control flow depends on possibly non-uniform value",
                                   control_flow->ast->source);
             // TODO(jrprice): There are cases where the function with uniformity requirements is not
             // actually inside this control flow construct, for example:
@@ -1677,7 +1678,15 @@
             // the actual cause of divergence.
         }
 
-        auto get_var_type = [&](const sem::Variable* var) {
+        ShowSourceOfNonUniformity(non_uniform_source);
+    }
+
+    /// Add a diagnostic note to show the origin of a non-uniform value.
+    /// @param non_uniform_source the node that represents a non-uniform value
+    void ShowSourceOfNonUniformity(Node* non_uniform_source) {
+        TINT_ASSERT(Resolver, non_uniform_source);
+
+        auto var_type = [&](const sem::Variable* var) {
             switch (var->AddressSpace()) {
                 case ast::AddressSpace::kStorage:
                     return "read_write storage buffer ";
@@ -1686,17 +1695,18 @@
                 case ast::AddressSpace::kPrivate:
                     return "module-scope private variable ";
                 default:
-                    if (ast::HasAttribute<ast::BuiltinAttribute>(var->Declaration()->attributes)) {
-                        return "builtin ";
-                    } else if (ast::HasAttribute<ast::LocationAttribute>(
-                                   var->Declaration()->attributes)) {
-                        return "user-defined input ";
-                    } else {
-                        // TODO(jrprice): Provide more info for this case.
-                    }
-                    break;
+                    return "";
             }
-            return "";
+        };
+        auto param_type = [&](const sem::Parameter* param) {
+            if (ast::HasAttribute<ast::BuiltinAttribute>(param->Declaration()->attributes)) {
+                return "builtin ";
+            } else if (ast::HasAttribute<ast::LocationAttribute>(
+                           param->Declaration()->attributes)) {
+                return "user-defined input ";
+            } else {
+                return "parameter ";
+            }
         };
 
         // Show the source of the non-uniform value.
@@ -1704,19 +1714,23 @@
             non_uniform_source->ast,
             [&](const ast::IdentifierExpression* ident) {
                 auto* var = sem_.Get(ident)->UnwrapLoad()->As<sem::VariableUser>()->Variable();
-                std::string var_type = get_var_type(var);
-                diagnostics_.add_note(diag::System::Resolver,
-                                      "reading from " + var_type + "'" + NameFor(ident) +
-                                          "' may result in a non-uniform value",
-                                      ident->source);
+                std::ostringstream ss;
+                if (auto* param = var->As<sem::Parameter>()) {
+                    auto* func = param->Owner()->As<sem::Function>();
+                    ss << param_type(param) << "'" << NameFor(ident) << "' of '"
+                       << NameFor(func->Declaration()) << "' may be non-uniform";
+                } else {
+                    ss << "reading from " << var_type(var) << "'" << NameFor(ident)
+                       << "' may result in a non-uniform value";
+                }
+                diagnostics_.add_note(diag::System::Resolver, ss.str(), ident->source);
             },
             [&](const ast::Variable* v) {
                 auto* var = sem_.Get(v);
-                std::string var_type = get_var_type(var);
-                diagnostics_.add_note(diag::System::Resolver,
-                                      "reading from " + var_type + "'" + NameFor(v) +
-                                          "' may result in a non-uniform value",
-                                      v->source);
+                std::ostringstream ss;
+                ss << "reading from " << var_type(var) << "'" << NameFor(v)
+                   << "' may result in a non-uniform value";
+                diagnostics_.add_note(diag::System::Resolver, ss.str(), v->source);
             },
             [&](const ast::CallExpression* c) {
                 auto target_name = NameFor(c->target.name);
@@ -1730,11 +1744,10 @@
                     case Node::kFunctionCallArgumentContents: {
                         auto* arg = c->args[non_uniform_source->arg_index];
                         auto* var = sem_.Get(arg)->RootIdentifier();
-                        std::string var_type = get_var_type(var);
-                        diagnostics_.add_note(diag::System::Resolver,
-                                              "reading from " + var_type + "'" +
-                                                  NameFor(var->Declaration()) +
-                                                  "' may result in a non-uniform value",
+                        std::ostringstream ss;
+                        ss << "reading from " << var_type(var) << "'" << NameFor(var->Declaration())
+                           << "' may result in a non-uniform value";
+                        diagnostics_.add_note(diag::System::Resolver, ss.str(),
                                               var->Declaration()->source);
                         break;
                     }
@@ -1750,7 +1763,7 @@
                     case Node::kFunctionCallPointerArgumentResult: {
                         diagnostics_.add_note(
                             diag::System::Resolver,
-                            "pointer contents may become non-uniform after calling '" +
+                            "contents of pointer may become non-uniform after calling '" +
                                 target_name + "'",
                             c->args[non_uniform_source->arg_index]->source);
                         break;
@@ -1773,11 +1786,9 @@
     /// Generate an error message for a uniformity issue.
     /// @param function the function that the diagnostic is being produced for
     /// @param source_node the node that has caused a uniformity issue in `function`
-    /// @param note `true` if the diagnostic should be emitted as a note
-    void MakeError(FunctionInfo& function, Node* source_node, bool note = false) {
-        // Helper to produce a diagnostic message with the severity required by this invocation of
-        // the `MakeError` function.
-        auto report = [&](Source source, std::string msg) {
+    void MakeError(FunctionInfo& function, Node* source_node) {
+        // Helper to produce a diagnostic message, as a note or with the global failure severity.
+        auto report = [&](Source source, std::string msg, bool note) {
             diag::Diagnostic error{};
             auto failureSeverity =
                 kUniformityFailuresAsError ? diag::Severity::Error : diag::Severity::Warning;
@@ -1802,77 +1813,54 @@
         auto* call = cause->ast->As<ast::CallExpression>();
         TINT_ASSERT(Resolver, call);
         auto* target = SemCall(call)->Target();
+        auto func_name = NameFor(call->target.name);
 
-        std::string func_name;
-        if (auto* builtin = target->As<sem::Builtin>()) {
-            func_name = builtin->str();
-        } else if (auto* user = target->As<sem::Function>()) {
-            func_name = NameFor(user->Declaration());
-        }
+        if (cause->type == Node::kFunctionCallArgumentValue ||
+            cause->type == Node::kFunctionCallArgumentContents) {
+            bool is_value = (cause->type == Node::kFunctionCallArgumentValue);
 
-        if (cause->type == Node::kFunctionCallArgumentValue) {
-            // The requirement was on a function parameter.
-            auto* ast_param = target->Parameters()[cause->arg_index]->Declaration();
-            std::string param_name;
-            if (ast_param) {
-                param_name = " '" + NameFor(ast_param) + "'";
+            auto* user_func = target->As<sem::Function>();
+            if (user_func) {
+                // Recurse into the called function to show the reason for the requirement.
+                auto next_function = functions_.Find(user_func->Declaration());
+                auto& param_info = next_function->parameters[cause->arg_index];
+                MakeError(*next_function,
+                          is_value ? param_info.value : param_info.ptr_input_contents);
             }
-            report(call->args[cause->arg_index]->source,
-                   "parameter" + param_name + " of '" + func_name + "' must be uniform");
 
-            // If this is a call to a user-defined function, add a note to show the reason that the
-            // parameter is required to be uniform.
-            if (auto* user = target->As<sem::Function>()) {
-                auto next_function = functions_.Find(user->Declaration());
-                Node* next_cause = next_function->parameters[cause->arg_index].value;
-                MakeError(*next_function, next_cause, true);
-            }
-        } else if (cause->type == Node::kFunctionCallArgumentContents) {
-            // The requirement was on the contents of a function parameter.
-            auto param_name = NameFor(target->Parameters()[cause->arg_index]->Declaration());
-            report(call->args[cause->arg_index]->source, "contents of parameter '" + param_name +
-                                                             "' of '" + func_name +
-                                                             "' must be uniform");
+            // Show the place where the non-uniform argument was passed.
+            // If this is a builtin, this will be the trigger location for the failure.
+            std::ostringstream ss;
+            ss << "possibly non-uniform value passed" << (is_value ? "" : " via pointer")
+               << " here";
+            report(call->args[cause->arg_index]->source, ss.str(), /* note */ user_func != nullptr);
 
-            // If this is a call to a user-defined function, add a note to show the reason that the
-            // parameter is required to be uniform.
-            if (auto* user = target->As<sem::Function>()) {
-                auto next_function = functions_.Find(user->Declaration());
-                Node* next_cause = next_function->parameters[cause->arg_index].ptr_input_contents;
-                MakeError(*next_function, next_cause, true);
-            }
+            // Show the origin of non-uniformity for the value or data that is being passed.
+            ShowSourceOfNonUniformity(source_node->visited_from);
         } else {
-            // The requirement was on a function callsite.
-            report(call->source,
-                   "'" + func_name + "' must only be called from uniform control flow");
-
-            // If this is a call to a user-defined function, add a note to show the builtin that
-            // causes the uniformity requirement.
-            auto* innermost_call = FindBuiltinThatRequiresUniformity(call);
-            if (innermost_call != call) {
-                auto* sem_call = SemCall(call);
-                auto* sem_innermost_call = SemCall(innermost_call);
-
-                // Determine whether the builtin is being called directly or indirectly.
-                bool indirect = false;
-                if (sem_call->Target()->As<sem::Function>() !=
-                    sem_innermost_call->Stmt()->Function()) {
-                    indirect = true;
-                }
-
-                auto* builtin = sem_innermost_call->Target()->As<sem::Builtin>();
-                diagnostics_.add_note(diag::System::Resolver,
-                                      "'" + func_name + "' requires uniformity because it " +
-                                          (indirect ? "indirectly " : "") + "calls " +
-                                          builtin->str(),
-                                      innermost_call->source);
+            auto* builtin_call = FindBuiltinThatRequiresUniformity(call);
+            {
+                // Show a builtin was reachable from this call (which may be the call itself).
+                // This will be the trigger location for the failure.
+                std::ostringstream ss;
+                ss << "'" << NameFor(builtin_call->target.name)
+                   << "' must only be called from uniform control flow";
+                report(builtin_call->source, ss.str(), /* note */ false);
             }
-        }
 
-        // Show the cause of non-uniformity (starting at the top-level error).
-        if (!note) {
-            ShowCauseOfNonUniformity(function, function.required_to_be_uniform,
-                                     function.may_be_non_uniform);
+            if (builtin_call != call) {
+                // The call was to a user function, so show that call too.
+                std::ostringstream ss;
+                ss << "called ";
+                if (target->As<sem::Function>() != SemCall(builtin_call)->Stmt()->Function()) {
+                    ss << "indirectly ";
+                }
+                ss << "by '" << func_name << "' from '" << function.name << "'";
+                report(call->source, ss.str(), /* note */ true);
+            }
+
+            // Show the point at which control-flow depends on a non-uniform value.
+            ShowControlFlowDivergence(function, cause, source_node);
         }
     }
 
diff --git a/src/tint/resolver/uniformity_test.cc b/src/tint/resolver/uniformity_test.cc
index 51e607a..5052a1f 100644
--- a/src/tint/resolver/uniformity_test.cc
+++ b/src/tint/resolver/uniformity_test.cc
@@ -326,7 +326,6 @@
     bool should_pass = !(MayBeNonUniform(condition) && RequiredToBeUniform(function));
     RunTest(src, should_pass);
     if (!should_pass) {
-        EXPECT_THAT(error_, ::testing::StartsWith("test:31:5 warning: "));
         EXPECT_THAT(error_, ::testing::HasSubstr("must only be called from uniform control flow"));
     }
 }
@@ -408,14 +407,22 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:11:7 warning: parameter 'i' of 'foo' must be uniform
-  foo(rw);
-      ^^
-
-test:6:5 note: 'workgroupBarrier' must only be called from uniform control flow
+              R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
+test:5:3 note: control flow depends on possibly non-uniform value
+  if (i == 0) {
+  ^^
+
+test:5:7 note: parameter 'i' of 'foo' may be non-uniform
+  if (i == 0) {
+      ^
+
+test:11:7 note: possibly non-uniform value passed here
+  foo(rw);
+      ^^
+
 test:11:7 note: reading from read_write storage buffer 'rw' may result in a non-uniform value
   foo(rw);
       ^^
@@ -465,7 +472,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (foo(rw) == 7) {
   ^^
 
@@ -508,11 +515,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:4:3 note: control flow depends on non-uniform value
+test:4:3 note: control flow depends on possibly non-uniform value
   if (all(vec3(b) == vec3(0u))) {
   ^^
 
-test:4:16 note: reading from builtin 'b' may result in a non-uniform value
+test:4:16 note: builtin 'b' of 'main' may be non-uniform
   if (all(vec3(b) == vec3(0u))) {
                ^
 )");
@@ -543,11 +550,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (all(vec3(s.b) == vec3(0u))) {
   ^^
 
-test:8:16 note: reading from 's' may result in a non-uniform value
+test:8:16 note: parameter 's' of 'main' may be non-uniform
   if (all(vec3(s.b) == vec3(0u))) {
                ^
 )");
@@ -588,11 +595,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (s.num_groups.x == 0u) {
   ^^
 
-test:9:7 note: reading from 's' may result in a non-uniform value
+test:9:7 note: parameter 's' of 'main' may be non-uniform
   if (s.num_groups.x == 0u) {
       ^
 )");
@@ -619,11 +626,11 @@
     dpdx(0.5);
     ^^^^
 
-test:4:3 note: control flow depends on non-uniform value
+test:4:3 note: control flow depends on possibly non-uniform value
   if (u32(vec4(b).x) == 0u) {
   ^^
 
-test:4:16 note: reading from builtin 'b' may result in a non-uniform value
+test:4:16 note: builtin 'b' of 'main' may be non-uniform
   if (u32(vec4(b).x) == 0u) {
                ^
 )");
@@ -653,11 +660,11 @@
     dpdx(0.5);
     ^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (u32(vec4(s.b).x) == 0u) {
   ^^
 
-test:8:16 note: reading from 's' may result in a non-uniform value
+test:8:16 note: parameter 's' of 'main' may be non-uniform
   if (u32(vec4(s.b).x) == 0u) {
                ^
 )");
@@ -690,11 +697,11 @@
     dpdx(0.5);
     ^^^^
 
-test:4:3 note: control flow depends on non-uniform value
+test:4:3 note: control flow depends on possibly non-uniform value
   if (l == 0.0) {
   ^^
 
-test:4:7 note: reading from user-defined input 'l' may result in a non-uniform value
+test:4:7 note: user-defined input 'l' of 'main' may be non-uniform
   if (l == 0.0) {
       ^
 )");
@@ -720,11 +727,11 @@
     dpdx(0.5);
     ^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (s.l == 0.0) {
   ^^
 
-test:8:7 note: reading from 's' may result in a non-uniform value
+test:8:7 note: parameter 's' of 'main' may be non-uniform
   if (s.l == 0.0) {
       ^
 )");
@@ -961,7 +968,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:10:7 note: control flow depends on non-uniform value
+test:10:7 note: control flow depends on possibly non-uniform value
       break if (i == n);
       ^^^^^
 
@@ -1012,7 +1019,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:10:7 note: control flow depends on non-uniform value
+test:10:7 note: control flow depends on possibly non-uniform value
       break if (i == n);
       ^^^^^
 
@@ -1080,7 +1087,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:7:5 note: control flow depends on non-uniform value
+test:7:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -1164,7 +1171,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:13:5 note: control flow depends on non-uniform value
+test:13:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -1202,7 +1209,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:14:3 note: control flow depends on non-uniform value
+test:14:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -1245,7 +1252,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:19:3 note: control flow depends on non-uniform value
+test:19:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -1319,7 +1326,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:19:3 note: control flow depends on non-uniform value
+test:19:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -1360,7 +1367,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:7:5 note: control flow depends on non-uniform value
+test:7:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -1404,7 +1411,7 @@
         workgroupBarrier();
         ^^^^^^^^^^^^^^^^
 
-test:15:7 note: control flow depends on non-uniform value
+test:15:7 note: control flow depends on possibly non-uniform value
       if (v == 0) {
       ^^
 
@@ -1445,7 +1452,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:7:5 note: control flow depends on non-uniform value
+test:7:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -1486,7 +1493,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:7:5 note: control flow depends on non-uniform value
+test:7:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -1604,7 +1611,7 @@
         workgroupBarrier();
         ^^^^^^^^^^^^^^^^
 
-test:15:7 note: control flow depends on non-uniform value
+test:15:7 note: control flow depends on possibly non-uniform value
       if (v == 0) {
       ^^
 
@@ -1666,7 +1673,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   for (var i = 0; i < n; i = i + 1) {
   ^^^
 
@@ -1699,7 +1706,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:7:5 note: control flow depends on non-uniform value
+test:7:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -1754,7 +1761,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -1809,7 +1816,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:7:5 note: control flow depends on non-uniform value
+test:7:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -1870,7 +1877,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:14:3 note: control flow depends on non-uniform value
+test:14:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -1915,7 +1922,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:20:3 note: control flow depends on non-uniform value
+test:20:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -1957,7 +1964,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:7:5 note: control flow depends on non-uniform value
+test:7:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -1998,7 +2005,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:7:5 note: control flow depends on non-uniform value
+test:7:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -2035,7 +2042,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   for (var i = 0; i < 10; i++) {
   ^^^
 
@@ -2131,7 +2138,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:6:3 note: control flow depends on non-uniform value
+test:6:3 note: control flow depends on possibly non-uniform value
   while (i < n) {
   ^^^^^
 
@@ -2168,7 +2175,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:8:5 note: control flow depends on non-uniform value
+test:8:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -2233,7 +2240,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:16:3 note: control flow depends on non-uniform value
+test:16:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -2280,7 +2287,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:22:3 note: control flow depends on non-uniform value
+test:22:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -2323,7 +2330,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:8:5 note: control flow depends on non-uniform value
+test:8:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -2366,7 +2373,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:8:5 note: control flow depends on non-uniform value
+test:8:5 note: control flow depends on possibly non-uniform value
     if (v == 0) {
     ^^
 
@@ -2461,7 +2468,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (non_uniform == 42) {
   ^^
 
@@ -2489,7 +2496,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (non_uniform == 42) {
   ^^
 
@@ -2518,7 +2525,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:34 note: control flow depends on non-uniform value
+test:7:34 note: control flow depends on possibly non-uniform value
   if ((non_uniform_global == 42) && false) {
                                  ^^
 
@@ -2547,7 +2554,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (false && (non_uniform_global == 42)) {
   ^^
 
@@ -2576,7 +2583,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:34 note: control flow depends on non-uniform value
+test:7:34 note: control flow depends on possibly non-uniform value
   if ((non_uniform_global == 42) || true) {
                                  ^^
 
@@ -2605,7 +2612,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (true || (non_uniform_global == 42)) {
   ^^
 
@@ -2633,7 +2640,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (non_uniform == 42) {
   ^^
 
@@ -2664,7 +2671,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -2741,7 +2748,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:14:3 note: control flow depends on non-uniform value
+test:14:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -2824,7 +2831,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:11:3 note: control flow depends on non-uniform value
+test:11:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -2861,7 +2868,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:12:3 note: control flow depends on non-uniform value
+test:12:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -3018,7 +3025,7 @@
   workgroupBarrier();
   ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (non_uniform == 42) {
   ^^
 
@@ -3055,7 +3062,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   switch (non_uniform) {
   ^^^^^^
 
@@ -3085,7 +3092,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   switch (non_uniform) {
   ^^^^^^
 
@@ -3120,7 +3127,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:8:7 note: control flow depends on non-uniform value
+test:8:7 note: control flow depends on possibly non-uniform value
       if (non_uniform == 42) {
       ^^
 
@@ -3209,7 +3216,7 @@
         workgroupBarrier();
         ^^^^^^^^^^^^^^^^
 
-test:13:7 note: control flow depends on non-uniform value
+test:13:7 note: control flow depends on possibly non-uniform value
       if (x == 0) {
       ^^
 
@@ -3249,7 +3256,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:18:3 note: control flow depends on non-uniform value
+test:18:3 note: control flow depends on possibly non-uniform value
   if (x == 0) {
   ^^
 
@@ -3315,7 +3322,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:17:3 note: control flow depends on non-uniform value
+test:17:3 note: control flow depends on possibly non-uniform value
   if (x == 0) {
   ^^
 
@@ -3384,7 +3391,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:20:3 note: control flow depends on non-uniform value
+test:20:3 note: control flow depends on possibly non-uniform value
   if (x == 0) {
   ^^
 
@@ -3426,7 +3433,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:8:5 note: control flow depends on non-uniform value
+test:8:5 note: control flow depends on possibly non-uniform value
     if (x == 0) {
     ^^
 
@@ -3531,7 +3538,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -3561,7 +3568,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -3626,7 +3633,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (non_uniform == 0) {
   ^^
 
@@ -3654,7 +3661,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:6:3 note: control flow depends on non-uniform value
+test:6:3 note: control flow depends on possibly non-uniform value
   if (*&v == 0) {
   ^^
 
@@ -3683,7 +3690,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (*pv == 0) {
   ^^
 
@@ -3711,14 +3718,22 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:12:7 warning: contents of parameter 'p' of 'bar' must be uniform
-  bar(&v);
-      ^
-
-test:6:5 note: 'workgroupBarrier' must only be called from uniform control flow
+              R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
+test:5:3 note: control flow depends on possibly non-uniform value
+  if (*p == 0) {
+  ^^
+
+test:5:8 note: parameter 'p' of 'bar' may be non-uniform
+  if (*p == 0) {
+       ^
+
+test:12:7 note: possibly non-uniform value passed via pointer here
+  bar(&v);
+      ^
+
 test:11:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
   var v = non_uniform;
           ^^^^^^^^^^^
@@ -3743,7 +3758,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:6:3 note: control flow depends on non-uniform value
+test:6:3 note: control flow depends on possibly non-uniform value
   if (*pv == 0) {
   ^^
 
@@ -3772,14 +3787,22 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:13:7 warning: contents of parameter 'p' of 'bar' must be uniform
-  bar(&non_uniform);
-      ^
-
-test:8:5 note: 'workgroupBarrier' must only be called from uniform control flow
+              R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
+test:7:3 note: control flow depends on possibly non-uniform value
+  if (*p == 0) {
+  ^^
+
+test:7:8 note: parameter 'p' of 'bar' may be non-uniform
+  if (*p == 0) {
+       ^
+
+test:13:7 note: possibly non-uniform value passed via pointer here
+  bar(&non_uniform);
+      ^
+
 test:4:48 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
 @group(0) @binding(0) var<storage, read_write> non_uniform : i32;
                                                ^^^^^^^^^^^
@@ -3809,7 +3832,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:11:3 note: control flow depends on non-uniform value
+test:11:3 note: control flow depends on possibly non-uniform value
   if (0 == bar(&non_uniform)) {
   ^^
 
@@ -3838,14 +3861,22 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:13:7 warning: contents of parameter 'p' of 'bar' must be uniform
-  bar(&v);
-      ^
-
-test:6:5 note: 'workgroupBarrier' must only be called from uniform control flow
+              R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
+test:5:3 note: control flow depends on possibly non-uniform value
+  if (*p == 0) {
+  ^^
+
+test:5:8 note: parameter 'p' of 'bar' may be non-uniform
+  if (*p == 0) {
+       ^
+
+test:13:7 note: possibly non-uniform value passed via pointer here
+  bar(&v);
+      ^
+
 test:12:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
   var v = non_uniform;
           ^^^^^^^^^^^
@@ -3871,14 +3902,22 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:12:7 warning: contents of parameter 'p' of 'bar' must be uniform
-  bar(&v);
-      ^
-
-test:6:5 note: 'workgroupBarrier' must only be called from uniform control flow
+              R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
+test:5:3 note: control flow depends on possibly non-uniform value
+  if (*p == 0) {
+  ^^
+
+test:5:8 note: parameter 'p' of 'bar' may be non-uniform
+  if (*p == 0) {
+       ^
+
+test:12:7 note: possibly non-uniform value passed via pointer here
+  bar(&v);
+      ^
+
 test:11:11 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
   var v = non_uniform;
           ^^^^^^^^^^^
@@ -3950,7 +3989,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (*p == 0) {
   ^^
 
@@ -3988,7 +4027,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (*local_p == 0) {
   ^^
 
@@ -4025,17 +4064,29 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:21:7 warning: contents of parameter 'p' of 'bar' must be uniform
-  bar(p);
-      ^
+              R"(test:8:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+    workgroupBarrier();
+    ^^^^^^^^^^^^^^^^
 
-test:13:7 note: contents of parameter 'p' of 'zoo' must be uniform
+test:7:3 note: control flow depends on possibly non-uniform value
+  if (*p == 0) {
+  ^^
+
+test:7:8 note: parameter 'p' of 'zoo' may be non-uniform
+  if (*p == 0) {
+       ^
+
+test:13:7 note: possibly non-uniform value passed via pointer here
   zoo(p);
       ^
 
-test:8:5 note: 'workgroupBarrier' must only be called from uniform control flow
-    workgroupBarrier();
-    ^^^^^^^^^^^^^^^^
+test:12:8 note: reading from 'p' may result in a non-uniform value
+fn bar(p : ptr<function, i32>) {
+       ^
+
+test:21:7 note: possibly non-uniform value passed via pointer here
+  bar(p);
+      ^
 
 test:20:14 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
   let p = &v[non_uniform];
@@ -4065,7 +4116,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:10:3 note: control flow depends on non-uniform value
+test:10:3 note: control flow depends on possibly non-uniform value
   if (*p == 0) {
   ^^
 
@@ -4103,17 +4154,29 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:22:7 warning: contents of parameter 'p' of 'bar' must be uniform
-  bar(p);
-      ^
+              R"(test:9:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+    workgroupBarrier();
+    ^^^^^^^^^^^^^^^^
 
-test:14:7 note: contents of parameter 'p' of 'zoo' must be uniform
+test:8:3 note: control flow depends on possibly non-uniform value
+  if (*p == 0) {
+  ^^
+
+test:8:8 note: parameter 'p' of 'zoo' may be non-uniform
+  if (*p == 0) {
+       ^
+
+test:14:7 note: possibly non-uniform value passed via pointer here
   zoo(p);
       ^
 
-test:9:5 note: 'workgroupBarrier' must only be called from uniform control flow
-    workgroupBarrier();
-    ^^^^^^^^^^^^^^^^
+test:13:8 note: reading from 'p' may result in a non-uniform value
+fn bar(p : ptr<function, i32>) {
+       ^
+
+test:22:7 note: possibly non-uniform value passed via pointer here
+  bar(p);
+      ^
 
 test:19:34 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
   var v = array<i32, 4>(0, 0, 0, non_uniform);
@@ -4141,7 +4204,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (*pv == 0) {
   ^^
 
@@ -4189,7 +4252,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -4219,7 +4282,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (*&*&*pv2 == 0) {
   ^^
 
@@ -4251,7 +4314,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:10:3 note: control flow depends on non-uniform value
+test:10:3 note: control flow depends on possibly non-uniform value
   if (*pv1 == 0) {
   ^^
 
@@ -4302,7 +4365,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:10:3 note: control flow depends on non-uniform value
+test:10:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -4352,11 +4415,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:11:3 note: control flow depends on non-uniform value
+test:11:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
-test:10:7 note: pointer contents may become non-uniform after calling 'bar'
+test:10:7 note: contents of pointer may become non-uniform after calling 'bar'
   bar(&v);
       ^
 )");
@@ -4405,7 +4468,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:11:3 note: control flow depends on non-uniform value
+test:11:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -4439,7 +4502,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:12:3 note: control flow depends on non-uniform value
+test:12:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -4522,7 +4585,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:20:3 note: control flow depends on non-uniform value
+test:20:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -4616,11 +4679,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:17:3 note: control flow depends on non-uniform value
+test:17:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
-test:16:7 note: pointer contents may become non-uniform after calling 'bar'
+test:16:7 note: contents of pointer may become non-uniform after calling 'bar'
   bar(&v);
       ^
 )");
@@ -4653,11 +4716,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:15:3 note: control flow depends on non-uniform value
+test:15:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
-test:14:7 note: pointer contents may become non-uniform after calling 'bar'
+test:14:7 note: contents of pointer may become non-uniform after calling 'bar'
   bar(&v);
       ^
 )");
@@ -4690,11 +4753,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:15:3 note: control flow depends on non-uniform value
+test:15:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
-test:14:7 note: pointer contents may become non-uniform after calling 'bar'
+test:14:7 note: contents of pointer may become non-uniform after calling 'bar'
   bar(&v);
       ^
 )");
@@ -4735,11 +4798,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:23:3 note: control flow depends on non-uniform value
+test:23:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
-test:22:7 note: pointer contents may become non-uniform after calling 'bar'
+test:22:7 note: contents of pointer may become non-uniform after calling 'bar'
   bar(&v);
       ^
 )");
@@ -4774,11 +4837,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:17:3 note: control flow depends on non-uniform value
+test:17:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
-test:16:7 note: pointer contents may become non-uniform after calling 'bar'
+test:16:7 note: contents of pointer may become non-uniform after calling 'bar'
   bar(&v);
       ^
 )");
@@ -4810,7 +4873,7 @@
       workgroupBarrier();
       ^^^^^^^^^^^^^^^^
 
-test:6:5 note: control flow depends on non-uniform value
+test:6:5 note: control flow depends on possibly non-uniform value
     if (*p == 0) {
     ^^
 
@@ -4846,7 +4909,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:14:3 note: control flow depends on non-uniform value
+test:14:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -4883,7 +4946,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:11:3 note: control flow depends on non-uniform value
+test:11:3 note: control flow depends on possibly non-uniform value
   if (non_uniform_global == 0) {
   ^^
 
@@ -4920,7 +4983,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:11:3 note: control flow depends on non-uniform value
+test:11:3 note: control flow depends on possibly non-uniform value
   if (non_uniform_global == 0) {
   ^^
 
@@ -4961,7 +5024,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:15:3 note: control flow depends on non-uniform value
+test:15:3 note: control flow depends on possibly non-uniform value
   if (non_uniform_global == 0) {
   ^^
 
@@ -5020,7 +5083,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:13:3 note: control flow depends on non-uniform value
+test:13:3 note: control flow depends on possibly non-uniform value
   if (b == 0) {
   ^^
 
@@ -5077,11 +5140,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:13:3 note: control flow depends on non-uniform value
+test:13:3 note: control flow depends on possibly non-uniform value
   if (b == 0) {
   ^^
 
-test:12:11 note: pointer contents may become non-uniform after calling 'bar'
+test:12:11 note: contents of pointer may become non-uniform after calling 'bar'
   bar(&a, &b);
           ^
 )");
@@ -5132,7 +5195,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:11:3 note: control flow depends on non-uniform value
+test:11:3 note: control flow depends on possibly non-uniform value
   if (v == 1) {
   ^^
 
@@ -5170,11 +5233,11 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:13:3 note: control flow depends on non-uniform value
+test:13:3 note: control flow depends on possibly non-uniform value
   if (b == 0) {
   ^^
 
-test:12:11 note: pointer contents may become non-uniform after calling 'bar'
+test:12:11 note: contents of pointer may become non-uniform after calling 'bar'
   bar(&a, &b);
           ^
 )");
@@ -5210,7 +5273,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:15:3 note: control flow depends on non-uniform value
+test:15:3 note: control flow depends on possibly non-uniform value
   if (c == 0) {
   ^^
 
@@ -5277,7 +5340,7 @@
     RunTest(std::move(b), false);
     EXPECT_EQ(error_,
               R"(warning: 'workgroupBarrier' must only be called from uniform control flow
-note: control flow depends on non-uniform value
+note: control flow depends on possibly non-uniform value
 note: reading from module-scope private variable 'non_uniform_global' may result in a non-uniform value)");
 }
 
@@ -5316,7 +5379,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (v[2] == 0) {
   ^^
 
@@ -5345,7 +5408,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (v[2] == 0) {
   ^^
 
@@ -5390,7 +5453,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (v[2] == 0) {
   ^^
 
@@ -5423,7 +5486,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (v[1] == 0) {
   ^^
 
@@ -5541,7 +5604,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (v[1] == 0) {
   ^^
 
@@ -5571,7 +5634,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (v.y == 0) {
   ^^
 
@@ -5604,7 +5667,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (v[1] == 0) {
   ^^
 
@@ -5633,7 +5696,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (any(v == vec4(42))) {
   ^^
 
@@ -5666,7 +5729,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -5770,7 +5833,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -5803,7 +5866,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -5836,7 +5899,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -5870,7 +5933,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -5905,7 +5968,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -5939,7 +6002,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -5969,7 +6032,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -6000,7 +6063,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -6032,7 +6095,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -6064,7 +6127,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -6094,7 +6157,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (m[1][1] == 0.0) {
   ^^
 
@@ -6143,7 +6206,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (s.b == 0) {
   ^^
 
@@ -6176,7 +6239,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:11:3 note: control flow depends on non-uniform value
+test:11:3 note: control flow depends on possibly non-uniform value
   if (s.b == 0) {
   ^^
 
@@ -6229,7 +6292,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:11:3 note: control flow depends on non-uniform value
+test:11:3 note: control flow depends on possibly non-uniform value
   if (s.b == 0) {
   ^^
 
@@ -6266,7 +6329,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:12:3 note: control flow depends on non-uniform value
+test:12:3 note: control flow depends on possibly non-uniform value
   if (s.a == 0) {
   ^^
 
@@ -6304,7 +6367,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:13:3 note: control flow depends on non-uniform value
+test:13:3 note: control flow depends on possibly non-uniform value
   if (s.a == 0) {
   ^^
 
@@ -6342,7 +6405,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:13:3 note: control flow depends on non-uniform value
+test:13:3 note: control flow depends on possibly non-uniform value
   if (s.a == 0) {
   ^^
 
@@ -6397,7 +6460,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:12:3 note: control flow depends on non-uniform value
+test:12:3 note: control flow depends on possibly non-uniform value
   if (s.a == 0) {
   ^^
 
@@ -6498,7 +6561,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:12:3 note: control flow depends on non-uniform value
+test:12:3 note: control flow depends on possibly non-uniform value
   if (s.a == 0) {
   ^^
 
@@ -6534,7 +6597,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:13:3 note: control flow depends on non-uniform value
+test:13:3 note: control flow depends on possibly non-uniform value
   if (s.a == 0) {
   ^^
 
@@ -6570,7 +6633,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:13:3 note: control flow depends on non-uniform value
+test:13:3 note: control flow depends on possibly non-uniform value
   if (s.a == 0) {
   ^^
 
@@ -6607,7 +6670,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:12:3 note: control flow depends on non-uniform value
+test:12:3 note: control flow depends on possibly non-uniform value
   if (s.a == 0) {
   ^^
 
@@ -6648,7 +6711,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (arr[7] == 0) {
   ^^
 
@@ -6677,7 +6740,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (arr[2] == 0) {
   ^^
 
@@ -6722,7 +6785,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (arr[2] == 0) {
   ^^
 
@@ -6753,7 +6816,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (arr[2] == 0) {
   ^^
 
@@ -6786,7 +6849,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (arr[1] == 0) {
   ^^
 
@@ -6833,7 +6896,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (arr[1] == 0) {
   ^^
 
@@ -6866,7 +6929,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (arr[1] == 0) {
   ^^
 
@@ -6899,7 +6962,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (arr[1] == 0) {
   ^^
 
@@ -6932,7 +6995,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:8:3 note: control flow depends on non-uniform value
+test:8:3 note: control flow depends on possibly non-uniform value
   if (arr[1] == 0) {
   ^^
 
@@ -6966,7 +7029,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (arr[1] == 0) {
   ^^
 
@@ -7001,7 +7064,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (arr[1] == 0) {
   ^^
 
@@ -7035,7 +7098,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:9:3 note: control flow depends on possibly non-uniform value
   if (arr[1] == 0) {
   ^^
 
@@ -7181,7 +7244,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (i32(non_uniform_global) == 0) {
   ^^
 
@@ -7208,7 +7271,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (f32(non_uniform_global) == 0.0) {
   ^^
 
@@ -7235,7 +7298,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (bitcast<f32>(non_uniform_global) == 0.0) {
   ^^
 
@@ -7265,7 +7328,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -7295,7 +7358,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:7:3 note: control flow depends on non-uniform value
+test:7:3 note: control flow depends on possibly non-uniform value
   if (v == 0) {
   ^^
 
@@ -7332,7 +7395,7 @@
   let b = (non_uniform_global == 0) && (dpdx(1.0) == 0.0);
                                         ^^^^
 
-test:5:37 note: control flow depends on non-uniform value
+test:5:37 note: control flow depends on possibly non-uniform value
   let b = (non_uniform_global == 0) && (dpdx(1.0) == 0.0);
                                     ^^
 
@@ -7585,7 +7648,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:19:3 note: control flow depends on non-uniform value
+test:19:3 note: control flow depends on possibly non-uniform value
   if (0 == bar(p)) {
   ^^
 
@@ -7650,11 +7713,12 @@
 )";
 
     RunTest(src, false);
-    EXPECT_EQ(error_, R"(test:8:28 warning: parameter of 'workgroupUniformLoad' must be uniform
+    EXPECT_EQ(error_,
+              R"(test:8:28 warning: possibly non-uniform value passed here
   if (workgroupUniformLoad(&data[idx]) > 0) {
                            ^
 
-test:8:34 note: reading from builtin 'idx' may result in a non-uniform value
+test:8:34 note: builtin 'idx' of 'main' may be non-uniform
   if (workgroupUniformLoad(&data[idx]) > 0) {
                                  ^^^
 )");
@@ -7681,15 +7745,20 @@
 )";
 
     RunTest(src, false);
-    EXPECT_EQ(error_, R"(test:14:11 warning: parameter 'p' of 'foo' must be uniform
-  if (foo(&data[idx]) > 0) {
-          ^
-
-test:8:31 note: parameter of 'workgroupUniformLoad' must be uniform
+    EXPECT_EQ(error_,
+              R"(test:8:31 warning: possibly non-uniform value passed here
   return workgroupUniformLoad(p);
                               ^
 
-test:14:17 note: reading from builtin 'idx' may result in a non-uniform value
+test:8:31 note: parameter 'p' of 'foo' may be non-uniform
+  return workgroupUniformLoad(p);
+                              ^
+
+test:14:11 note: possibly non-uniform value passed here
+  if (foo(&data[idx]) > 0) {
+          ^
+
+test:14:17 note: builtin 'idx' of 'main' may be non-uniform
   if (foo(&data[idx]) > 0) {
                 ^^^
 )");
@@ -7712,7 +7781,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (atomicAdd(&a, 1) == 1) {
   ^^
 
@@ -7739,7 +7808,7 @@
     storageBarrier();
     ^^^^^^^^^^^^^^
 
-test:5:3 note: control flow depends on non-uniform value
+test:5:3 note: control flow depends on possibly non-uniform value
   if (atomicAdd(&a, 1) == 1) {
   ^^
 
@@ -7795,7 +7864,7 @@
     RunTest(std::move(b), false);
     EXPECT_EQ(error_,
               R"(warning: 'workgroupBarrier' must only be called from uniform control flow
-note: control flow depends on non-uniform value
+note: control flow depends on possibly non-uniform value
 note: reading from module-scope private variable 'v0' may result in a non-uniform value)");
 }
 
@@ -7820,15 +7889,15 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:10:5 warning: 'foo' must only be called from uniform control flow
-    foo();
-    ^^^
-
-test:5:3 note: 'foo' requires uniformity because it calls workgroupBarrier
+              R"(test:5:3 warning: 'workgroupBarrier' must only be called from uniform control flow
   workgroupBarrier();
   ^^^^^^^^^^^^^^^^
 
-test:9:3 note: control flow depends on non-uniform value
+test:10:5 note: called by 'foo' from 'main'
+    foo();
+    ^^^
+
+test:9:3 note: control flow depends on possibly non-uniform value
   if (non_uniform == 42) {
   ^^
 
@@ -7863,15 +7932,15 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:18:5 warning: 'foo' must only be called from uniform control flow
-    foo();
-    ^^^
-
-test:5:3 note: 'foo' requires uniformity because it indirectly calls workgroupBarrier
+              R"(test:5:3 warning: 'workgroupBarrier' must only be called from uniform control flow
   workgroupBarrier();
   ^^^^^^^^^^^^^^^^
 
-test:17:3 note: control flow depends on non-uniform value
+test:18:5 note: called indirectly by 'foo' from 'main'
+    foo();
+    ^^^
+
+test:17:3 note: control flow depends on possibly non-uniform value
   if (non_uniform == 42) {
   ^^
 
@@ -7906,21 +7975,37 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:19:7 warning: parameter 'c' of 'foo' must be uniform
-  foo(non_uniform);
-      ^^^^^^^^^^^
+              R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
+    workgroupBarrier();
+    ^^^^^^^^^^^^^^^^
 
-test:15:7 note: parameter 'b' of 'bar' must be uniform
-  bar(c);
+test:5:3 note: control flow depends on possibly non-uniform value
+  if (a == 42) {
+  ^^
+
+test:5:7 note: parameter 'a' of 'zoo' may be non-uniform
+  if (a == 42) {
       ^
 
-test:11:7 note: parameter 'a' of 'zoo' must be uniform
+test:11:7 note: possibly non-uniform value passed here
   zoo(b);
       ^
 
-test:6:5 note: 'workgroupBarrier' must only be called from uniform control flow
-    workgroupBarrier();
-    ^^^^^^^^^^^^^^^^
+test:11:7 note: parameter 'b' of 'bar' may be non-uniform
+  zoo(b);
+      ^
+
+test:15:7 note: possibly non-uniform value passed here
+  bar(c);
+      ^
+
+test:15:7 note: parameter 'c' of 'foo' may be non-uniform
+  bar(c);
+      ^
+
+test:19:7 note: possibly non-uniform value passed here
+  foo(non_uniform);
+      ^^^^^^^^^^^
 
 test:19:7 note: reading from read_write storage buffer 'non_uniform' may result in a non-uniform value
   foo(non_uniform);
@@ -7957,7 +8042,7 @@
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:17:3 note: control flow depends on non-uniform value
+test:17:3 note: control flow depends on possibly non-uniform value
   if (foo() == 42) {
   ^^
 
@@ -7988,15 +8073,15 @@
 
     RunTest(src, false);
     EXPECT_EQ(error_,
-              R"(test:12:5 warning: 'foo' must only be called from uniform control flow
-    foo(0);
-    ^^^
-
-test:6:5 note: 'foo' requires uniformity because it calls workgroupBarrier
+              R"(test:6:5 warning: 'workgroupBarrier' must only be called from uniform control flow
     workgroupBarrier();
     ^^^^^^^^^^^^^^^^
 
-test:11:3 note: control flow depends on non-uniform value
+test:12:5 note: called by 'foo' from 'main'
+    foo(0);
+    ^^^
+
+test:11:3 note: control flow depends on possibly non-uniform value
   if (non_uniform == 42) {
   ^^