wasmerio/wasmer · critical
Unhandled internal variant
Error message
Unhandled internal variant
What it means
In the LLVM backend's translator, the i32x4.extadd_pairwise_i16x8 implementation uses a match over operators to pick a sign/zero extension closure; any other operator reaching this match is an internal invariant violation, so it panics with "Unhandled internal variant". This means the dispatcher passed an operator the SIMD helper was never written to receive.
Source
Thrown at lib/compiler-llvm/src/translator/code.rs:4080
let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;
let (v1, _) = self.v128_into_i32x4(v1, i1)?;
let (v2, _) = self.v128_into_i32x4(v2, i2)?;
let res = err!(self.builder.build_int_add(v1, v2, ""));
let res = err!(
self.builder
.build_bit_cast(res, self.intrinsics.i128_ty, "")
);
self.state.push1(res);
}
Operator::I32x4ExtAddPairwiseI16x8S | Operator::I32x4ExtAddPairwiseI16x8U => {
let extend_op = match op {
Operator::I32x4ExtAddPairwiseI16x8S => {
|s: &Self, v| s.builder.build_int_s_extend(v, s.intrinsics.i32x4_ty, "")
}
Operator::I32x4ExtAddPairwiseI16x8U => {
|s: &Self, v| s.builder.build_int_z_extend(v, s.intrinsics.i32x4_ty, "")
}
_ => unreachable!("Unhandled internal variant"),
};
let (v, i) = self.state.pop1_extra()?;
let (v, _) = self.v128_into_i16x8(v, i)?;
let left = err!(self.builder.build_shuffle_vector(
v,
v.get_type().get_undef(),
VectorType::const_vector(&[
self.intrinsics.i32_consts[0],
self.intrinsics.i32_consts[2],
self.intrinsics.i32_consts[4],
self.intrinsics.i32_consts[6],
]),
"",
));
let left = err!(extend_op(self, left));
let right = err!(self.builder.build_shuffle_vector(
v,View on GitHub (pinned to 8c4b9ee9d3)
Solutions
- Retry compilation with a different backend (Cranelift or singlepass) if available.
- Check your wasmer version for known LLVM-backend SIMD bugs and upgrade.
- Avoid or polyfill the extadd_pairwise SIMD instructions if stuck on an affected version.
- Report a bug with the failing module; the unreachable! marks a translator invariant break.
Example fix
// before wasmer compile module.wasm --llvm // after wasmer compile module.wasm --cranelift // workaround for LLVM SIMD translator bug
Defensive patterns
Strategy: fallback
Try / catch
// Compilation aborts via panic; isolate compilation in a worker process
let out = std::process::Command::new("wasmer").args(["compile", "--cranelift", "module.wasm"]).status(); Prevention
- Pin a wasmer version with passing LLVM SIMD tests before deploying.
- Prefer the Cranelift backend for modules using extadd_pairwise/extmul SIMD instructions.
- Add CI coverage compiling SIMD-heavy modules with the LLVM backend.
- Keep module source simple/polyfilled where SIMD intrinsics are not required.
When it happens
Trigger: Compiling a WASM module containing i32x4.extadd_pairwise_i16x8_s/u SIMD instructions (via translate_operator -> translate_integer_arithmetic_operator) with the LLVM compiler, when an internal refactor lets an unexpected Operator variant fall through.
Common situations: Running modules using the SIMD extended-pairwise-add proposal on the LLVM backend; usually a backend bug after code changes rather than a user mistake.
Related errors
- unimplemented operator {operator:?}
- Unhandled inner case
- duplicate function
- Can't form ExtraInfo with two pending canonicalization
- only numeric types are supported in function signatures
AI-assisted analysis of wasmerio/wasmer@8c4b9ee9d3 (2026-09-01).
Data as JSON: /api/errors/35b29fd44e667719.
Report an issue: GitHub.