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: Select eagerly evaluates both true and false branches — vector: an atomic
/// in the unchosen branch of a Select still executes, corrupting state that the program
/// assumed was guarded by the condition.
#[test]
fn select_does_not_evaluate_unchosen_branch() {
    let program = Program::new(
        vec![
            BufferDecl::read_write("side_effect", 0, DataType::U32),
            BufferDecl::read_write("out", 1, DataType::U32),
        ],
        [1, 1, 1],
        vec![Node::store(
            "out",
            Expr::u32(0),
            Expr::select(
                Expr::LitBool(true),
                Expr::u32(42),
                Expr::Atomic {
                    op: AtomicOp::Exchange,
                    buffer: "side_effect".to_string(),
                    index: Box::new(Expr::u32(0)),
                    expected: None,
                    value: Box::new(Expr::u32(1)),
                },
            ),
        )],
    );

    // Condition is true, so only the true branch (42) should be evaluated.
    // The atomic in the false branch must NOT execute.
    let outputs = interp::run(&program, &[Value::U32(0), Value::U32(0)])
        .expect("select must not evaluate the unchosen branch");

    assert_eq!(
        outputs[0],
        Value::U32(0),
        "atomic in false branch must not execute"
    );
    assert_eq!(
        outputs[1],
        Value::U32(42),
        "select must return true branch value"
    );
}