rust-lang/rust · error
funnel shift on {:?}
Error message
funnel shift on {:?} What it means
An `unimplemented!("funnel shift on {:?}", elem_type)` ICE inside `simd_funnel_shift` in rustc_codegen_gcc (master-feature path). The function lowers SIMD funnel-shift to a scalar loop but only supports vector element widths 8/16/32/64 bits. A vector whose element type is none of those (e.g. 128-bit integers, or a non-integer element) reaches the `else` branch and panics.
Source
Thrown at compiler/rustc_codegen_gcc/src/intrinsic/simd.rs:1709
let vector_type = a_type.unqualified().dyncast_vector().expect("vector type");
let num_units = vector_type.get_num_units();
let elem_type = vector_type.get_element_type();
let (new_int_type, int_shift_val, int_mask) = if elem_type.is_compatible_with(bx.u8_type)
|| elem_type.is_compatible_with(bx.i8_type)
{
(bx.u16_type, 8, u8::MAX as u64)
} else if elem_type.is_compatible_with(bx.u16_type) || elem_type.is_compatible_with(bx.i16_type)
{
(bx.u32_type, 16, u16::MAX as u64)
} else if elem_type.is_compatible_with(bx.u32_type) || elem_type.is_compatible_with(bx.i32_type)
{
(bx.u64_type, 32, u32::MAX as u64)
} else if elem_type.is_compatible_with(bx.u64_type) || elem_type.is_compatible_with(bx.i64_type)
{
(bx.u128_type, 64, u64::MAX)
} else {
unimplemented!("funnel shift on {:?}", elem_type);
};
let int_mask = bx.context.new_rvalue_from_long(new_int_type, int_mask as i64);
let int_shift_val = bx.context.new_rvalue_from_int(new_int_type, int_shift_val);
let mut elements = vec![];
let unsigned_type = elem_type.to_unsigned(bx);
for i in 0..num_units {
let index = bx.context.new_rvalue_from_int(bx.int_type, i as i32);
let a_val = bx.context.new_vector_access(None, a, index).to_rvalue();
let a_val = bx.context.new_bitcast(None, a_val, unsigned_type);
let a_val = bx.gcc_int_cast(a_val, new_int_type);
let b_val = bx.context.new_vector_access(None, b, index).to_rvalue();
let b_val = bx.context.new_bitcast(None, b_val, unsigned_type);
let b_val = bx.gcc_int_cast(b_val, new_int_type);
let shift_val = bx.context.new_vector_access(None, shift, index).to_rvalue();
let shift_val = bx.gcc_int_cast(shift_val, new_int_type);
let mut val = a_val << int_shift_val | b_val;
if shift_left {View on GitHub (pinned to 7088e4b63a)
Solutions
- Use LLVM backend for funnel shifts on non-standard lane widths.
- Ensure the SIMD vector's lane type is one of i8..i64 / u8..u64 — widen/narrow explicitly before the funnel shift.
- If 128-bit funnel shift is required, decompose it manually into 64-bit operations so it stays within supported element widths.
Example fix
// before (cg_gcc, funnel shift on u128 lanes -> ICE)
let r: Simd<u128, 4> = unsafe { simd_shl(a, b, shift) };
// after — LLVM backend, or restrict lanes to u64
let a64 = a.cast::<u64>(); // operate on supported lane width Defensive patterns
Strategy: validation
Validate before calling
# Funnel shift only supports i8..i64 / u8..u64 lanes in cg_gcc # In review, reject funnel/rotate shifts on u128/i128 lanes when targeting cg_gcc rg -n 'simd_(shl|shr)|rotate_left|rotate_right' src/ # audit lane widths
Prevention
- Keep SIMD funnel/rotate-shift lane widths in {8,16,32,64}-bit integer ranges under cg_gcc.
- Cast wide integer lanes to u64 before funnel shifting.
- Use LLVM for funnel shifts on 128-bit or non-integer lanes.
When it happens
Trigger: Invoking a SIMD funnel-shift intrinsic (`simd_shl`/`simd_shr` funnel forms) on a SIMD vector whose lane type is `i128`/`u128`, a float, or any type not matching `u8/i8/u16/i16/u32/i32/u64/i64`, while compiling with cg_gcc (master).
Common situations: Portable-SIMD code that performs funnel/rotate-shift on unusual lane widths (128-bit integer lanes), or where type inference produces an unexpected element type, combined with the GCC backend.
Related errors
- unsupported LLVM intrinsic {}
- simd {}
- not implemented
- Kind: {:?}
- unsupported Apple pointer width {pointer_width:?}
AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10).
Data as JSON: /api/errors/51cff1d858e86666.
Report an issue: GitHub.