wasmerio/wasmer · error

Can't form ExtraInfo with two pending canonicalization

Error message

Can't form ExtraInfo with two pending canonicalization

What it means

This panic occurs in `ExtraInfo`'s `bitand` implementation in wasmtime's LLVM backend state tracking. `ExtraInfo` can carry at most one pending NaN canonicalization flag (pending f32 or pending f64); when combining two infos that both have pending NaN flags, the `(true, true)` arm deliberately panics because the struct cannot represent two pending canonicalizations at once. It is an internal invariant violation in floating-point NaN legalization bookkeeping.

Source

Thrown at lib/compiler-llvm/src/translator/state.rs:213

        debug_assert!(
            self.has_pending_f64_nan() == other.has_pending_f64_nan()
                || self.is_arithmetic_f64()
                || other.is_arithmetic_f64()
        );
        let info = match (
            self.is_arithmetic_f32() && other.is_arithmetic_f32(),
            self.is_arithmetic_f64() && other.is_arithmetic_f64(),
        ) {
            (false, false) => Default::default(),
            (true, false) => ExtraInfo::arithmetic_f32(),
            (false, true) => ExtraInfo::arithmetic_f64(),
            (true, true) => (ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64())?,
        };
        match (self.has_pending_f32_nan(), self.has_pending_f64_nan()) {
            (false, false) => Ok(info),
            (true, false) => info | ExtraInfo::pending_f32_nan(),
            (false, true) => info | ExtraInfo::pending_f64_nan(),
            (true, true) => unreachable!("Can't form ExtraInfo with two pending canonicalization"),
        }
    }
}

#[derive(Debug, Clone, Copy)]
pub struct TagCatchInfo<'ctx> {
    pub tag: u32,
    // The catch block
    pub catch_block: BasicBlock<'ctx>,
    // The PHI node to receive the exnref, if needed; catch_all
    // blocks don't need the exnref.
    pub exnref_phi: Option<PhiValue<'ctx>>,
}

#[derive(Debug)]
pub struct Landingpad<'ctx> {
    // The block that has the landingpad instruction.
    // Will be None for catch-less try_table instructions

View on GitHub (pinned to 8c4b9ee9d3)

Solutions

  1. Upgrade wasmtime — NaN-canonicalization bookkeeping bugs are fixed over time
  2. Disable NaN canonicalization: `Config::wasm_nan_canonicalization(false)` (accepting non-deterministic NaNs) if your workload tolerates it
  3. Reduce the module with wasm-opt/NaN-transform passes so canonicalization is not needed at runtime
  4. Check whether a custom LLVM build changes float instruction selection and try the stock toolchain
  5. Report with a minimal f32/f64 module reproducing the double pending canonicalization

Example fix

// before
let mut config = Config::default();
config.wasm_nan_canonicalization(true);
// after
let mut config = Config::default();
config.wasm_nan_canonicalization(false); // avoid the ExtraInfo invariant panic
Defensive patterns

Strategy: validation

Validate before calling

let mut config = wasmtime::Config::default();
config.wasm_nan_canonicalization(false); // skip the ExtraInfo NaN bookkeeping entirely if your workload tolerates it
let engine = Engine::new(&config)?;

Try / catch

let module = std::panic::catch_unwind(|| Module::new(&engine, &bytes).map_err(|e| anyhow::anyhow!(e)))
    .map_err(|_| anyhow::anyhow!("compiler panic"))??;
// on panic: retry with wasm_nan_canonicalization(false)

Prevention

When it happens

Trigger: Chaining floating-point LLVM operations (via `and` on `ExtraInfo`) where both operands produced a pending NaN canonicalization — e.g. `ExtraInfo::arithmetic_f32() | ExtraInfo::arithmetic_f64()` combined with state that already has both `has_pending_f32_nan()` and `has_pending_f64_nan()` set.

Common situations: Running wasm with unusual NaN-heavy float code through the LLVM backend; enabling `wasm_nan_canonicalization` (or backends where it is default) on versions with bookkeeping bugs; modules mixing f32/f64 NaN-producing ops in patterns the tracker didn't expect.

Related errors


AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01). Data as JSON: /api/errors/605c09d4ef657031. Report an issue: GitHub.