@@ -55,7 +55,7 @@ pub fn build_downcast<'ctx, 'this>(
5555 _metadata : & mut MetadataStorage ,
5656 info : & DowncastConcreteLibfunc ,
5757) -> Result < ( ) > {
58- let range_check = super :: increment_builtin_counter ( context , entry, location , entry . arg ( 0 ) ? ) ?;
58+ let range_check = entry. arg ( 0 ) ?;
5959 let src_value: Value = entry. arg ( 1 ) ?;
6060
6161 if info. signature . param_signatures [ 1 ] . ty == info. signature . branch_signatures [ 0 ] . vars [ 1 ] . ty {
@@ -247,6 +247,52 @@ pub fn build_downcast<'ctx, 'this>(
247247 }
248248 } ;
249249
250+ // Incrementing the range check depends on whether the source range can hold a felt252 or not
251+ let range_check = if info. from_range . is_full_felt252_range ( ) {
252+ let rc_size = BigInt :: from ( 1 ) << 128 ;
253+ // If the range can contain a felt252, how the range check is increased depends on whether the value is in bounds or not:
254+ // * If it is in bounds, we check whether the destination range size is less than range check size. If it is, increment
255+ // the range check builtin by 2. Otherwise, increment it by 1.
256+ // https://github.com/starkware-libs/cairo/blob/v2.12.0-dev.1/crates/cairo-lang-sierra-to-casm/src/invocations/range_reduction.rs#L87
257+ // * If it is not in bounds, increment the range check builtin by 3.
258+ // https://github.com/starkware-libs/cairo/blob/v2.12.0-dev.1/crates/cairo-lang-sierra-to-casm/src/invocations/range_reduction.rs#L79
259+ super :: increment_builtin_counter_by_if (
260+ context,
261+ entry,
262+ location,
263+ range_check,
264+ if dst_range. size ( ) < rc_size { 2 } else { 1 } ,
265+ 3 ,
266+ is_in_bounds,
267+ ) ?
268+ } else {
269+ match ( lower_check, upper_check) {
270+ ( Some ( _) , None ) | ( None , Some ( _) ) => {
271+ // If either the lower or the upper bound was checked, increment the range check builtin by 1.
272+ // * In case the lower bound was checked: https://github.com/starkware-libs/cairo/blob/v2.12.0-dev.1/crates/cairo-lang-sierra-to-casm/src/invocations/casts.rs#L135
273+ // * In case the upper bound was checked: https://github.com/starkware-libs/cairo/blob/v2.12.0-dev.1/crates/cairo-lang-sierra-to-casm/src/invocations/casts.rs#L111
274+ super :: increment_builtin_counter_by ( context, entry, location, range_check, 1 ) ?
275+ }
276+ ( Some ( lower_check) , Some ( upper_check) ) => {
277+ let is_in_range =
278+ entry. append_op_result ( arith:: andi ( lower_check, upper_check, location) ) ?;
279+
280+ // If the result is in range, increment the range check builtin by 2. Otherwise, increment it by 1.
281+ // https://github.com/starkware-libs/cairo/blob/v2.12.0-dev.1/crates/cairo-lang-sierra-to-casm/src/invocations/casts.rs#L160
282+ super :: increment_builtin_counter_by_if (
283+ context,
284+ entry,
285+ location,
286+ range_check,
287+ 2 ,
288+ 1 ,
289+ is_in_range,
290+ ) ?
291+ }
292+ ( None , None ) => range_check,
293+ }
294+ } ;
295+
250296 let dst_value = if dst_ty. is_bounded_int ( registry) ? && dst_range. lower != BigInt :: ZERO {
251297 let dst_offset = entry. const_int_from_type (
252298 context,
@@ -268,6 +314,7 @@ pub fn build_downcast<'ctx, 'this>(
268314 } else {
269315 dst_value
270316 } ;
317+
271318 helper. cond_br (
272319 context,
273320 entry,
0 commit comments