mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-08-07 12:45:57 +00:00
tint: Add implicit CF_return->{last cf} edge
If the function has no return statements, we need to do this to capture the potential non-uniformity coming from nested function calls. This also removes the need to add explicit edges for discard statements, so remove them. Bug: tint:880 Change-Id: I88b1132faf35a6d36460ef353912f77a15f8abaa Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/89861 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
bf1fe84d35
commit
816148fe32
@ -314,7 +314,8 @@ class UniformityGraph {
|
|||||||
|
|
||||||
// Process function body.
|
// Process function body.
|
||||||
if (func->body) {
|
if (func->body) {
|
||||||
ProcessStatement(current_function_->cf_start, func->body);
|
auto* cf = ProcessStatement(current_function_->cf_start, func->body);
|
||||||
|
current_function_->cf_return->AddEdge(cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TINT_DUMP_UNIFORMITY_GRAPH
|
#if TINT_DUMP_UNIFORMITY_GRAPH
|
||||||
@ -556,10 +557,7 @@ class UniformityGraph {
|
|||||||
return cf;
|
return cf;
|
||||||
},
|
},
|
||||||
|
|
||||||
[&](const ast::DiscardStatement*) {
|
[&](const ast::DiscardStatement*) { return cf; },
|
||||||
current_function_->cf_return->AddEdge(cf);
|
|
||||||
return cf;
|
|
||||||
},
|
|
||||||
|
|
||||||
[&](const ast::FallthroughStatement*) { return cf; },
|
[&](const ast::FallthroughStatement*) { return cf; },
|
||||||
|
|
||||||
|
@ -401,6 +401,47 @@ test:16:3 note: calling 'foo' may cause subsequent control flow to be non-unifor
|
|||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(UniformityAnalysisTest, SubsequentControlFlowMayBeNonUniform_Nested_Fail) {
|
||||||
|
// Indirectly call a function that causes subsequent control flow to be non-uniform, and then
|
||||||
|
// call another function that requires uniformity.
|
||||||
|
// The lack of return statement in `foo()` requires that we implicitly add an edge from
|
||||||
|
// CF_return to that last control flow node of the function.
|
||||||
|
auto src = R"(
|
||||||
|
@group(0) @binding(0) var<storage, read_write> rw : i32;
|
||||||
|
|
||||||
|
var<private> p : i32;
|
||||||
|
|
||||||
|
fn bar() {
|
||||||
|
if (rw == 0) {
|
||||||
|
p = 42;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p = 5;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo() {
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
foo();
|
||||||
|
workgroupBarrier();
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
|
RunTest(src, false);
|
||||||
|
EXPECT_EQ(error_,
|
||||||
|
R"(test:21:3 warning: 'workgroupBarrier' must only be called from uniform control flow
|
||||||
|
workgroupBarrier();
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
test:20:3 note: calling 'foo' may cause subsequent control flow to be non-uniform
|
||||||
|
foo();
|
||||||
|
^^^
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(UniformityAnalysisTest, ParameterNoRestriction_Pass) {
|
TEST_F(UniformityAnalysisTest, ParameterNoRestriction_Pass) {
|
||||||
// Pass a non-uniform value as an argument, and then try to use the return value for
|
// Pass a non-uniform value as an argument, and then try to use the return value for
|
||||||
// control-flow guarding a barrier.
|
// control-flow guarding a barrier.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user