{"record":{"id":"27ed7161713d0b68","repo":"wasmerio/wasmer","slug":"internal-error-entered-unreachable-code","errorCode":null,"errorMessage":"internal error: entered unreachable code","messagePattern":"internal error: entered unreachable code","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/compiler-llvm/src/translator/code.rs","lineNumber":4962,"sourceCode":"                let res = err!(self.builder.build_int_unsigned_div(v1, v2, \"\"));\n                self.state.push1(res);\n            }\n            Operator::I32RemS | Operator::I64RemS => {\n                let ((v1, i1), (v2, i2)) = self.state.pop2_extra()?;\n                let v1 = self.apply_pending_canonicalization(v1, i1)?;\n                let v2 = self.apply_pending_canonicalization(v2, i2)?;\n                let (v1, v2) = (v1.into_int_value(), v2.into_int_value());\n                let int_type = v1.get_type();\n                let (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {\n                    let min_value = int_type.const_int(i32::MIN as u64, false);\n                    let neg_one_value = int_type.const_int(-1i32 as u32 as u64, false);\n                    (min_value, neg_one_value)\n                } else if int_type == self.intrinsics.i64_ty {\n                    let min_value = int_type.const_int(i64::MIN as u64, false);\n                    let neg_one_value = int_type.const_int(-1i64 as u64, false);\n                    (min_value, neg_one_value)\n                } else {\n                    unreachable!()\n                };\n\n                self.trap_if_zero(v2)?;\n\n                // \"Overflow also leads to undefined behavior; this is a rare\n                // case, but can occur, for example, by taking the remainder of\n                // a 32-bit division of -2147483648 by -1. (The remainder\n                // doesn’t actually overflow, but this rule lets srem be\n                // implemented using instructions that return both the result\n                // of the division and the remainder.)\"\n                //   -- https://llvm.org/docs/LangRef.html#srem-instruction\n                //\n                // In Wasm, the i32.rem_s i32.const -2147483648 i32.const -1 is\n                // i32.const 0. We implement this by swapping out the left value\n                // for 0 in this case.\n                let will_overflow = err!(self.builder.build_and(\n                    err!(self.builder.build_int_compare(\n                        IntPredicate::EQ,","sourceCodeStart":4944,"sourceCodeEnd":4980,"githubUrl":"https://github.com/wasmerio/wasmer/blob/8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5/lib/compiler-llvm/src/translator/code.rs#L4944-L4980","documentation":"A bare `unreachable!()` panic in the signed-division/remainder lowering of `translate_integer_arithmetic_operator` (lib/compiler-llvm/src/translator/code.rs). The code builds i32::MIN / -1 and i64::MIN / -1 overflow-trap constants and asserts the operand's LLVM int type is exactly i32 or i64; any other type (i8/i16/i128/floating) hitting the srem/sdiv path violates the translator's invariant and aborts with \"internal error: entered unreachable code\".","triggerScenarios":"Compiling a Wasm `i32.rem_s`/`i64.rem_s`-style operator (div/rem with overflow trap) when the value on the stack has an unexpected LLVM integer type — only possible through an internal bug: a new numeric proposal (e.g. wide-arithmetic i128) routed into the scalar div/rem path, or a refactoring that changed the type of the pushed operand.","commonSituations":"Running a nightly/fork of wasmtime with partial wide-arithmetic support and a module that does `i128`-wide arithmetic; fuzzing the compiler with hand-built modules; mixing incompatible wasmtime subcrate versions so operator-to-type assumptions drift.","solutions":["Use an official released wasmtime version that matches the feature set of your modules (enable the `wide-arithmetic` Cargo feature or upgrade, rather than patching the div/rem path ad hoc).","If you modified the translator, ensure new integer types (i128) are handled before this arm, e.g. lower wide div/rem in the I64Add128/I64MulWide-style arms instead.","Rebuild cleanly with all wasmtime crates at one version to rule out enum/type mismatches.","Report a minimal .wasm repro to the Wasmtime maintainers if it occurs on an unmodified release."],"exampleFix":"// before\nlet (min_value, neg_one_value) = if int_type == self.intrinsics.i32_ty {\n    (...)\n} else if int_type == self.intrinsics.i64_ty {\n    (...)\n} else {\n    unreachable!()\n};\n// after: handle i128 explicitly (or reject it earlier with a proper error)\n} else if int_type == self.intrinsics.i128_ty {\n    let min_value = int_type.const_int(i128::MIN as u128, false);\n    let neg_one_value = int_type.const_int((-1i128) as u128, false);\n    (min_value, neg_one_value)\n} else {\n    unreachable!()\n};","handlingStrategy":"validation","validationCode":"// Ensure only integer types the translator expects reach div/rem lowering;\n// at the API level, validate the module and reject experimental numeric opcodes.\nlet features = wasmparser::WasmFeatures::default(); // no wide-arithmetic on stock releases\nwasmparser::Validator::new_with_features(features)\n    .validate_all(&wasm_bytes)\n    .map_err(|e| CompileError::InvalidModule(e))?;","typeGuard":"fn is_compiler_panic(err: &anyhow::Error) -> bool {\n    err.to_string().contains(\"entered unreachable code\")\n}","tryCatchPattern":"let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| Module::new(&engine, &wasm_bytes)));\nresult.map_err(|p| CompilerCrash::from_panic(p))?","preventionTips":["Enable the wide-arithmetic Cargo feature (or upgrade) before compiling modules that use i128-wide ops.","Don't hand-patch the div/rem overflow-trap path; extend type coverage explicitly.","Pin wasmtime crates to one release and rebuild cleanly after upgrades.","Validate modules with a feature set matching your compiler build."],"tags":["wasmtime","llvm-backend","compiler-panic","integer-division","internal-invariant"],"backgroundTag":"internal-unreachable-panic","analyzedSha":"8c4b9ee9d33fb2068863fbb3d328683e7e6ff7f5","analyzedAt":"2026-09-01T23:06:31.009Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}