Skip to content

Commit

Permalink
Add more cases to @must_use validation tests
Browse files Browse the repository at this point in the history
  • Loading branch information
amaiorano committed Jan 26, 2024
1 parent 99ff37e commit fba0b4b
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 8 deletions.
1 change: 1 addition & 0 deletions src/webgpu/listing_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -1917,6 +1917,7 @@
"webgpu:shader,validation,parse,must_use:builtin_no_must_use:*": { "subcaseMS": 1.206 },
"webgpu:shader,validation,parse,must_use:call:*": { "subcaseMS": 1.275 },
"webgpu:shader,validation,parse,must_use:declaration:*": { "subcaseMS": 1.523 },
"webgpu:shader,validation,parse,must_use:ignore_result_of_non_must_use_that_returns_call_of_must_use:*": { "subcaseMS": 0.0 },
"webgpu:shader,validation,parse,pipeline_stage:compute_parsing:*": { "subcaseMS": 1.000 },
"webgpu:shader,validation,parse,pipeline_stage:duplicate_compute_on_function:*": { "subcaseMS": 2.651 },
"webgpu:shader,validation,parse,pipeline_stage:duplicate_fragment_on_function:*": { "subcaseMS": 1.001 },
Expand Down
1 change: 1 addition & 0 deletions src/webgpu/shader/execution/expression/expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const allInputSources: InputSource[] = ['const', 'uniform', 'storage_r',
/** Just constant input source */
export const onlyConstInputSource: InputSource[] = ['const'];

/** All input sources except const */
export const allButConstInputSource: InputSource[] = ['uniform', 'storage_r', 'storage_rw'];

/** Configuration for running a expression test */
Expand Down
63 changes: 55 additions & 8 deletions src/webgpu/shader/validation/parse/must_use.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,27 +57,74 @@ g.test('declaration')
});

const kMustUseCalls = {
no_call: ``, // Never calling a @must_use function should pass
phony: `_ = bar();`,
let: `let tmp = bar();`,
var: `var tmp = bar();`,
local_var: `var tmp = bar();`,
private_var: `private_var = bar();`,
storage_var: `storage_var = bar();`,
pointer: `
var a : f32;
let p = &a;
(*p) = bar();`,
vector_elem: `
var a : vec3<f32>;
a.x = bar();`,
matrix_elem: `
var a : mat3x2<f32>;
a[0][0] = bar();`,
condition: `if bar() == 0 { }`,
param: `baz(bar());`,
statement: `bar();`,
return: `return bar();`,
statement: `bar();`, // should fail if bar is @must_use
};

g.test('call')
.desc(`Validate that a call to must_use function cannot be the whole function call statement`)
.params(u => u.combine('use', ['@must_use', ''] as const).combine('call', keysOf(kMustUseCalls)))
.params(u =>
u //
.combine('use', ['@must_use', ''] as const)
.combine('call', keysOf(kMustUseCalls))
)
.fn(t => {
const test = kMustUseCalls[t.params.call];
const code = `
fn baz(param : u32) { }
${t.params.use} fn bar() -> u32 { return 0; }
fn foo() {
@group(0) @binding(0) var<storage, read_write> storage_var : f32;
var<private> private_var : f32;
fn baz(param : f32) { }
${t.params.use} fn bar() -> f32 { return 0; }
fn foo() ${t.params.call === 'return' ? '-> f32' : ''} {
${test}
}`;
const res = t.params.call !== 'statement' || t.params.use === '';
t.expectCompileResult(res, code);

const should_pass = t.params.call !== 'statement' || t.params.use === '';
t.expectCompileResult(should_pass, code);
});

g.test('ignore_result_of_non_must_use_that_returns_call_of_must_use')
.desc(
`Test that ignoring the result of a non-@must_use function that returns the result of a @must_use function succeeds`
)
.fn(t => {
const wgsl = `
@must_use
fn f() -> f32 {
return 0;
}
fn g() -> f32 {
return f();
}
fn main() {
g(); // Ignore result
}
`;

t.expectCompileResult(true, wgsl);
});

const kMustUseBuiltinCalls = {
Expand Down

0 comments on commit fba0b4b

Please sign in to comment.