Skip to content

Commit 12f3e7e

Browse files
authored
fix: to-bits and to-radix for > 128 bits (#1312)
* fix: to-bits and to-radix for > 128 bits * revert: use earlier overflow check that ensures unicity
1 parent e123aa7 commit 12f3e7e

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

crates/noirc_evaluator/src/ssa/optimizations.rs

+12-10
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::ssa::{
99
},
1010
};
1111
use acvm::FieldElement;
12-
use num_bigint::ToBigUint;
12+
use num_bigint::BigUint;
1313

1414
pub(super) fn simplify_id(ctx: &mut SsaContext, ins_id: NodeId) -> Result<(), RuntimeError> {
1515
let mut ins = ctx.instruction(ins_id).clone();
@@ -74,22 +74,24 @@ pub(super) fn simplify(ctx: &mut SsaContext, ins: &mut Instruction) -> Result<()
7474
fn evaluate_intrinsic(
7575
ctx: &mut SsaContext,
7676
op: builtin::Opcode,
77-
args: Vec<u128>,
77+
args: Vec<FieldElement>,
7878
res_type: &ObjectType,
7979
block_id: BlockId,
8080
) -> Result<Vec<NodeId>, RuntimeErrorKind> {
8181
match op {
8282
builtin::Opcode::ToBits(_) => {
83-
let bit_count = args[1] as u32;
83+
let bit_count = args[1].to_u128() as u32;
8484
let mut result = Vec::new();
85+
let mut bits = args[0].bits();
86+
bits.reverse();
8587

8688
if let ObjectType::ArrayPointer(a) = res_type {
8789
for i in 0..bit_count {
8890
let index = ctx.get_or_create_const(
8991
FieldElement::from(i as i128),
9092
ObjectType::native_field(),
9193
);
92-
let op = if args[0] & (1 << i) != 0 {
94+
let op = if i < bits.len() as u32 && bits[i as usize] {
9395
Operation::Store {
9496
array_id: *a,
9597
index,
@@ -116,9 +118,10 @@ fn evaluate_intrinsic(
116118
);
117119
}
118120
builtin::Opcode::ToRadix(endian) => {
119-
let mut element = args[0].to_biguint().unwrap().to_radix_le(args[1] as u32);
120-
let byte_count = args[2] as u32;
121-
let diff = if byte_count > element.len() as u32 {
121+
let mut element = BigUint::from_bytes_be(&args[0].to_be_bytes())
122+
.to_radix_le(args[1].to_u128() as u32);
123+
let byte_count = args[2].to_u128() as u32;
124+
let diff = if byte_count >= element.len() as u32 {
122125
byte_count - element.len() as u32
123126
} else {
124127
return Err(RuntimeErrorKind::ArrayOutOfBounds {
@@ -532,9 +535,8 @@ fn cse_block_with_anchor(
532535
// We do not simplify print statements
533536
builtin::Opcode::Println(_) => (),
534537
_ => {
535-
let args = args.iter().map(|arg| {
536-
NodeEval::from_id(ctx, *arg).into_const_value().map(|f| f.to_u128())
537-
});
538+
let args =
539+
args.iter().map(|arg| NodeEval::from_id(ctx, *arg).into_const_value());
538540

539541
if let Some(args) = args.collect() {
540542
update2.mark = Mark::Deleted;

0 commit comments

Comments
 (0)