vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
use vyre::ir::{AtomicOp, BufferDecl, DataType, Expr, Node, Program};
use vyre_conform::{reference::interp, spec::value::Value};

/// ADVERSARIAL: eval_atomic evaluates expected operand before OOB check — vector: a nested
/// atomic inside the expected expression of CompareExchange executes even when the outer
/// atomic target is empty and the operation will be discarded.
#[test]
fn compare_exchange_expected_is_not_evaluated_when_oob() {
    let program = Program {
        entry_op_id: None,
        buffers: vec![
            BufferDecl::read_write("empty", 0, DataType::U32),
            BufferDecl::read_write("side_effect", 1, DataType::U32),
        ],
        workgroup_size: [1, 1, 1],
        entry: vec![Node::store(
            "empty",
            Expr::u32(0),
            Expr::Atomic {
                op: AtomicOp::CompareExchange,
                buffer: "empty".to_string(),
                index: Box::new(Expr::u32(0)),
                expected: Some(Box::new(Expr::atomic_add(
                    "side_effect",
                    Expr::u32(0),
                    Expr::u32(1),
                ))),
                value: Box::new(Expr::u32(42)),
            },
        )],
    };

    // The outer CompareExchange on "empty" (0 bytes) is OOB, so it must be a no-op.
    // The nested atomic inside expected must NOT execute.
    let outputs = interp::run(
        &program,
        &[Value::Bytes(vec![]), Value::Bytes(vec![0, 0, 0, 0])],
    )
    .expect("OOB compare-exchange must not evaluate nested side effects");

    assert_eq!(
        outputs,
        vec![Value::Bytes(vec![]), Value::Bytes(vec![0, 0, 0, 0])]
    );
}