rust-lang/rust · critical
internal error: entered unreachable code
Error message
internal error: entered unreachable code
What it means
In `fcmp`, the LLVM float predicate `RealPredicate::RealPredicateFalse` (a comparison that is always false) is matched to `unreachable!()`, producing an internal compiler error (ICE) if it is ever reached. The GCC backend assumes rustc constant-folds this degenerate predicate away before codegen; LLVM uses it mostly as a sentinel for folded comparisons, so cg_gcc treats its presence as a frontend contract violation.
Source
Thrown at compiler/rustc_codegen_gcc/src/builder.rs:1353
// When they are not pointers, we want a transmute (or reinterpret_cast).
self.bitcast(value, dest_ty)
}
(true, true) => self.cx.context.new_cast(self.location, value, dest_ty),
(true, false) => unimplemented!(),
}
}
/* Comparisons */
fn icmp(&mut self, op: IntPredicate, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> {
self.gcc_icmp(op, lhs, rhs)
}
fn fcmp(&mut self, op: RealPredicate, lhs: RValue<'gcc>, rhs: RValue<'gcc>) -> RValue<'gcc> {
// LLVM has a concept of "unordered compares", where eg ULT returns true if either the two
// arguments are unordered (i.e. either is NaN), or the lhs is less than the rhs. GCC does
// not natively have this concept, so in some cases we must manually handle NaNs
let must_handle_nan = match op {
RealPredicate::RealPredicateFalse => unreachable!(),
RealPredicate::RealOEQ => false,
RealPredicate::RealOGT => false,
RealPredicate::RealOGE => false,
RealPredicate::RealOLT => false,
RealPredicate::RealOLE => false,
RealPredicate::RealONE => false,
RealPredicate::RealORD => unreachable!(),
RealPredicate::RealUNO => unreachable!(),
RealPredicate::RealUEQ => false,
RealPredicate::RealUGT => true,
RealPredicate::RealUGE => true,
RealPredicate::RealULT => true,
RealPredicate::RealULE => true,
RealPredicate::RealUNE => false,
RealPredicate::RealPredicateTrue => unreachable!(),
};
let cmp = self.context.new_comparison(self.location, op.to_gcc_comparison(), lhs, rhs);View on GitHub (pinned to 22057b88b0)
Solutions
- Update rustc_codegen_gcc to match your rustc toolchain version
- Simplify or remove the dead/constant-false float comparison in the source
- Patch the arm to return a constant false (`self.cx.const_bool(false)`) instead of `unreachable!()`
- File an issue with the MIR/IR reproducer
Example fix
// before RealPredicate::RealPredicateFalse => unreachable!(), // after RealPredicate::RealPredicateFalse => return self.cx.const_bool(false),
Defensive patterns
Strategy: fallback
Validate before calling
// fcmp panics (unreachable!()) on RealPredicate::RealPredicateFalse.
// 'always false' has no GCC lowering here — emit a constant false instead.
match op {
RealPredicate::RealPredicateFalse => {
return const_false(builder);
}
_ => { /* safe to call builder.fcmp(op, lhs, rhs) */ }
} Try / catch
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
builder.fcmp(op, lhs, rhs)
})) {
Ok(v) => v,
Err(_) => const_false(builder),
} Prevention
- Replace `fcmp RealPredicateFalse` with a constant false at the IR-building layer; it never needs a real comparison.
- Audit frontends so the always-false float predicate is constant-folded before reaching cg_gcc.
When it happens
Trigger: rustc lowers a float comparison to `fcmp` with the `RealPredicateFalse` predicate — e.g. a constant-folded dead branch involving float operands, or an `fcmp` that the frontend failed to simplify before reaching the backend.
Common situations: cg_gcc built against a rustc version that started emitting this predicate for certain const-evaluated float conditions, or unusual `if false { ... }` guards over float expressions. Reproducible only under the GCC backend.
Related errors
- first index in inbounds_gep
- not implemented
- `rustc_codegen_gcc` doesn't support scalable vectors yet
- Called extract_element on a non-vector type
- unsupported float: {self:?}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/ee59de8dfccb0be1.json.
Report an issue: GitHub.