vyre-conform 0.1.0

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

/// ADVERSARIAL: eval_binop eagerly evaluates both operands for And/Or — vector: a logical
/// And with a false left-hand side still executes a nested atomic in the right-hand side,
/// leaking side effects that should have been short-circuited.
#[test]
fn logical_and_short_circuits_right_hand_side() {
    let program = Program {
        entry_op_id: None,
        buffers: vec![
            BufferDecl::read_write("side_effect", 0, DataType::U32),
            BufferDecl::read_write("out", 1, DataType::U32),
        ],
        workgroup_size: [1, 1, 1],
        entry: vec![Node::store(
            "out",
            Expr::u32(0),
            Expr::BinOp {
                op: BinOp::And,
                left: Box::new(Expr::u32(0)),
                right: Box::new(Expr::Atomic {
                    op: AtomicOp::Exchange,
                    buffer: "side_effect".to_string(),
                    index: Box::new(Expr::u32(0)),
                    expected: None,
                    value: Box::new(Expr::u32(1)),
                }),
            },
        )],
    };

    let outputs = interp::run(&program, &[Value::U32(0), Value::U32(0)])
        .expect("logical and with short-circuit must not error");

    // The result of And(0, _) is 0, so out should be 0.
    // Crucially, the right-hand atomic must NOT execute because the left side already
    // determines the result.
    assert_eq!(
        outputs[0],
        Value::U32(0),
        "nested atomic must not leak side effects"
    );
    assert_eq!(outputs[1], Value::U32(0), "And result must be 0");
}