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

  1. Update rustc_codegen_gcc to match your rustc toolchain version
  2. Simplify or remove the dead/constant-false float comparison in the source
  3. Patch the arm to return a constant false (`self.cx.const_bool(false)`) instead of `unreachable!()`
  4. 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

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


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/ee59de8dfccb0be1.json. Report an issue: GitHub.