Skip to content

Commit a8ddadc

Browse files
Fix range check increments for downcast (#1316)
* fix range check increments for downcast * add missing increment case * fix comments * fix comments * update docs * fix typo
1 parent 4e2c9ef commit a8ddadc

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

src/libfuncs/cast.rs

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)