Skip to content

Commit b657b07

Browse files
authored
fix: pass Field to ToBits intrinsic in remove_bit_shifts optimization (#8493)
1 parent 9c53936 commit b657b07

7 files changed

+421
-131
lines changed

compiler/noirc_evaluator/src/ssa/opt/remove_bit_shifts.rs

Lines changed: 106 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,10 @@ impl Context<'_, '_, '_> {
234234
if let Type::Numeric(NumericType::Unsigned { bit_size }) = typ {
235235
let to_bits = self.context.dfg.import_intrinsic(Intrinsic::ToBits(Endian::Little));
236236
let result_types = vec![Type::Array(Arc::new(vec![Type::bool()]), bit_size)];
237-
let rhs_bits = self.insert_call(to_bits, vec![rhs], result_types);
237+
238+
// A call to ToBits can only be done with a field argument (rhs is always u8 here)
239+
let rhs_as_field = self.insert_cast(rhs, NumericType::NativeField);
240+
let rhs_bits = self.insert_call(to_bits, vec![rhs_as_field], result_types);
238241

239242
let rhs_bits = rhs_bits[0];
240243
let one = self.field_constant(FieldElement::one());
@@ -349,7 +352,7 @@ mod tests {
349352
use crate::{assert_ssa_snapshot, ssa::ssa_gen::Ssa};
350353

351354
#[test]
352-
fn removes_shl() {
355+
fn removes_shl_with_constant_rhs() {
353356
let src = "
354357
acir(inline) fn main f0 {
355358
b0(v0: u32):
@@ -372,4 +375,105 @@ mod tests {
372375
}
373376
");
374377
}
378+
379+
#[test]
380+
fn removes_shl_with_non_constant_rhs() {
381+
let src = "
382+
acir(inline) fn main f0 {
383+
b0(v0: u32, v1: u8):
384+
v2 = shl v0, v1
385+
v3 = truncate v2 to 32 bits, max_bit_size: 33
386+
return v2
387+
}
388+
";
389+
let ssa = Ssa::from_str(src).unwrap();
390+
let ssa = ssa.remove_bit_shifts();
391+
assert_ssa_snapshot!(ssa, @r"
392+
acir(inline) fn main f0 {
393+
b0(v0: u32, v1: u8):
394+
v3 = lt v1, u8 32
395+
v4 = cast v3 as u32
396+
v5 = cast v1 as Field
397+
v7 = call to_le_bits(v5) -> [u1; 8]
398+
v9 = array_get v7, index Field 7 -> u1
399+
v10 = not v9
400+
v11 = cast v9 as Field
401+
v12 = cast v10 as Field
402+
v14 = mul Field 2, v11
403+
v15 = add v12, v14
404+
v17 = array_get v7, index Field 6 -> u1
405+
v18 = not v17
406+
v19 = cast v17 as Field
407+
v20 = cast v18 as Field
408+
v21 = mul v15, v15
409+
v22 = mul v21, v20
410+
v23 = mul v21, Field 2
411+
v24 = mul v23, v19
412+
v25 = add v22, v24
413+
v27 = array_get v7, index Field 5 -> u1
414+
v28 = not v27
415+
v29 = cast v27 as Field
416+
v30 = cast v28 as Field
417+
v31 = mul v25, v25
418+
v32 = mul v31, v30
419+
v33 = mul v31, Field 2
420+
v34 = mul v33, v29
421+
v35 = add v32, v34
422+
v37 = array_get v7, index Field 4 -> u1
423+
v38 = not v37
424+
v39 = cast v37 as Field
425+
v40 = cast v38 as Field
426+
v41 = mul v35, v35
427+
v42 = mul v41, v40
428+
v43 = mul v41, Field 2
429+
v44 = mul v43, v39
430+
v45 = add v42, v44
431+
v47 = array_get v7, index Field 3 -> u1
432+
v48 = not v47
433+
v49 = cast v47 as Field
434+
v50 = cast v48 as Field
435+
v51 = mul v45, v45
436+
v52 = mul v51, v50
437+
v53 = mul v51, Field 2
438+
v54 = mul v53, v49
439+
v55 = add v52, v54
440+
v56 = array_get v7, index Field 2 -> u1
441+
v57 = not v56
442+
v58 = cast v56 as Field
443+
v59 = cast v57 as Field
444+
v60 = mul v55, v55
445+
v61 = mul v60, v59
446+
v62 = mul v60, Field 2
447+
v63 = mul v62, v58
448+
v64 = add v61, v63
449+
v66 = array_get v7, index Field 1 -> u1
450+
v67 = not v66
451+
v68 = cast v66 as Field
452+
v69 = cast v67 as Field
453+
v70 = mul v64, v64
454+
v71 = mul v70, v69
455+
v72 = mul v70, Field 2
456+
v73 = mul v72, v68
457+
v74 = add v71, v73
458+
v76 = array_get v7, index Field 0 -> u1
459+
v77 = not v76
460+
v78 = cast v76 as Field
461+
v79 = cast v77 as Field
462+
v80 = mul v74, v74
463+
v81 = mul v80, v79
464+
v82 = mul v80, Field 2
465+
v83 = mul v82, v78
466+
v84 = add v81, v83
467+
v85 = cast v84 as u32
468+
v86 = unchecked_mul v4, v85
469+
v87 = cast v0 as Field
470+
v88 = cast v86 as Field
471+
v89 = mul v87, v88
472+
v90 = truncate v89 to 32 bits, max_bit_size: 254
473+
v91 = cast v90 as u32
474+
v92 = truncate v91 to 32 bits, max_bit_size: 33
475+
return v91
476+
}
477+
");
478+
}
375479
}

tooling/nargo_cli/tests/snapshots/execution_success/binary_operator_overloading/execute__tests__force_brillig_false_inliner_-9223372036854775808.snap

Lines changed: 63 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tooling/nargo_cli/tests/snapshots/execution_success/binary_operator_overloading/execute__tests__force_brillig_false_inliner_0.snap

Lines changed: 63 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tooling/nargo_cli/tests/snapshots/execution_success/binary_operator_overloading/execute__tests__force_brillig_false_inliner_9223372036854775807.snap

Lines changed: 63 additions & 32 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tooling/nargo_cli/tests/snapshots/execution_success/u16_support/execute__tests__force_brillig_false_inliner_-9223372036854775808.snap

Lines changed: 42 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)