diff --git a/src/tint/resolver/uniformity.cc b/src/tint/resolver/uniformity.cc index a5aa37ddfd..5fed4716d4 100644 --- a/src/tint/resolver/uniformity.cc +++ b/src/tint/resolver/uniformity.cc @@ -15,6 +15,7 @@ #include "src/tint/resolver/uniformity.h" #include +#include #include #include #include @@ -1651,9 +1652,9 @@ class UniformityGraph { /// @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 @@ class UniformityGraph { 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 @@ class UniformityGraph { // 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 @@ class UniformityGraph { case ast::AddressSpace::kPrivate: return "module-scope private variable "; default: - if (ast::HasAttribute(var->Declaration()->attributes)) { - return "builtin "; - } else if (ast::HasAttribute( - var->Declaration()->attributes)) { - return "user-defined input "; - } else { - // TODO(jrprice): Provide more info for this case. - } - break; + return ""; + } + }; + auto param_type = [&](const sem::Parameter* param) { + if (ast::HasAttribute(param->Declaration()->attributes)) { + return "builtin "; + } else if (ast::HasAttribute( + param->Declaration()->attributes)) { + return "user-defined input "; + } else { + return "parameter "; } - return ""; }; // Show the source of the non-uniform value. @@ -1704,19 +1714,23 @@ class UniformityGraph { non_uniform_source->ast, [&](const ast::IdentifierExpression* ident) { auto* var = sem_.Get(ident)->UnwrapLoad()->As()->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()) { + auto* func = param->Owner()->As(); + 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 @@ class UniformityGraph { 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 @@ class UniformityGraph { 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 @@ class UniformityGraph { /// 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 @@ class UniformityGraph { auto* call = cause->ast->As(); 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()) { - func_name = builtin->str(); - } else if (auto* user = target->As()) { - 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(); + 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()) { - 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()) { - 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_innermost_call->Stmt()->Function()) { - indirect = true; - } - - auto* builtin = sem_innermost_call->Target()->As(); - 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() != 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 51e607a4a2..5052a1f3db 100644 --- a/src/tint/resolver/uniformity_test.cc +++ b/src/tint/resolver/uniformity_test.cc @@ -326,7 +326,6 @@ fn foo() { 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 @@ fn bar() { 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 @@ fn bar() { 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 @@ fn main(@builtin()" + GetParam().name + 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 @@ fn main(s : S) { 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 @@ fn main(s : S) { 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 @@ fn main(@builtin()" + GetParam().name + 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 @@ fn main(s : S) { 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 @@ fn main(@location(0) l : f32) { 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 @@ fn main(s : S) { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn main() { 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 @@ fn main() { 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 @@ fn main() { 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 @@ fn main() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 non_uniform : i32; ^^^^^^^^^^^ @@ -3809,7 +3832,7 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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) { + ^ + +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 @@ fn foo() { 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 @@ fn foo() { 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) { + ^ + +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(0, 0, 0, non_uniform); @@ -4141,7 +4204,7 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo(p : ptr) { 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 @@ fn foo() { 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 @@ fn main() { 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 @@ fn main() { 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 @@ fn main() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ TEST_F(UniformityAnalysisTest, MaximumNumberOfPointerParameters) { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn foo() { 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(non_uniform_global) == 0.0) { ^^ @@ -7265,7 +7328,7 @@ fn foo() { 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 @@ fn foo() { 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 @@ fn main() { 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 @@ fn foo() { 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 @@ fn main(@builtin(local_invocation_index) idx : u32) { )"; 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 @@ fn main(@builtin(local_invocation_index) idx : u32) { )"; 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 @@ fn foo() { 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 @@ fn foo() { 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 @@ TEST_F(UniformityAnalysisTest, StressGraphTraversalDepth) { 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 @@ fn main() { 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 @@ fn main() { 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 @@ fn main() { 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 @@ fn main() { 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 @@ fn main() { 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) { ^^