[ICE]: Cannot select XtensaISD::PCREL_WRAPPER for serde Vec deserialize on xtensa-esp32s3-espidf (regression in 1.94.0.0+)
Default cargo build --release on xtensa-esp32s3-espidf fails during LLVM SelectionDAG instruction selection when deserializing a serde-internally-tagged enum that carries Vec<{ f32 }> via serde_json::from_slice. The same source compiles cleanly on 1.93.0.0 and fails on 1.94.0.0, 1.94.0.1, 1.94.0.2, and 1.95.0.0. The regression coincides with the LLVM 20 to 21 bump in the esp-rs fork.
cargo check and cargo clippy pass. Only codegen fails.
Code
Inline reproducer, four files. Build with cargo build --release.
src/lib.rs:
use serde::Deserialize;
#[derive(Deserialize)]
pub struct Inner {
pub x: f32,
}
#[derive(Deserialize)]
#[serde(tag = "kind")]
pub enum Outer {
B { items: Vec<Inner> },
}
#[unsafe(no_mangle)]
pub extern "C" fn parse(json: *const u8, len: usize) -> usize {
let bytes = unsafe { core::slice::from_raw_parts(json, len) };
match serde_json::from_slice::<Outer>(bytes) {
Ok(Outer::B { items }) => items.len(),
Err(_) => 0,
}
}
Cargo.toml:
[package]
name = "xtensa-repro"
version = "0.0.0"
edition = "2024"
[lib]
crate-type = ["staticlib"]
[dependencies]
serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0"
.cargo/config.toml:
[build]
target = "xtensa-esp32s3-espidf"
[unstable]
build-std = ["std", "panic_abort"]
[target.xtensa-esp32s3-espidf]
linker = "ldproxy"
rust-toolchain.toml:
[toolchain]
channel = "esp"
Meta
rustc 1.95.0-nightly (95e5bda86 2026-04-15) (1.95.0.0)
binary: rustc
commit-hash: 95e5bda868c960c607597bc03ed9e8f0ad26226d
commit-date: 2026-04-15
host: aarch64-apple-darwin
release: 1.95.0-nightly
LLVM version: 21.1.3
Toolchain installed via espup install --toolchain-version 1.95.0.0.
Error output
rustc-LLVM ERROR: Cannot select: 0x10991ba80: i32 = XtensaISD::PCREL_WRAPPER
TargetConstantPool:i32<@.LCP11_13 = internal constant [2 x float] [float -1.000000e+00, float 1.000000e+00]> 0
In function: _RINvXs3_NtCsl6TiYZRKOYz_10serde_core2deINtNtCsk3RiYsTPuMT_4core6marker11PhantomDataINtNtCsekL40WErSze_5alloc3vec3VecNtCseQGsyqO7byi_12xtensa_repro5InnerEENtB6_15DeserializeSeed11deserializeINtNtNtNtCs3Fy1Qq9mMO9_5serde7private2de7content19ContentDeserializerNtNtCsjFHir6sNDPy_10serde_json5error5ErrorEEB1S_
error: could not compile `xtensa-repro` (lib)
Failing function demangled:
<core::marker::PhantomData<alloc::vec::Vec<xtensa_repro::Inner>> as serde_core::de::DeserializeSeed>
::deserialize::<serde::private::de::content::ContentDeserializer<serde_json::error::Error>>
The constant pool entry [2 x float] [-1.0, 1.0] is materialized inside that monomorphization.
Backtrace
RUST_BACKTRACE=full cargo build --release
This produces no additional Rust backtrace. The failure is LLVMReportFatalError exiting rustc with status 101 directly from the backend, not via a Rust panic.
Affected channels
Bisect
| Toolchain |
LLVM |
Status |
1.93.0.0 |
20.1.1 |
builds OK |
1.94.0.0 |
21.x |
fails |
1.94.0.1 |
21.x |
fails |
1.94.0.2 |
21.x |
fails |
1.95.0.0 |
21.1.3 |
fails (this report) |
Trigger reduction (each confirmed necessary)
- target =
xtensa-esp32s3-espidf (std). The same source as a no_std staticlib on xtensa-esp32s3-none-elf builds clean.
#[serde(tag = "...")] on the enum (forces ContentDeserializer).
- An inner struct with at least one
f32 field, inside a Vec<_> inside the tagged-enum variant.
cargo build --release. No lto, opt-level, codegen-units, or panic overrides required. The default release profile is enough.
Possibly related (open, unlabeled)
PCREL_WRAPPER and "constant pool" haven't been filed yet in this repo or espressif/llvm-project.
Workaround
Stay on toolchain 1.93.0.0 until a fix lands.
[ICE]: Cannot select XtensaISD::PCREL_WRAPPER for serde Vec deserialize on xtensa-esp32s3-espidf (regression in 1.94.0.0+)
Default
cargo build --releaseonxtensa-esp32s3-espidffails during LLVM SelectionDAG instruction selection when deserializing a serde-internally-tagged enum that carriesVec<{ f32 }>viaserde_json::from_slice. The same source compiles cleanly on 1.93.0.0 and fails on 1.94.0.0, 1.94.0.1, 1.94.0.2, and 1.95.0.0. The regression coincides with the LLVM 20 to 21 bump in the esp-rs fork.cargo checkandcargo clippypass. Only codegen fails.Code
Inline reproducer, four files. Build with
cargo build --release.src/lib.rs:Cargo.toml:.cargo/config.toml:rust-toolchain.toml:Meta
Toolchain installed via
espup install --toolchain-version 1.95.0.0.Error output
Failing function demangled:
The constant pool entry
[2 x float] [-1.0, 1.0]is materialized inside that monomorphization.Backtrace
This produces no additional Rust backtrace. The failure is
LLVMReportFatalErrorexiting rustc with status 101 directly from the backend, not via a Rust panic.Affected channels
channel = "esp")Bisect
1.93.0.01.94.0.01.94.0.11.94.0.21.95.0.0Trigger reduction (each confirmed necessary)
xtensa-esp32s3-espidf(std). The same source as ano_stdstaticlib onxtensa-esp32s3-none-elfbuilds clean.#[serde(tag = "...")]on the enum (forcesContentDeserializer).f32field, inside aVec<_>inside the tagged-enum variant.cargo build --release. Nolto,opt-level,codegen-units, orpanicoverrides required. The default release profile is enough.Possibly related (open, unlabeled)
Cannot select: Constant<4096>, same target, serde 1.0.228 + piper.Unexpected node to loweron 1.94.0.1, slint demo.PCREL_WRAPPERand "constant pool" haven't been filed yet in this repo orespressif/llvm-project.Workaround
Stay on toolchain 1.93.0.0 until a fix lands.