diff --git a/kmir/src/kmir/kdist/mir-semantics/kmir.md b/kmir/src/kmir/kdist/mir-semantics/kmir.md index dffd6372e..2597c5705 100644 --- a/kmir/src/kmir/kdist/mir-semantics/kmir.md +++ b/kmir/src/kmir/kdist/mir-semantics/kmir.md @@ -5,6 +5,7 @@ requires "kmir-ast.md" requires "rt/data.md" requires "rt/configuration.md" requires "lemmas/kmir-lemmas.md" +requires "lemmas/bitwise-lemmas.md" requires "cheatcodes.md" requires "intrinsics.md" ``` @@ -730,7 +731,7 @@ endmodule ## Top-level Module -The top-level module `KMIR` includes both the control flow constructs (and transitively all modules related to runtime operations and AST) and a collection of simplification lemmas required for symbolic execution of MIR programs. +The top-level module `KMIR` includes both the control flow constructs (and transitively all modules related to runtime operations and AST) and collections of simplification lemmas required for symbolic execution of MIR programs. ```k module KMIR @@ -739,4 +740,5 @@ module KMIR imports KMIR-CHEATCODES imports KMIR-INTRINSICS imports KMIR-LEMMAS + imports KMIR-BITWISE-LEMMAS endmodule diff --git a/kmir/src/kmir/kdist/mir-semantics/lemmas/bitwise-lemmas.md b/kmir/src/kmir/kdist/mir-semantics/lemmas/bitwise-lemmas.md new file mode 100644 index 000000000..87708b473 --- /dev/null +++ b/kmir/src/kmir/kdist/mir-semantics/lemmas/bitwise-lemmas.md @@ -0,0 +1,147 @@ +# Bitwise lemmas for MIR symbolic execution + +This file contains lemmas that rewrite bitwise operations on integers into arithmetic, and that bound the results of +bitwise operations. They are imported into the `KMIR` module alongside the lemmas in `kmir-lemmas.md`. + +```k +module KMIR-BITWISE-LEMMAS + imports INT + imports INT-SYMBOLIC + imports BOOL +``` + +The SMT solver treats `&Int`, `|Int`, `>>Int` and `< X modInt (M +Int 1) + requires 0 <=Int M andBool M &Int (M +Int 1) ==Int 0 + [simplification(60), preserves-definedness, concrete(M)] + + rule [bitwise-low-mask-comm]: + M &Int X => X modInt (M +Int 1) + requires 0 <=Int M andBool M &Int (M +Int 1) ==Int 0 + [simplification(60), preserves-definedness, concrete(M)] +``` + +An arithmetic right shift is floor division by `2^N`, which for `X >= 0` is truncating division (`/Int`). For negative +`X` it equals Euclidean division (`divInt`) instead, but the rule is restricted to nonnegative values for simplicity. + +```k + rule [bitwise-shr]: + X >>Int N => X /Int (2 ^Int N) + requires 0 <=Int N andBool 0 <=Int X + [simplification(60), preserves-definedness, concrete(N)] +``` + +Repeated shifts give nested divisions, each of which the solver sees as a nested if-then-else; they are collapsed into +one. Truncating division by a positive `A`, then by a positive `B`, equals truncating division by `A * B`, for either +sign of `X`. + +```k + rule [bitwise-div-div]: + (X /Int A) /Int B => X /Int (A *Int B) + requires 0 X *Int (2 ^Int N) + requires 0 <=Int N andBool 0 <=Int X + [simplification(60), preserves-definedness, concrete(N)] +``` + +With the rules above, the bytes of a nonnegative number `X` become `(X /Int 256^k) modInt 256` instead of +`(X >>Int 8 ... >>Int 8) &Int 255`, so the round-trip simplifications in `kmir-lemmas.md` no longer apply when the bytes are +put back together. The following simplifications put them back together instead, from the most significant byte. +Note that the second rule follows directly from the definition of integer division, and is equivalent to the first rule with +`A ==Int 1`. + +```k + rule [bitwise-digits]: + (X /Int A) modInt N +Int N *Int (X /Int B) => X /Int A + requires 0 <=Int X andBool 0 X + requires 0 <=Int X andBool 0 (C &Int X) modInt (2 ^Int (log2Int(C) +Int 1)) + requires 0 true + requires 0 <=Int X + [simplification] + + rule [bitwise-and-lower-ge]: + X &Int _Y >=Int 0 => true + requires 0 <=Int X + [simplification] + + rule [bitwise-and-upper]: + X &Int _Y <=Int X => true + requires 0 <=Int X + [simplification] + + rule [bitwise-and-upper-ge]: + X >=Int X &Int _Y => true + requires 0 <=Int X + [simplification] + + rule [bitwise-or-lower]: + 0 <=Int X |Int Y => true + requires 0 <=Int X andBool 0 <=Int Y + [simplification] + + rule [bitwise-or-upper]: + X |Int Y true + requires 0 true + requires 0 <=Int C + andBool 0 <=Int X andBool X = 0 { + assert_eq!(m, x % 256); + } else { + let r = x % 256; + assert_eq!(m, if r == 0 { 0 } else { r + 256 }); + } +} + +/// A low mask is the same with the mask on either side. +#[no_mangle] +pub fn mask_comm(x: i64) { + assert_eq!(0xFF & x, x & 0xFF); +} + +/// A right shift is a division. +#[no_mangle] +pub fn shr_is_div(x: u64) { + assert_eq!(x >> 8, x / 256); +} + +/// Repeated right shifts are a single division. +#[no_mangle] +pub fn shr_shr_is_div(x: u64) { + assert_eq!((x >> 1) >> 2, x / 8); +} + +/// A left shift that does not overflow is a multiplication. `<<` drops the bits shifted out but `*` checks for overflow, +/// so the value is widened first. +#[no_mangle] +pub fn shl_is_mul(x: u32) { + let y = x as u64; + assert_eq!(y << 3, y * 8); +} + +/// The first step of a parallel bit count: masking with 0x5555_5555 bounds both halves below 2^31, so their sum +/// cannot overflow. +#[no_mangle] +pub fn masked_sum_no_overflow(x: u32) -> u32 { + (x & 0x5555_5555) + ((x >> 1) & 0x5555_5555) +} + +/// The bitwise and with a nonnegative value lies between zero and that value. +#[no_mangle] +pub fn and_nonneg_bounds(x: i64, y: i64) { + if x >= 0 { + assert!(0 <= x & y); + assert!(x & y >= 0); + assert!(x & y <= x); + assert!(x >= x & y); + } +} + +/// The bitwise or of two nonnegative values is nonnegative. +#[no_mangle] +pub fn or_nonneg(x: i64, y: i64) { + if x >= 0 && y >= 0 { + assert!(0 <= x | y); + } +} + +/// The bitwise or of two bytes is a byte. +#[no_mangle] +pub fn or_bytes_fit(a: u8, b: u8) { + let (a, b) = (a as u16, b as u16); + assert!(a | b < 256); +} + +/// The bitwise or of two bytes is at most the largest byte. +#[no_mangle] +pub fn or_bytes_fit_le(a: u8, b: u8) { + let (a, b) = (a as u16, b as u16); + assert!(a | b <= 255); +} + +/// A round trip through the native-endian bytes is a cast. Not a test of the bitwise lemmas, but of their interaction +/// with the existing round-trip lemmas. +#[no_mangle] +pub fn ne_bytes_roundtrip(x: i64) { + assert_eq!(u64::from_ne_bytes(x.to_ne_bytes()), x as u64); +} + +fn main() { + mask_is_rem(-0x1234); + mask_comm(-0x1234); + shr_is_div(0x1234); + shr_shr_is_div(0x1234); + shl_is_mul(0x1234); + masked_sum_no_overflow(0xFFFF_FFFF); + and_nonneg_bounds(6, -3); + or_nonneg(6, 3); + or_bytes_fit(0x0F, 0xF0); + or_bytes_fit_le(0x0F, 0xF0); + ne_bytes_roundtrip(-2); +} diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u128.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u128.expected index 572968652..bd93ad2ca 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u128.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u128.expected @@ -12,7 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int +Int ARG_UINT2:Int &Int 34028236692093846346337460743176 +┃ │ Integer ( ARG_UINT1:Int +Int ARG_UINT2:Int , 128 , false ) +~> #freezer#setLocalV ┃ │ span: 332 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u16.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u16.expected index c53f171f6..d266fe052 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u16.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u16.expected @@ -12,8 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int +Int ARG_UINT2:Int &Int 65535 , 16 , false ) -~> #freezer +┃ │ Integer ( ARG_UINT1:Int +Int ARG_UINT2:Int , 16 , false ) +~> #freezer#setLocalVa ┃ │ span: 208 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u32.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u32.expected index 8f57a76ea..bd517538c 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u32.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u32.expected @@ -12,8 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int +Int ARG_UINT2:Int &Int 4294967295 , 32 , false ) -~> #fr +┃ │ Integer ( ARG_UINT1:Int +Int ARG_UINT2:Int , 32 , false ) +~> #freezer#setLocalVa ┃ │ span: 239 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u64.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u64.expected index 22da7fec2..a84bce043 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u64.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u64.expected @@ -12,7 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int +Int ARG_UINT2:Int &Int 18446744073709551615 , 64 , fals +┃ │ Integer ( ARG_UINT1:Int +Int ARG_UINT2:Int , 64 , false ) +~> #freezer#setLocalVa ┃ │ span: 270 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u8.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u8.expected index e7cd93750..8fa609cca 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u8.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_add-fail.unchecked_add_u8.expected @@ -12,8 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int +Int ARG_UINT2:Int &Int 255 , 8 , false ) -~> #freezer#se +┃ │ Integer ( ARG_UINT1:Int +Int ARG_UINT2:Int , 8 , false ) +~> #freezer#setLocalVal ┃ │ span: 84 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u128.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u128.expected index 69ea3f3a6..90b8a3240 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u128.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u128.expected @@ -12,7 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int *Int ARG_UINT2:Int &Int 34028236692093846346337460743176 +┃ │ Integer ( ARG_UINT1:Int *Int ARG_UINT2:Int , 128 , false ) +~> #freezer#setLocalV ┃ │ span: 332 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u16.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u16.expected index 2e2d9c588..e080d4ad0 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u16.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u16.expected @@ -12,8 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int *Int ARG_UINT2:Int &Int 65535 , 16 , false ) -~> #freezer +┃ │ Integer ( ARG_UINT1:Int *Int ARG_UINT2:Int , 16 , false ) +~> #freezer#setLocalVa ┃ │ span: 208 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u32.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u32.expected index 3789d378d..9f7f662c5 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u32.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u32.expected @@ -12,8 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int *Int ARG_UINT2:Int &Int 4294967295 , 32 , false ) -~> #fr +┃ │ Integer ( ARG_UINT1:Int *Int ARG_UINT2:Int , 32 , false ) +~> #freezer#setLocalVa ┃ │ span: 239 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u64.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u64.expected index f8a5f84db..a6dcd24cd 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u64.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u64.expected @@ -12,7 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int *Int ARG_UINT2:Int &Int 18446744073709551615 , 64 , fals +┃ │ Integer ( ARG_UINT1:Int *Int ARG_UINT2:Int , 64 , false ) +~> #freezer#setLocalVa ┃ │ span: 270 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u8.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u8.expected index 60b7467a9..f62461aac 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u8.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_mul-fail.unchecked_mul_u8.expected @@ -12,8 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int *Int ARG_UINT2:Int &Int 255 , 8 , false ) -~> #freezer#se +┃ │ Integer ( ARG_UINT1:Int *Int ARG_UINT2:Int , 8 , false ) +~> #freezer#setLocalVal ┃ │ span: 84 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u128.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u128.expected index ee6861d7f..30ed888ee 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u128.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u128.expected @@ -12,7 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int -Int ARG_UINT2:Int &Int 34028236692093846346337460743176 +┃ │ Integer ( ARG_UINT1:Int -Int ARG_UINT2:Int , 128 , false ) +~> #freezer#setLocalV ┃ │ span: 332 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u16.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u16.expected index 475bd35cd..b599cf45b 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u16.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u16.expected @@ -12,8 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int -Int ARG_UINT2:Int &Int 65535 , 16 , false ) -~> #freezer +┃ │ Integer ( ARG_UINT1:Int -Int ARG_UINT2:Int , 16 , false ) +~> #freezer#setLocalVa ┃ │ span: 208 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u32.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u32.expected index 45d31eb40..a71a0748e 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u32.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u32.expected @@ -12,8 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int -Int ARG_UINT2:Int &Int 4294967295 , 32 , false ) -~> #fr +┃ │ Integer ( ARG_UINT1:Int -Int ARG_UINT2:Int , 32 , false ) +~> #freezer#setLocalVa ┃ │ span: 239 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u64.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u64.expected index d1fbde105..7f22b3b49 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u64.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u64.expected @@ -12,7 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int -Int ARG_UINT2:Int &Int 18446744073709551615 , 64 , fals +┃ │ Integer ( ARG_UINT1:Int -Int ARG_UINT2:Int , 64 , false ) +~> #freezer#setLocalVa ┃ │ span: 270 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u8.expected b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u8.expected index 5031f1ed6..a08cebc22 100644 --- a/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u8.expected +++ b/kmir/src/tests/integration/data/verify-rust-std/0011-floats-ints/show/unchecked_sub-fail.unchecked_sub_u8.expected @@ -12,8 +12,8 @@ ┣━━┓ ┃ │ ┃ ├─ 4 -┃ │ Integer ( ARG_UINT1:Int -Int ARG_UINT2:Int &Int 255 , 8 , false ) -~> #freezer#se +┃ │ Integer ( ARG_UINT1:Int -Int ARG_UINT2:Int , 8 , false ) +~> #freezer#setLocalVal ┃ │ span: 84 ┃ │ ┃ │ (71 steps) diff --git a/kmir/src/tests/integration/test_integration.py b/kmir/src/tests/integration/test_integration.py index 1ad957c62..92ca721d5 100644 --- a/kmir/src/tests/integration/test_integration.py +++ b/kmir/src/tests/integration/test_integration.py @@ -38,6 +38,19 @@ 'assume-cheatcode': ['check_assume'], 'assume-cheatcode-conflict-fail': ['check_assume_conflict'], 'transmute-bytes': ['bytes_to_u64', 'u64_to_bytes'], + 'bitwise-lemmas': [ + 'mask_is_rem', + 'mask_comm', + 'shr_is_div', + 'shr_shr_is_div', + 'shl_is_mul', + 'masked_sum_no_overflow', + 'and_nonneg_bounds', + 'or_nonneg', + 'or_bytes_fit', + 'or_bytes_fit_le', + 'ne_bytes_roundtrip', + ], 'test_offset_from-fail': ['testing'], 'iter-eq-copied-take-dereftruncate': ['repro'], 'spl-multisig-iter-eq-copied-next': ['repro'],