@@ -372,7 +372,7 @@ fn build_mul<'ctx, 'this>(
372372 let res_value = entry. muli ( lhs_value, rhs_value, location) ?;
373373
374374 // Offset and truncate the result to the output type.
375- let res_offset = ( & dst_range. lower ) . max ( & compute_range . lower ) . clone ( ) ;
375+ let res_offset = dst_range. lower . clone ( ) ;
376376 let res_value = if res_offset != BigInt :: ZERO {
377377 let res_offset = entry. const_int_from_type ( context, location, res_offset, compute_ty) ?;
378378 entry. append_op_result ( arith:: subi ( res_value, res_offset, location) ) ?
@@ -838,6 +838,132 @@ mod test {
838838 Value ,
839839 } ;
840840
841+ lazy_static ! {
842+ static ref TEST_MUL_PROGRAM : ( String , Program ) = load_cairo! {
843+ #[ feature( "bounded-int-utils" ) ]
844+ use core:: internal:: bounded_int:: { self , BoundedInt , MulHelper , mul, UnitInt } ;
845+
846+ impl MulHelperBI_m128x127_BI_m128x127 of MulHelper <BoundedInt <-128 , 127 >, BoundedInt <-128 , 127 >> {
847+ type Result = BoundedInt <-16256 , 16384 >;
848+ }
849+
850+ impl MulHelperBI_0x128_BI_0x128 of MulHelper <BoundedInt <0 , 128 >, BoundedInt <0 , 128 >> {
851+ type Result = BoundedInt <0 , 16384 >;
852+ }
853+
854+ impl MulHelperBI_1x31_BI_1x1 of MulHelper <BoundedInt <1 , 31 >, BoundedInt <1 , 1 >> {
855+ type Result = BoundedInt <1 , 31 >;
856+ }
857+
858+ impl MulHelperBI_m1x31_BI_m1xm1 of MulHelper <BoundedInt <-1 , 31 >, BoundedInt <-1 , -1 >> {
859+ type Result = BoundedInt <-31 , 1 >;
860+ }
861+
862+ impl MulHelperBI_31x31_BI_1x1 of MulHelper <BoundedInt <31 , 31 >, BoundedInt <1 , 1 >> {
863+ type Result = BoundedInt <31 , 31 >;
864+ }
865+
866+ impl MulHelperBI_m10x0_BI_0x100 of MulHelper <BoundedInt <-100 , 0 >, BoundedInt <0 , 100 >> {
867+ type Result = BoundedInt <-10000 , 0 >;
868+ }
869+
870+ impl MulHelperBI_1x1_BI_1x1 of MulHelper <BoundedInt <1 , 1 >, BoundedInt <1 , 1 >> {
871+ type Result = BoundedInt <1 , 1 >;
872+ }
873+
874+ impl MulHelperBI_m5x5_UI_2 of MulHelper <BoundedInt <-5 , 5 >, UnitInt <2 >> {
875+ type Result = BoundedInt <-10 , 10 >;
876+ }
877+
878+ fn bi_m128x127_times_bi_m128x127( a: felt252, b: felt252) -> BoundedInt <-16256 , 16384 > {
879+ let a: BoundedInt <-128 , 127 > = a. try_into( ) . unwrap( ) ;
880+ let b: BoundedInt <-128 , 127 > = b. try_into( ) . unwrap( ) ;
881+
882+ mul( a, b)
883+ }
884+
885+ fn bi_0x128_times_bi_0x128( a: felt252, b: felt252) -> BoundedInt <0 , 16384 > {
886+ let a: BoundedInt <0 , 128 > = a. try_into( ) . unwrap( ) ;
887+ let b: BoundedInt <0 , 128 > = b. try_into( ) . unwrap( ) ;
888+
889+ mul( a, b)
890+ }
891+
892+ fn bi_1x31_times_bi_1x1( a: felt252, b: felt252) -> BoundedInt <1 , 31 > {
893+ let a: BoundedInt <1 , 31 > = a. try_into( ) . unwrap( ) ;
894+ let b: BoundedInt <1 , 1 > = b. try_into( ) . unwrap( ) ;
895+
896+ mul( a, b)
897+ }
898+
899+ fn bi_m1x31_times_bi_m1xm1( a: felt252, b: felt252) -> BoundedInt <-31 , 1 > {
900+ let a: BoundedInt <-1 , 31 > = a. try_into( ) . unwrap( ) ;
901+ let b: BoundedInt <-1 , -1 > = b. try_into( ) . unwrap( ) ;
902+
903+ mul( a, b)
904+ }
905+
906+ fn bi_31x31_times_bi_1x1( a: felt252, b: felt252) -> BoundedInt <31 , 31 > {
907+ let a: BoundedInt <31 , 31 > = a. try_into( ) . unwrap( ) ;
908+ let b: BoundedInt <1 , 1 > = b. try_into( ) . unwrap( ) ;
909+
910+ mul( a, b)
911+ }
912+
913+ fn bi_m100x0_times_bi_0x100( a: felt252, b: felt252) -> BoundedInt <-10000 , 0 > {
914+ let a: BoundedInt <-100 , 0 > = a. try_into( ) . unwrap( ) ;
915+ let b: BoundedInt <0 , 100 > = b. try_into( ) . unwrap( ) ;
916+
917+ mul( a, b)
918+ }
919+
920+ fn bi_1x1_times_bi_1x1( a: felt252, b: felt252) -> BoundedInt <1 , 1 > {
921+ let a: BoundedInt <1 , 1 > = a. try_into( ) . unwrap( ) ;
922+ let b: BoundedInt <1 , 1 > = b. try_into( ) . unwrap( ) ;
923+
924+ mul( a, b)
925+ }
926+
927+ fn bi_m5x5_times_ui_2( a: felt252, b: felt252) -> BoundedInt <-10 , 10 > {
928+ let a: BoundedInt <-5 , 5 > = a. try_into( ) . unwrap( ) ;
929+ let b: UnitInt <2 > = b. try_into( ) . unwrap( ) ;
930+
931+ mul( a, b)
932+ }
933+ } ;
934+ }
935+
936+ #[ test_case( "bi_m128x127_times_bi_m128x127" , -128 , -128 , 16384 ) ]
937+ #[ test_case( "bi_0x128_times_bi_0x128" , 126 , 128 , 16128 ) ]
938+ #[ test_case( "bi_1x31_times_bi_1x1" , 31 , 1 , 31 ) ]
939+ #[ test_case( "bi_m1x31_times_bi_m1xm1" , 31 , -1 , -31 ) ]
940+ #[ test_case( "bi_31x31_times_bi_1x1" , 31 , 1 , 31 ) ]
941+ #[ test_case( "bi_m100x0_times_bi_0x100" , -100 , 100 , -10000 ) ]
942+ #[ test_case( "bi_1x1_times_bi_1x1" , 1 , 1 , 1 ) ]
943+ #[ test_case( "bi_m5x5_times_ui_2" , -3 , 2 , -6 ) ]
944+ fn test_mul ( entry_point : & str , lhs : i32 , rhs : i32 , expected_result : i32 ) {
945+ let result = run_program (
946+ & TEST_MUL_PROGRAM ,
947+ entry_point,
948+ & [
949+ Value :: Felt252 ( Felt252 :: from ( lhs) ) ,
950+ Value :: Felt252 ( Felt252 :: from ( rhs) ) ,
951+ ] ,
952+ )
953+ . return_value ;
954+ if let Value :: Enum { value, .. } = result {
955+ if let Value :: Struct { fields, .. } = * value {
956+ assert ! (
957+ matches!( fields[ 0 ] , Value :: BoundedInt { value, .. } if value == Felt252 :: from( expected_result) )
958+ )
959+ } else {
960+ panic ! ( "Test returned an unexpected value" ) ;
961+ }
962+ } else {
963+ panic ! ( "Test didn't return an enum as expected" ) ;
964+ }
965+ }
966+
841967 lazy_static ! {
842968 static ref TEST_TRIM_PROGRAM : ( String , Program ) = load_cairo! {
843969 #[ feature( "bounded-int-utils" ) ]
0 commit comments