Skip to content

Commit 67c7a2f

Browse files
authored
Test swizzle assignment eval order (#4608)
Test that the lhs swizzle's vector pointer is evaluated before the rhs, and that it's value as a swizzle is loaded before rhs. Then check that it is re-loaded after rhs evaluation for use in the store of the whole swizzle assignment vector, because side effects from the rhs on non-swizzled components should persist.
1 parent 54441b8 commit 67c7a2f

2 files changed

Lines changed: 76 additions & 0 deletions

File tree

src/webgpu/listing_meta.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,8 @@
20662066
"webgpu:shader,execution,statement,increment_decrement:vec4_element_decrement:*": { "subcaseMS": 5.300 },
20672067
"webgpu:shader,execution,statement,increment_decrement:vec4_element_increment:*": { "subcaseMS": 6.300 },
20682068
"webgpu:shader,execution,statement,phony:executes:*": { "subcaseMS": 129.949 },
2069+
"webgpu:shader,execution,statement,swizzle_assignment:compound_eval_order:*": { "subcaseMS": 16.651 },
2070+
"webgpu:shader,execution,statement,swizzle_assignment:eval_order:*": { "subcaseMS": 17.193 },
20692071
"webgpu:shader,execution,statement,swizzle_assignment:swizzle_assignment_vars:*": { "subcaseMS": 1200.970 },
20702072
"webgpu:shader,execution,statement,swizzle_assignment:swizzle_compound_assignment:*": { "subcaseMS": 0.091 },
20712073
"webgpu:shader,execution,value_init:array,nested:*": { "subcaseMS": 3004.523 },

src/webgpu/shader/execution/statement/swizzle_assignment.spec.ts

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { keysOf } from '../../../../common/util/data_tables.js';
77
import { TypedArrayBufferView } from '../../../../common/util/util.js';
88
import { Float16Array } from '../../../../external/petamoriken/float16/float16.js';
99
import { AllFeaturesMaxLimitsGPUTest, GPUTest } from '../../../gpu_test.js';
10+
import { runFlowControlTest } from '../flow_control/harness.js';
1011

1112
export const g = makeTestGroup(AllFeaturesMaxLimitsGPUTest);
1213

@@ -420,3 +421,76 @@ fn main() {
420421
}`;
421422
runSwizzleAssignmentTest(t, elemType, expected, wgsl);
422423
});
424+
425+
g.test('eval_order')
426+
.desc(
427+
'Tests that the vec pointer on the lhs of a swizzle assignment is evaluated before the rhs, and the load of the lhs vec happens after rhs.'
428+
)
429+
.fn(t => {
430+
t.skipIfLanguageFeatureNotSupported('swizzle_assignment');
431+
runFlowControlTest(t, f => ({
432+
entrypoint: `
433+
arr[0] = vec4u(1, 1, 1, 1);
434+
${f.expect_order(0)}
435+
arr[foo()].xy = bar();
436+
${f.expect_order(3)}
437+
if (all(arr[0] == vec4u(4, 5, 3, 8))) {
438+
${f.expect_order(4)}
439+
} else {
440+
${f.expect_not_reached()}
441+
}
442+
`,
443+
extra: `
444+
var<private> arr : array<vec4u, 1>;
445+
fn foo() -> u32 {
446+
${f.expect_order(1)}
447+
arr[0].x = 6; // overwritten by swizzle
448+
arr[0].z = 7; // overwritten by bar()
449+
arr[0].w = 8; // persists
450+
return 0;
451+
}
452+
fn bar() -> vec2u {
453+
${f.expect_order(2)}
454+
arr[0].z = 3; // persists
455+
return vec2u(4, 5); // will set x,y
456+
}
457+
`,
458+
}));
459+
});
460+
461+
g.test('compound_eval_order')
462+
.desc(
463+
'Tests that the lhs of a swizzle compound assignment is evaluated before the rhs, and another load of the lhs vec happens after rhs evaluation, without re-evaluating the pointer to the lhs vec.'
464+
)
465+
.fn(t => {
466+
t.skipIfLanguageFeatureNotSupported('swizzle_assignment');
467+
runFlowControlTest(t, f => ({
468+
entrypoint: `
469+
arr[0] = vec4u(1, 1, 1, 1);
470+
${f.expect_order(0)}
471+
arr[foo()].xy += bar();
472+
${f.expect_order(3)}
473+
if (all(arr[0] == vec4u(10, 6, 3, 8))) {
474+
${f.expect_order(4)}
475+
} else {
476+
${f.expect_not_reached()}
477+
}
478+
`,
479+
extra: `
480+
var<private> arr : array<vec4u, 1>;
481+
fn foo() -> u32 {
482+
${f.expect_order(1)}
483+
arr[0].x = 6; // modifies x before add
484+
arr[0].z = 7; // overwritten by bar()
485+
arr[0].w = 8; // persists
486+
return 0;
487+
}
488+
fn bar() -> vec2u {
489+
${f.expect_order(2)}
490+
arr[0].x = 2; // no visible effect
491+
arr[0].z = 3; // persists
492+
return vec2u(4, 5); // will add to x,y
493+
}
494+
`,
495+
}));
496+
});

0 commit comments

Comments
 (0)