Skip to content

Commit 81e81e4

Browse files
authored
Merge pull request #290 from 0xPolygonMiden/greenhat/i263-mem-intrinsics-felts-tests
Add a test for memory intrinsics for storing/loading felts
2 parents 632a045 + 202cb9f commit 81e81e4

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

codegen/masm/src/tests.rs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ use super::*;
1616

1717
const MEMORY_SIZE_BYTES: u32 = 1048576 * 2; // Twice the size of the default Rust shadow stack size
1818
const MEMORY_SIZE_VM_WORDS: u32 = MEMORY_SIZE_BYTES / 16;
19+
/// In miden-sdk-alloc we require all allocations to be minimally word-aligned, i.e. 32 byte
20+
/// alignment
21+
const MIN_ALIGN: u32 = 32;
1922

2023
#[cfg(test)]
2124
#[allow(unused_macros)]
@@ -638,6 +641,87 @@ fn codegen_mem_store_dw_load_dw() {
638641
.unwrap();
639642
}
640643

644+
#[test]
645+
fn codegen_mem_store_felt_load_felt() {
646+
let context = TestContext::default();
647+
let mut builder = ProgramBuilder::new(&context.session.diagnostics);
648+
let mut mb = builder.module("test");
649+
let id = {
650+
let mut fb = mb
651+
.function(
652+
"store_load_felt",
653+
Signature::new(
654+
[AbiParam::new(Type::U32), AbiParam::new(Type::Felt)],
655+
[AbiParam::new(Type::Felt)],
656+
),
657+
)
658+
.expect("unexpected symbol conflict");
659+
let entry = fb.current_block();
660+
let (ptr_u32, value) = {
661+
let args = fb.block_params(entry);
662+
(args[0], args[1])
663+
};
664+
let ptr = fb.ins().inttoptr(ptr_u32, Type::Ptr(Type::Felt.into()), SourceSpan::UNKNOWN);
665+
fb.ins().store(ptr, value, SourceSpan::UNKNOWN);
666+
let loaded_value = fb.ins().load(ptr, SourceSpan::UNKNOWN);
667+
fb.ins().ret(Some(loaded_value), SourceSpan::UNKNOWN);
668+
fb.build().expect("unexpected error building function")
669+
};
670+
671+
mb.build().expect("unexpected error constructing test module");
672+
673+
let program = builder.with_entrypoint(id).link().expect("failed to link program");
674+
675+
let ir_module = program
676+
.modules()
677+
.iter()
678+
.take(1)
679+
.collect::<Vec<&midenc_hir::Module>>()
680+
.first()
681+
.expect("no module in IR program")
682+
.to_string();
683+
684+
eprintln!("{}", ir_module.as_str());
685+
686+
let mut compiler = MasmCompiler::new(&context.session);
687+
let program = compiler
688+
.compile(program)
689+
.expect("compilation failed")
690+
.unwrap_executable()
691+
.freeze();
692+
693+
eprintln!("{}", program);
694+
695+
fn roundtrip(program: Arc<Program>, ptr: u32, value: Felt) -> Felt {
696+
eprintln!("---------------------------------");
697+
eprintln!("testing store_felt/load_felt ptr: {ptr}, value: {value}");
698+
eprintln!("---------------------------------");
699+
let mut harness = TestByEmulationHarness::with_emulator_config(
700+
MEMORY_SIZE_VM_WORDS as usize,
701+
Emulator::DEFAULT_HEAP_START as usize,
702+
Emulator::DEFAULT_LOCALS_START as usize,
703+
true,
704+
);
705+
let mut stack = harness
706+
.execute_program(program.clone(), &[Felt::new(ptr as u64), value])
707+
.expect("execution failed");
708+
stack.pop().unwrap()
709+
}
710+
711+
TestRunner::new(Config::with_cases(1024))
712+
.run(
713+
&(0u32..(MEMORY_SIZE_BYTES / MIN_ALIGN - 1), (0u64..u64::MAX).prop_map(Felt::new)),
714+
move |(word_ptr, value)| {
715+
// a felt memory pointer must be naturally aligned, i.e. a multiple of MIN_ALIGN
716+
let ptr = word_ptr * MIN_ALIGN;
717+
let out = roundtrip(program.clone(), ptr, value);
718+
prop_assert_eq!(out, value);
719+
Ok(())
720+
},
721+
)
722+
.unwrap();
723+
}
724+
641725
#[allow(unused)]
642726
macro_rules! proptest_unary_numeric_op {
643727
($ty_name:ident :: $op:ident, $ty:ty => $ret:ty, $rust_op:ident) => {

0 commit comments

Comments
 (0)