use vyre::ir::{BufferDecl, DataType, Expr, Node, Program};
use vyre_conform::{reference::interp, spec::value::Value};
/// ADVERSARIAL: finished invocation retains stale uniform-check — vector: a done invocation's
/// past branch observation falsely triggers a uniform-control-flow violation when a later
/// invocation legitimately reaches the same barrier with a different condition.
#[test]
fn done_invocation_does_not_corrupt_barrier_uniformity() {
let program = Program {
entry_op_id: None,
buffers: vec![BufferDecl::read_write("out", 0, DataType::U32)],
workgroup_size: [2, 1, 1],
entry: vec![
Node::if_then_else(
Expr::eq(Expr::LocalId { axis: 0 }, Expr::u32(0)),
vec![Node::Barrier],
vec![],
),
Node::store("out", Expr::u32(0), Expr::u32(1)),
],
};
// Invocation 0: local_id=0, condition=true, hits barrier then store.
// Invocation 1: local_id=1, condition=false, skips barrier then store.
// Per spec, the barrier is only reached by invocation 0; invocation 1 is done and must not
// participate in the uniformity check. A buggy interpreter that filters on !returned instead
// of !done() includes invocation 1 and falsely reports a mismatch.
let outputs = interp::run(&program, &[Value::Bytes(vec![0; 4])])
.expect("valid divergent barrier path must not falsely trigger uniformity error");
assert_eq!(outputs, vec![Value::Bytes(vec![1, 0, 0, 0])]);
}