Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

Commit 176d98f

Browse files
committed
test: add test for roundtripping signed ints.
1 parent 118e779 commit 176d98f

File tree

1 file changed

+64
-11
lines changed

1 file changed

+64
-11
lines changed

src/extension/conversions.rs

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ mod test {
401401
assert_eq!(val, exec_ctx.exec_hugr_u64(hugr, "main"));
402402
}
403403

404-
fn roundtrip_hugr(val: u64) -> Hugr {
404+
fn roundtrip_hugr(val: u64, signed: bool) -> Hugr {
405405
let int64 = INT_TYPES[6].clone();
406406
SimpleHugrConfig::new()
407407
.with_outs(USIZE_T)
@@ -412,14 +412,29 @@ mod test {
412412
.add_dataflow_op(ConvertOpDef::ifromusize.without_log_width(), [k])
413413
.unwrap()
414414
.outputs_arr();
415-
let [flt] = builder
416-
.add_dataflow_op(ConvertOpDef::convert_u.with_log_width(6), [int])
415+
let [flt] = {
416+
let op = if signed {
417+
ConvertOpDef::convert_s.with_log_width(6)
418+
} else {
419+
ConvertOpDef::convert_u.with_log_width(6)
420+
};
421+
builder
422+
.add_dataflow_op(op, [int])
417423
.unwrap()
418-
.outputs_arr();
419-
let [int_or_err] = builder
420-
.add_dataflow_op(ConvertOpDef::trunc_u.with_log_width(6), [flt])
424+
.outputs_arr()
425+
};
426+
427+
let [int_or_err] = {
428+
let op = if signed {
429+
ConvertOpDef::trunc_s.with_log_width(6)
430+
} else {
431+
ConvertOpDef::trunc_u.with_log_width(6)
432+
};
433+
builder
434+
.add_dataflow_op(op, [flt])
421435
.unwrap()
422-
.outputs_arr();
436+
.outputs_arr()
437+
};
423438
let sum_ty = sum_with_error(int64.clone());
424439
let variants = (0..sum_ty.num_variants())
425440
.map(|i| sum_ty.get_variant(i).unwrap().clone().try_into().unwrap());
@@ -467,9 +482,9 @@ mod test {
467482
#[case(4294967295)]
468483
#[case(42)]
469484
#[case(18_000_000_000_000_000_000)]
470-
fn roundtrip(mut exec_ctx: TestContext, #[case] val: u64) {
485+
fn roundtrip_signed(mut exec_ctx: TestContext, #[case] val: u64) {
471486
add_extensions(&mut exec_ctx);
472-
let hugr = roundtrip_hugr(val);
487+
let hugr = roundtrip_hugr(val, false);
473488
assert_eq!(val, exec_ctx.exec_hugr_u64(hugr, "main"));
474489
}
475490

@@ -493,13 +508,51 @@ mod test {
493508
fn approx_roundtrip_unsigned(mut exec_ctx: TestContext, #[case] val: u64) {
494509
add_extensions(&mut exec_ctx);
495510

496-
let hugr = roundtrip_hugr(val);
511+
let hugr = roundtrip_hugr(val, false);
497512
let result = exec_ctx.exec_hugr_u64(hugr, "main");
498513
let (v_r_max, v_r_min) = (val.max(result), val.min(result));
499-
// if val is too large ()
514+
// If val is too large the `trunc_u` op in `hugr` will return None.
515+
// In this case the hugr returns the magic number `999`.
500516
assert!(result == 999 || (v_r_max - v_r_min) < 1 << 10);
501517
}
502518

519+
#[rstest]
520+
#[case(i64::MAX)]
521+
#[case(i64::MAX - 1)] // 2 ^ 63
522+
#[case(i64::MAX - (1 << 1))] // 2 ^ 63
523+
#[case(i64::MAX - (1 << 2))] // 2 ^ 63
524+
#[case(i64::MAX - (1 << 3))] // 2 ^ 63
525+
#[case(i64::MAX - (1 << 4))] // 2 ^ 63
526+
#[case(i64::MAX - (1 << 5))] // 2 ^ 63
527+
#[case(i64::MAX - (1 << 6))] // 2 ^ 63
528+
#[case(i64::MAX - (1 << 7))] // 2 ^ 63
529+
#[case(i64::MAX - (1 << 8))] // 2 ^ 63
530+
#[case(i64::MAX - (1 << 9))] // 2 ^ 63
531+
#[case(i64::MAX - (1 << 10))] // 2 ^ 63
532+
#[case(i64::MAX - (1 << 11))] // 2 ^ 63
533+
#[case(i64::MIN)]
534+
#[case(i64::MIN + 1)] // 2 ^ 63
535+
#[case(i64::MIN + (1 << 1))] // 2 ^ 63
536+
#[case(i64::MIN + (1 << 2))] // 2 ^ 63
537+
#[case(i64::MIN + (1 << 3))] // 2 ^ 63
538+
#[case(i64::MIN + (1 << 4))] // 2 ^ 63
539+
#[case(i64::MIN + (1 << 5))] // 2 ^ 63
540+
#[case(i64::MIN + (1 << 6))] // 2 ^ 63
541+
#[case(i64::MIN + (1 << 7))] // 2 ^ 63
542+
#[case(i64::MIN + (1 << 8))] // 2 ^ 63
543+
#[case(i64::MIN + (1 << 9))] // 2 ^ 63
544+
#[case(i64::MIN + (1 << 10))] // 2 ^ 63
545+
#[case(i64::MIN + (1 << 11))] // 2 ^ 63
546+
fn approx_roundtrip_signed(mut exec_ctx: TestContext, #[case] val: i64) {
547+
add_extensions(&mut exec_ctx);
548+
549+
let hugr = roundtrip_hugr(val as u64, true);
550+
let result = exec_ctx.exec_hugr_u64(hugr, "main") as i64;
551+
// If val.abs() is too large the `trunc_s` op in `hugr` will return None.
552+
// In this case the hugr returns the magic number `999`.
553+
assert!(result == 999 || (val - result).abs() < 1 << 10);
554+
}
555+
503556
#[rstest]
504557
fn itobool_cond(mut exec_ctx: TestContext, #[values(0, 1)] i: u64) {
505558
use hugr::type_row;

0 commit comments

Comments
 (0)