Skip to content

Commit

Permalink
remove trim libfunc
Browse files Browse the repository at this point in the history
  • Loading branch information
FrancoGiachetta committed Dec 27, 2024
1 parent 0e4b9bf commit 48922df
Showing 1 changed file with 2 additions and 150 deletions.
152 changes: 2 additions & 150 deletions src/libfuncs/bounded_int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use cairo_lang_sierra::{
extensions::{
bounded_int::{
BoundedIntConcreteLibfunc, BoundedIntConstrainConcreteLibfunc,
BoundedIntDivRemConcreteLibfunc, BoundedIntTrimConcreteLibfunc,
BoundedIntDivRemConcreteLibfunc,
},
core::{CoreLibfunc, CoreType},
lib_func::SignatureOnlyConcreteLibfunc,
Expand Down Expand Up @@ -57,9 +57,7 @@ pub fn build<'ctx, 'this>(
BoundedIntConcreteLibfunc::Constrain(info) => {
build_constrain(context, registry, entry, location, helper, metadata, info)
}
BoundedIntConcreteLibfunc::Trim(info) => {
build_trim(context, registry, entry, location, helper, metadata, info)
}
BoundedIntConcreteLibfunc::Trim(_) => todo!("implement trim libfunc"),
BoundedIntConcreteLibfunc::IsZero(info) => {
build_is_zero(context, registry, entry, location, helper, metadata, info)
}
Expand Down Expand Up @@ -702,49 +700,6 @@ fn build_constrain<'ctx, 'this>(
Ok(())
}

/// Makes a downcast of a type `T` to `BoundedInt<T::MIN, T::MAX - 1>`
/// or `BoundedInt<T::MIN + 1, T::MAX>` where `T` can be any type of signed
/// or unsigned integer.
///
/// ```cairo
/// extern fn bounded_int_trim<T, const TRIMMED_VALUE: felt252, impl H: TrimHelper<T, TRIMMED_VALUE>>(
/// value: T,
/// ) -> core::internal::OptionRev<H::Target> nopanic;
/// ```
fn build_trim<'ctx, 'this>(
context: &'ctx Context,
_registry: &ProgramRegistry<CoreType, CoreLibfunc>,
entry: &'this Block<'ctx>,
location: Location<'ctx>,
helper: &LibfuncHelper<'ctx, 'this>,
_metadata: &mut MetadataStorage,
info: &BoundedIntTrimConcreteLibfunc,
) -> Result<()> {
let value: Value = entry.arg(0)?;
let trimmed_value = entry.const_int_from_type(
context,
location,
info.trimmed_value.clone(),
value.r#type(),
)?;

let is_invalid = entry.cmpi(context, CmpiPredicate::Eq, value, trimmed_value, location)?;

// There is no need to truncate the value type since we're only receiving power-of-two integers
// and constraining their range a single value from either the lower or upper limit. However,
// since we're returning a `BoundedInt` we need to offset its internal representation
// accordingly.
let value = if info.trimmed_value == BigInt::ZERO {
let k1 = entry.const_int_from_type(context, location, 1, value.r#type())?;
entry.append_op_result(arith::subi(value, k1, location))?
} else {
value
};

entry.append_operation(helper.cond_br(context, is_invalid, [0, 1], [&[], &[value]], location));
Ok(())
}

/// Generate MLIR operations for the `bounded_int_is_zero` libfunc.
fn build_is_zero<'ctx, 'this>(
context: &'ctx Context,
Expand Down Expand Up @@ -807,106 +762,3 @@ fn build_wrap_non_zero<'ctx, 'this>(
&info.signature.param_signatures,
)
}

#[cfg(test)]
mod test {
use cairo_vm::Felt252;

use crate::{
context::NativeContext, execution_result::ExecutionResult, executor::JitNativeExecutor,
utils::test::load_cairo, OptLevel, Value,
};

#[test]
fn test_trim_some_u8() {
let (_, program) = load_cairo!(
use core::internal::{OptionRev, bounded_int::BoundedInt};
use core::internal::bounded_int;
fn main() -> BoundedInt<1, 255> {
let num = match bounded_int::trim::<u8, 0>(1) {
OptionRev::Some(n) => n,
OptionRev::None => 1,
};

num
}
);
let ctx = NativeContext::new();
let module = ctx.compile(&program, false, None).unwrap();
let executor = JitNativeExecutor::from_native_module(module, OptLevel::Default).unwrap();
let ExecutionResult {
remaining_gas: _,
return_value,
builtin_stats: _,
} = executor
.invoke_dynamic(&program.funcs[0].id, &[], None)
.unwrap();

let Value::BoundedInt { value, range: _ } = return_value else {
panic!();
};
assert_eq!(value, Felt252::from(1_u8));
}

#[test]
fn test_trim_some_u32() {
let (_, program) = load_cairo!(
use core::internal::{OptionRev, bounded_int::BoundedInt};
use core::internal::bounded_int;
fn main() -> BoundedInt<0, 4294967294> {
let num = match bounded_int::trim::<u32, 0xffffffff>(0xfffffffe) {
OptionRev::Some(n) => n,
OptionRev::None => 0,
};

num
}
);
let ctx = NativeContext::new();
let module = ctx.compile(&program, false, None).unwrap();
let executor = JitNativeExecutor::from_native_module(module, OptLevel::Default).unwrap();
let ExecutionResult {
remaining_gas: _,
return_value,
builtin_stats: _,
} = executor
.invoke_dynamic(&program.funcs[0].id, &[], None)
.unwrap();

let Value::BoundedInt { value, range: _ } = return_value else {
panic!();
};
assert_eq!(value, Felt252::from(0xfffffffe_u32));
}

#[test]
fn test_trim_none() {
let (_, program) = load_cairo!(
use core::internal::{OptionRev, bounded_int::BoundedInt};
use core::internal::bounded_int;
fn main() -> BoundedInt<-32767, 32767> {
let num = match bounded_int::trim::<i16, -0x8000>(-0x8000) {
OptionRev::Some(n) => n,
OptionRev::None => 0,
};

num
}
);
let ctx = NativeContext::new();
let module = ctx.compile(&program, false, None).unwrap();
let executor = JitNativeExecutor::from_native_module(module, OptLevel::Default).unwrap();
let ExecutionResult {
remaining_gas: _,
return_value,
builtin_stats: _,
} = executor
.invoke_dynamic(&program.funcs[0].id, &[], None)
.unwrap();

let Value::BoundedInt { value, range: _ } = return_value else {
panic!();
};
assert_eq!(value, Felt252::from(0));
}
}

0 comments on commit 48922df

Please sign in to comment.