tint/uniformity: Use non-recursive graph traversal
Fixes a stack overflow when traversing particularly deep graphs. This changes the iteration order which changes some of the diagnostic notes, but the diagnostics are still correct and deterministic so it does not matter. Fixed: chromium:47418 Change-Id: I2def633b6d96d1525027f7929b0fa0a6fba0efeb Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/90140 Auto-Submit: James Price <jrprice@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
a89ff5981b
commit
35f0fcaac0
|
@ -1269,18 +1269,25 @@ class UniformityGraph {
|
||||||
return {cf_after, result};
|
return {cf_after, result};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively traverse a graph starting at `node`, inserting all nodes that are reached into
|
/// Traverse a graph starting at `source`, inserting all visited nodes into `reachable` and
|
||||||
/// `reachable`.
|
/// recording which node they were reached from.
|
||||||
/// @param node the starting node
|
/// @param source the starting node
|
||||||
/// @param reachable the set of reachable nodes to populate, if required
|
/// @param reachable the set of reachable nodes to populate, if required
|
||||||
void Traverse(Node* node, utils::UniqueVector<Node*>* reachable = nullptr) {
|
void Traverse(Node* source, utils::UniqueVector<Node*>* reachable = nullptr) {
|
||||||
|
std::vector<Node*> to_visit{source};
|
||||||
|
|
||||||
|
while (!to_visit.empty()) {
|
||||||
|
auto* node = to_visit.back();
|
||||||
|
to_visit.pop_back();
|
||||||
|
|
||||||
if (reachable) {
|
if (reachable) {
|
||||||
reachable->add(node);
|
reachable->add(node);
|
||||||
}
|
}
|
||||||
for (auto* to : node->edges) {
|
for (auto* to : node->edges) {
|
||||||
if (to->visited_from == nullptr) {
|
if (to->visited_from == nullptr) {
|
||||||
to->visited_from = node;
|
to->visited_from = node;
|
||||||
Traverse(to, reachable);
|
to_visit.push_back(to);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5907,6 +5907,41 @@ fn foo() {
|
||||||
RunTest(src, true);
|
RunTest(src, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(UniformityAnalysisTest, StressGraphTraversalDepth) {
|
||||||
|
// Create a function with a very long sequence of variable declarations and assignments to
|
||||||
|
// test traversals of very deep graphs. This requires a non-recursive traversal algorithm.
|
||||||
|
ProgramBuilder b;
|
||||||
|
auto& ty = b.ty;
|
||||||
|
|
||||||
|
// var<private> v0 : i32 = 0i;
|
||||||
|
// fn foo() {
|
||||||
|
// let v1 = v0;
|
||||||
|
// let v2 = v1;
|
||||||
|
// ...
|
||||||
|
// let v{N} = v{N-1};
|
||||||
|
// if (v{N} == 0) {
|
||||||
|
// workgroupBarrier();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
b.Global("v0", ty.i32(), ast::StorageClass::kPrivate, b.Expr(0_i));
|
||||||
|
ast::StatementList foo_body;
|
||||||
|
std::string v_last = "v0";
|
||||||
|
for (int i = 1; i < 100000; i++) {
|
||||||
|
auto v = "v" + std::to_string(i);
|
||||||
|
foo_body.push_back(b.Decl(b.Var(v, nullptr, b.Expr(v_last))));
|
||||||
|
v_last = v;
|
||||||
|
}
|
||||||
|
foo_body.push_back(b.If(b.Equal(v_last, 0_i), b.Block(b.CallStmt(b.Call("workgroupBarrier")))));
|
||||||
|
b.Func("foo", {}, ty.void_(), foo_body);
|
||||||
|
|
||||||
|
// TODO(jrprice): Expect false when uniformity issues become errors.
|
||||||
|
EXPECT_TRUE(RunTest(std::move(b))) << error_;
|
||||||
|
EXPECT_EQ(error_,
|
||||||
|
R"(warning: 'workgroupBarrier' must only be called from uniform control flow
|
||||||
|
note: control flow depends on non-uniform value
|
||||||
|
note: reading from module-scope private variable 'v0' may result in a non-uniform value)");
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// Tests for the quality of the error messages produced by the analysis.
|
/// Tests for the quality of the error messages produced by the analysis.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -6,8 +6,8 @@ bug/dawn/947.wgsl:55:5 note: control flow depends on non-uniform value
|
||||||
if (!all(clampedTexcoord == texcoord)) {
|
if (!all(clampedTexcoord == texcoord)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/dawn/947.wgsl:54:15 note: reading from user-defined input 'texcoord' may result in a non-uniform value
|
bug/dawn/947.wgsl:55:33 note: reading from user-defined input 'texcoord' may result in a non-uniform value
|
||||||
clamp(texcoord, vec2<f32>(0.0, 0.0), vec2<f32>(1.0, 1.0));
|
if (!all(clampedTexcoord == texcoord)) {
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
#version 310 es
|
#version 310 es
|
||||||
|
|
|
@ -6,8 +6,8 @@ bug/dawn/947.wgsl:55:5 note: control flow depends on non-uniform value
|
||||||
if (!all(clampedTexcoord == texcoord)) {
|
if (!all(clampedTexcoord == texcoord)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/dawn/947.wgsl:54:15 note: reading from user-defined input 'texcoord' may result in a non-uniform value
|
bug/dawn/947.wgsl:55:33 note: reading from user-defined input 'texcoord' may result in a non-uniform value
|
||||||
clamp(texcoord, vec2<f32>(0.0, 0.0), vec2<f32>(1.0, 1.0));
|
if (!all(clampedTexcoord == texcoord)) {
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
cbuffer cbuffer_uniforms : register(b0, space0) {
|
cbuffer cbuffer_uniforms : register(b0, space0) {
|
||||||
|
|
|
@ -6,8 +6,8 @@ bug/dawn/947.wgsl:55:5 note: control flow depends on non-uniform value
|
||||||
if (!all(clampedTexcoord == texcoord)) {
|
if (!all(clampedTexcoord == texcoord)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/dawn/947.wgsl:54:15 note: reading from user-defined input 'texcoord' may result in a non-uniform value
|
bug/dawn/947.wgsl:55:33 note: reading from user-defined input 'texcoord' may result in a non-uniform value
|
||||||
clamp(texcoord, vec2<f32>(0.0, 0.0), vec2<f32>(1.0, 1.0));
|
if (!all(clampedTexcoord == texcoord)) {
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
#include <metal_stdlib>
|
#include <metal_stdlib>
|
||||||
|
|
|
@ -6,8 +6,8 @@ bug/dawn/947.wgsl:55:5 note: control flow depends on non-uniform value
|
||||||
if (!all(clampedTexcoord == texcoord)) {
|
if (!all(clampedTexcoord == texcoord)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/dawn/947.wgsl:54:15 note: reading from user-defined input 'texcoord' may result in a non-uniform value
|
bug/dawn/947.wgsl:55:33 note: reading from user-defined input 'texcoord' may result in a non-uniform value
|
||||||
clamp(texcoord, vec2<f32>(0.0, 0.0), vec2<f32>(1.0, 1.0));
|
if (!all(clampedTexcoord == texcoord)) {
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
; SPIR-V
|
; SPIR-V
|
||||||
|
|
|
@ -6,8 +6,8 @@ bug/dawn/947.wgsl:55:5 note: control flow depends on non-uniform value
|
||||||
if (!all(clampedTexcoord == texcoord)) {
|
if (!all(clampedTexcoord == texcoord)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/dawn/947.wgsl:54:15 note: reading from user-defined input 'texcoord' may result in a non-uniform value
|
bug/dawn/947.wgsl:55:33 note: reading from user-defined input 'texcoord' may result in a non-uniform value
|
||||||
clamp(texcoord, vec2<f32>(0.0, 0.0), vec2<f32>(1.0, 1.0));
|
if (!all(clampedTexcoord == texcoord)) {
|
||||||
^^^^^^^^
|
^^^^^^^^
|
||||||
|
|
||||||
struct Uniforms {
|
struct Uniforms {
|
||||||
|
|
|
@ -2,13 +2,13 @@ bug/tint/948.wgsl:146:33 warning: 'textureSampleBias' must only be called from u
|
||||||
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
bug/tint/948.wgsl:125:5 note: control flow depends on non-uniform value
|
bug/tint/948.wgsl:138:9 note: control flow depends on non-uniform value
|
||||||
if ((x_174 > 0.0)) {
|
if ((x_197 > x_198)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/tint/948.wgsl:146:33 note: return value of 'textureSampleBias' may be non-uniform
|
bug/tint/948.wgsl:137:27 note: reading from module-scope private variable 'mt' may result in a non-uniform value
|
||||||
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
let x_198 : f32 = mt;
|
||||||
^^^^^^^^^^^^^^^^^
|
^^
|
||||||
|
|
||||||
#version 310 es
|
#version 310 es
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
|
@ -2,13 +2,13 @@ bug/tint/948.wgsl:146:33 warning: 'textureSampleBias' must only be called from u
|
||||||
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
bug/tint/948.wgsl:125:5 note: control flow depends on non-uniform value
|
bug/tint/948.wgsl:138:9 note: control flow depends on non-uniform value
|
||||||
if ((x_174 > 0.0)) {
|
if ((x_197 > x_198)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/tint/948.wgsl:146:33 note: return value of 'textureSampleBias' may be non-uniform
|
bug/tint/948.wgsl:137:27 note: reading from module-scope private variable 'mt' may result in a non-uniform value
|
||||||
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
let x_198 : f32 = mt;
|
||||||
^^^^^^^^^^^^^^^^^
|
^^
|
||||||
|
|
||||||
cbuffer cbuffer_x_20 : register(b9, space2) {
|
cbuffer cbuffer_x_20 : register(b9, space2) {
|
||||||
uint4 x_20[8];
|
uint4 x_20[8];
|
||||||
|
|
|
@ -2,13 +2,13 @@ bug/tint/948.wgsl:146:33 warning: 'textureSampleBias' must only be called from u
|
||||||
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
bug/tint/948.wgsl:125:5 note: control flow depends on non-uniform value
|
bug/tint/948.wgsl:138:9 note: control flow depends on non-uniform value
|
||||||
if ((x_174 > 0.0)) {
|
if ((x_197 > x_198)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/tint/948.wgsl:146:33 note: return value of 'textureSampleBias' may be non-uniform
|
bug/tint/948.wgsl:137:27 note: reading from module-scope private variable 'mt' may result in a non-uniform value
|
||||||
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
let x_198 : f32 = mt;
|
||||||
^^^^^^^^^^^^^^^^^
|
^^
|
||||||
|
|
||||||
#include <metal_stdlib>
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,13 @@ bug/tint/948.wgsl:146:33 warning: 'textureSampleBias' must only be called from u
|
||||||
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
bug/tint/948.wgsl:125:5 note: control flow depends on non-uniform value
|
bug/tint/948.wgsl:138:9 note: control flow depends on non-uniform value
|
||||||
if ((x_174 > 0.0)) {
|
if ((x_197 > x_198)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/tint/948.wgsl:146:33 note: return value of 'textureSampleBias' may be non-uniform
|
bug/tint/948.wgsl:137:27 note: reading from module-scope private variable 'mt' may result in a non-uniform value
|
||||||
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
let x_198 : f32 = mt;
|
||||||
^^^^^^^^^^^^^^^^^
|
^^
|
||||||
|
|
||||||
; SPIR-V
|
; SPIR-V
|
||||||
; Version: 1.3
|
; Version: 1.3
|
||||||
|
|
|
@ -2,13 +2,13 @@ bug/tint/948.wgsl:146:33 warning: 'textureSampleBias' must only be called from u
|
||||||
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
||||||
^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
bug/tint/948.wgsl:125:5 note: control flow depends on non-uniform value
|
bug/tint/948.wgsl:138:9 note: control flow depends on non-uniform value
|
||||||
if ((x_174 > 0.0)) {
|
if ((x_197 > x_198)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/tint/948.wgsl:146:33 note: return value of 'textureSampleBias' may be non-uniform
|
bug/tint/948.wgsl:137:27 note: reading from module-scope private variable 'mt' may result in a non-uniform value
|
||||||
let x_217 : vec4<f32> = textureSampleBias(animationMapTexture, animationMapSampler, vec2<f32>(((x_208 + 0.5) / x_211), (0.125 * x_214)), 0.0);
|
let x_198 : f32 = mt;
|
||||||
^^^^^^^^^^^^^^^^^
|
^^
|
||||||
|
|
||||||
struct LeftOver {
|
struct LeftOver {
|
||||||
time : f32,
|
time : f32,
|
||||||
|
|
|
@ -6,9 +6,9 @@ bug/tint/949.wgsl:330:5 note: control flow depends on non-uniform value
|
||||||
if ((x_400 > x_401)) {
|
if ((x_400 > x_401)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/tint/949.wgsl:326:29 note: return value of 'textureSample' may be non-uniform
|
bug/tint/949.wgsl:308:27 note: reading from module-scope private variable 'v_output2' may result in a non-uniform value
|
||||||
let x_397 : vec4<f32> = textureSample(TextureSamplerTexture, TextureSamplerSampler, (x_394 + x_395));
|
let x_366 : vec4<f32> = v_output2;
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
#version 310 es
|
#version 310 es
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
|
|
|
@ -6,9 +6,9 @@ bug/tint/949.wgsl:330:5 note: control flow depends on non-uniform value
|
||||||
if ((x_400 > x_401)) {
|
if ((x_400 > x_401)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/tint/949.wgsl:326:29 note: return value of 'textureSample' may be non-uniform
|
bug/tint/949.wgsl:308:27 note: reading from module-scope private variable 'v_output2' may result in a non-uniform value
|
||||||
let x_397 : vec4<f32> = textureSample(TextureSamplerTexture, TextureSamplerSampler, (x_394 + x_395));
|
let x_366 : vec4<f32> = v_output2;
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
struct lightingInfo {
|
struct lightingInfo {
|
||||||
float3 diffuse;
|
float3 diffuse;
|
||||||
|
|
|
@ -6,9 +6,9 @@ bug/tint/949.wgsl:330:5 note: control flow depends on non-uniform value
|
||||||
if ((x_400 > x_401)) {
|
if ((x_400 > x_401)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/tint/949.wgsl:326:29 note: return value of 'textureSample' may be non-uniform
|
bug/tint/949.wgsl:308:27 note: reading from module-scope private variable 'v_output2' may result in a non-uniform value
|
||||||
let x_397 : vec4<f32> = textureSample(TextureSamplerTexture, TextureSamplerSampler, (x_394 + x_395));
|
let x_366 : vec4<f32> = v_output2;
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
#include <metal_stdlib>
|
#include <metal_stdlib>
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ bug/tint/949.wgsl:330:5 note: control flow depends on non-uniform value
|
||||||
if ((x_400 > x_401)) {
|
if ((x_400 > x_401)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/tint/949.wgsl:326:29 note: return value of 'textureSample' may be non-uniform
|
bug/tint/949.wgsl:308:27 note: reading from module-scope private variable 'v_output2' may result in a non-uniform value
|
||||||
let x_397 : vec4<f32> = textureSample(TextureSamplerTexture, TextureSamplerSampler, (x_394 + x_395));
|
let x_366 : vec4<f32> = v_output2;
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
; SPIR-V
|
; SPIR-V
|
||||||
; Version: 1.3
|
; Version: 1.3
|
||||||
|
|
|
@ -6,9 +6,9 @@ bug/tint/949.wgsl:330:5 note: control flow depends on non-uniform value
|
||||||
if ((x_400 > x_401)) {
|
if ((x_400 > x_401)) {
|
||||||
^^
|
^^
|
||||||
|
|
||||||
bug/tint/949.wgsl:326:29 note: return value of 'textureSample' may be non-uniform
|
bug/tint/949.wgsl:308:27 note: reading from module-scope private variable 'v_output2' may result in a non-uniform value
|
||||||
let x_397 : vec4<f32> = textureSample(TextureSamplerTexture, TextureSamplerSampler, (x_394 + x_395));
|
let x_366 : vec4<f32> = v_output2;
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^
|
||||||
|
|
||||||
struct lightingInfo {
|
struct lightingInfo {
|
||||||
diffuse : vec3<f32>,
|
diffuse : vec3<f32>,
|
||||||
|
|
Loading…
Reference in New Issue