1
1
#![ allow( unused_imports) ]
2
- use std:: sync:: Arc ;
2
+ use std:: { fmt :: Display , sync:: Arc } ;
3
3
4
4
use midenc_hir:: {
5
5
self as hir,
@@ -500,83 +500,18 @@ fn i32_checked_neg() {
500
500
harness. invoke ( neg, & [ min] ) . expect ( "execution failed" ) ;
501
501
}
502
502
503
- #[ test]
504
- fn codegen_mem_store_sw_load_sw ( ) {
505
- let context = TestContext :: default ( ) ;
506
- let mut builder = ProgramBuilder :: new ( & context. session . diagnostics ) ;
507
- let mut mb = builder. module ( "test" ) ;
508
- let id = {
509
- let mut fb = mb
510
- . function (
511
- "store_load_sw" ,
512
- Signature :: new (
513
- [ AbiParam :: new ( Type :: U32 ) , AbiParam :: new ( Type :: U32 ) ] ,
514
- [ AbiParam :: new ( Type :: U32 ) ] ,
515
- ) ,
516
- )
517
- . expect ( "unexpected symbol conflict" ) ;
518
- let entry = fb. current_block ( ) ;
519
- let ( ptr_u32, value) = {
520
- let args = fb. block_params ( entry) ;
521
- ( args[ 0 ] , args[ 1 ] )
522
- } ;
523
- let ptr = fb. ins ( ) . inttoptr ( ptr_u32, Type :: Ptr ( Type :: U32 . into ( ) ) , SourceSpan :: UNKNOWN ) ;
524
- fb. ins ( ) . store ( ptr, value, SourceSpan :: UNKNOWN ) ;
525
- let loaded_value = fb. ins ( ) . load ( ptr, SourceSpan :: UNKNOWN ) ;
526
- fb. ins ( ) . ret ( Some ( loaded_value) , SourceSpan :: UNKNOWN ) ;
527
- fb. build ( ) . expect ( "unexpected error building function" )
528
- } ;
529
-
530
- mb. build ( ) . expect ( "unexpected error constructing test module" ) ;
531
-
532
- let program = builder. with_entrypoint ( id) . link ( ) . expect ( "failed to link program" ) ;
533
-
534
- let mut compiler = MasmCompiler :: new ( & context. session ) ;
535
- let program = compiler
536
- . compile ( program)
537
- . expect ( "compilation failed" )
538
- . unwrap_executable ( )
539
- . freeze ( ) ;
540
-
541
- // eprintln!("{}", program);
542
-
543
- fn roundtrip ( program : Arc < Program > , ptr : u32 , value : u32 ) -> u32 {
544
- eprintln ! ( "---------------------------------" ) ;
545
- eprintln ! ( "testing store_sw/load_sw ptr: {ptr}, value: {value}" ) ;
546
- eprintln ! ( "---------------------------------" ) ;
547
- let mut harness = TestByEmulationHarness :: with_emulator_config (
548
- MEMORY_SIZE_VM_WORDS as usize ,
549
- Emulator :: DEFAULT_HEAP_START as usize ,
550
- Emulator :: DEFAULT_LOCALS_START as usize ,
551
- true ,
552
- ) ;
553
- let mut stack = harness
554
- . execute_program ( program. clone ( ) , & [ Felt :: new ( ptr as u64 ) , Felt :: new ( value as u64 ) ] )
555
- . expect ( "execution failed" ) ;
556
- stack. pop ( ) . unwrap ( ) . as_int ( ) as u32
557
- }
558
-
559
- TestRunner :: new ( Config :: with_cases ( 1024 ) )
560
- . run ( & ( 0u32 ..MEMORY_SIZE_BYTES - 4 , any :: < u32 > ( ) ) , move |( ptr, value) | {
561
- let out = roundtrip ( program. clone ( ) , ptr, value) ;
562
- prop_assert_eq ! ( out, value) ;
563
- Ok ( ( ) )
564
- } )
565
- . unwrap ( ) ;
566
- }
567
-
568
- #[ test]
569
- fn codegen_mem_store_dw_load_dw ( ) {
503
+ fn roundtrip_store_t_load_t < T : ToCanonicalRepr + Display > ( ty : Type ) -> impl Fn ( u32 , T ) -> T {
570
504
let context = TestContext :: default ( ) ;
571
505
let mut builder = ProgramBuilder :: new ( & context. session . diagnostics ) ;
572
506
let mut mb = builder. module ( "test" ) ;
507
+ let type_name = ty. to_string ( ) ;
573
508
let id = {
574
509
let mut fb = mb
575
510
. function (
576
- "store_load_dw" ,
511
+ format ! ( "store_load_{type_name}" ) . as_str ( ) ,
577
512
Signature :: new (
578
- [ AbiParam :: new ( Type :: U32 ) , AbiParam :: new ( Type :: U64 ) ] ,
579
- [ AbiParam :: new ( Type :: U64 ) ] ,
513
+ [ AbiParam :: new ( Type :: U32 ) , AbiParam :: new ( ty . clone ( ) ) ] ,
514
+ [ AbiParam :: new ( ty . clone ( ) ) ] ,
580
515
) ,
581
516
)
582
517
. expect ( "unexpected symbol conflict" ) ;
@@ -585,7 +520,7 @@ fn codegen_mem_store_dw_load_dw() {
585
520
let args = fb. block_params ( entry) ;
586
521
( args[ 0 ] , args[ 1 ] )
587
522
} ;
588
- let ptr = fb. ins ( ) . inttoptr ( ptr_u32, Type :: Ptr ( Type :: U64 . into ( ) ) , SourceSpan :: UNKNOWN ) ;
523
+ let ptr = fb. ins ( ) . inttoptr ( ptr_u32, Type :: Ptr ( ty . into ( ) ) , SourceSpan :: UNKNOWN ) ;
589
524
fb. ins ( ) . store ( ptr, value, SourceSpan :: UNKNOWN ) ;
590
525
let loaded_value = fb. ins ( ) . load ( ptr, SourceSpan :: UNKNOWN ) ;
591
526
fb. ins ( ) . ret ( Some ( loaded_value) , SourceSpan :: UNKNOWN ) ;
@@ -616,112 +551,104 @@ fn codegen_mem_store_dw_load_dw() {
616
551
617
552
eprintln ! ( "{}" , program) ;
618
553
619
- fn roundtrip ( program : Arc < Program > , ptr : u32 , value : u64 ) -> u64 {
554
+ move | ptr : u32 , value : T | -> T {
620
555
eprintln ! ( "---------------------------------" ) ;
621
- eprintln ! ( "testing store_dw/load_dw ptr: {ptr}, value: {value}" ) ;
556
+ eprintln ! ( "testing store {type_name}/load {type_name} ptr: {ptr}, value: {value}" ) ;
622
557
eprintln ! ( "---------------------------------" ) ;
623
558
let mut harness = TestByEmulationHarness :: with_emulator_config (
624
559
MEMORY_SIZE_VM_WORDS as usize ,
625
560
Emulator :: DEFAULT_HEAP_START as usize ,
626
561
Emulator :: DEFAULT_LOCALS_START as usize ,
627
562
true ,
628
563
) ;
564
+
629
565
let mut args: SmallVec < [ Felt ; 4 ] > = smallvec ! ( Felt :: new( ptr as u64 ) ) ;
630
566
args. extend ( value. canonicalize ( ) ) ;
631
567
let mut stack = harness. execute_program ( program. clone ( ) , & args) . expect ( "execution failed" ) ;
632
- u64 :: from_stack ( & mut stack)
568
+ ToCanonicalRepr :: from_stack ( & mut stack)
633
569
}
634
-
635
- TestRunner :: new ( Config :: with_cases ( 1024 ) )
636
- . run ( & ( 0u32 ..MEMORY_SIZE_BYTES - 4 , any :: < u64 > ( ) ) , move |( ptr, value) | {
637
- let out = roundtrip ( program. clone ( ) , ptr, value) ;
638
- prop_assert_eq ! ( out, value) ;
639
- Ok ( ( ) )
640
- } )
641
- . unwrap ( ) ;
642
570
}
643
571
644
572
#[ 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
-
573
+ fn codegen_mem_store_load_felt ( ) {
574
+ let roundtrip = roundtrip_store_t_load_t :: < Felt > ( Type :: Felt ) ;
711
575
TestRunner :: new ( Config :: with_cases ( 1024 ) )
712
576
. run (
713
577
& ( 0u32 ..( MEMORY_SIZE_BYTES / MIN_ALIGN - 1 ) , ( 0u64 ..u64:: MAX ) . prop_map ( Felt :: new) ) ,
714
578
move |( word_ptr, value) | {
715
579
// a felt memory pointer must be naturally aligned, i.e. a multiple of MIN_ALIGN
716
580
let ptr = word_ptr * MIN_ALIGN ;
717
- let out = roundtrip ( program . clone ( ) , ptr, value) ;
581
+ let out = roundtrip ( ptr, value) ;
718
582
prop_assert_eq ! ( out, value) ;
719
583
Ok ( ( ) )
720
584
} ,
721
585
)
722
586
. unwrap ( ) ;
723
587
}
724
588
589
+ #[ test]
590
+ fn codegen_mem_store_load_u32 ( ) {
591
+ let roundtrip = roundtrip_store_t_load_t :: < u32 > ( Type :: U32 ) ;
592
+ TestRunner :: new ( Config :: with_cases ( 1024 ) )
593
+ . run ( & ( 0u32 ..MEMORY_SIZE_BYTES - 4 , any :: < u32 > ( ) ) , move |( ptr, value) | {
594
+ let out = roundtrip ( ptr, value) ;
595
+ prop_assert_eq ! ( out, value) ;
596
+ Ok ( ( ) )
597
+ } )
598
+ . unwrap ( ) ;
599
+ }
600
+
601
+ #[ test]
602
+ fn codegen_mem_store_load_i32 ( ) {
603
+ let roundtrip = roundtrip_store_t_load_t :: < i32 > ( Type :: I32 ) ;
604
+ TestRunner :: new ( Config :: with_cases ( 1024 ) )
605
+ . run ( & ( 0u32 ..MEMORY_SIZE_BYTES - 4 , any :: < i32 > ( ) ) , move |( ptr, value) | {
606
+ let out = roundtrip ( ptr, value) ;
607
+ prop_assert_eq ! ( out, value) ;
608
+ Ok ( ( ) )
609
+ } )
610
+ . unwrap ( ) ;
611
+ }
612
+
613
+ #[ test]
614
+ fn codegen_mem_store_load_u64 ( ) {
615
+ let roundtrip = roundtrip_store_t_load_t :: < u64 > ( Type :: U64 ) ;
616
+ TestRunner :: new ( Config :: with_cases ( 1024 ) )
617
+ . run ( & ( 0u32 ..MEMORY_SIZE_BYTES - 4 , any :: < u64 > ( ) ) , move |( ptr, value) | {
618
+ let out = roundtrip ( ptr, value) ;
619
+ prop_assert_eq ! ( out, value) ;
620
+ Ok ( ( ) )
621
+ } )
622
+ . unwrap ( ) ;
623
+ }
624
+
625
+ #[ test]
626
+ fn codegen_mem_store_load_i64 ( ) {
627
+ let roundtrip = roundtrip_store_t_load_t :: < i64 > ( Type :: I64 ) ;
628
+ TestRunner :: new ( Config :: with_cases ( 1024 ) )
629
+ . run ( & ( 0u32 ..MEMORY_SIZE_BYTES - 4 , any :: < i64 > ( ) ) , move |( ptr, value) | {
630
+ let out = roundtrip ( ptr, value) ;
631
+ prop_assert_eq ! ( out, value) ;
632
+ Ok ( ( ) )
633
+ } )
634
+ . unwrap ( ) ;
635
+ }
636
+
637
+ #[ test]
638
+ fn codegen_mem_store_load_u8 ( ) {
639
+ let roundtrip = roundtrip_store_t_load_t ( Type :: U8 ) ;
640
+ assert_eq ! ( roundtrip( 0 , 1 ) , 1 ) ;
641
+ // TestRunner::new(Config::with_cases(32))
642
+ // .run(&(0u32..MEMORY_SIZE_BYTES - 4, any::<u8>()), move |(ptr, value)| {
643
+ // let out = roundtrip(ptr, value);
644
+ // prop_assert_eq!(out, value);
645
+ // Ok(())
646
+ // })
647
+ // .unwrap();
648
+ }
649
+
650
+ // TODO: cover i8, u16, i16 cases
651
+
725
652
#[ allow( unused) ]
726
653
macro_rules! proptest_unary_numeric_op {
727
654
( $ty_name: ident :: $op: ident, $ty: ty => $ret: ty, $rust_op: ident) => {
@@ -965,6 +892,20 @@ impl ToCanonicalRepr for i128 {
965
892
}
966
893
}
967
894
895
+ impl ToCanonicalRepr for Felt {
896
+ fn ir_type ( ) -> Type {
897
+ Type :: Felt
898
+ }
899
+
900
+ fn canonicalize ( self ) -> SmallVec < [ Felt ; 4 ] > {
901
+ smallvec ! [ self ]
902
+ }
903
+
904
+ fn from_stack ( stack : & mut OperandStack < Felt > ) -> Self {
905
+ stack. pop ( ) . unwrap ( )
906
+ }
907
+ }
908
+
968
909
proptest ! {
969
910
#![ proptest_config( ProptestConfig { cases: 1000 , failure_persistence: None , ..Default :: default ( ) } ) ]
970
911
0 commit comments