rust-lang/rust · error
last arg
Error message
last arg
What it means
`new_args.pop().expect("last arg")` in the `__builtin_ia32_{add,sub,mul,div,max,min}{ps,pd}512_mask` arm. The adapter relocates the caller's trailing rounding/sae argument to the end (after inserting an undefined src and an all-ones mask) to match GCC's parameter order. It panics if the incoming `args` slice is empty, which only happens when an LLVM intrinsic routed here was called with no arguments — i.e. the intrinsic definition in rustc drifted from the GCC adapter's expected arity.
Source
Thrown at compiler/rustc_codegen_gcc/src/intrinsic/llvm.rs:402
new_args.push(last_arg);
}
args = new_args.into();
}
"__builtin_ia32_addps512_mask"
| "__builtin_ia32_addpd512_mask"
| "__builtin_ia32_subps512_mask"
| "__builtin_ia32_subpd512_mask"
| "__builtin_ia32_mulps512_mask"
| "__builtin_ia32_mulpd512_mask"
| "__builtin_ia32_divps512_mask"
| "__builtin_ia32_divpd512_mask"
| "__builtin_ia32_maxps512_mask"
| "__builtin_ia32_maxpd512_mask"
| "__builtin_ia32_minps512_mask"
| "__builtin_ia32_minpd512_mask" => {
let mut new_args = args.to_vec();
let last_arg = new_args.pop().expect("last arg");
let arg3_type = gcc_func.get_param_type(2);
let undefined = builder
.current_func()
.new_local(None, arg3_type, "undefined_for_intrinsic")
.to_rvalue();
new_args.push(undefined);
let arg4_type = gcc_func.get_param_type(3);
let minus_one = builder.context.new_rvalue_from_int(arg4_type, -1);
new_args.push(minus_one);
new_args.push(last_arg);
args = new_args.into();
}
"__builtin_ia32_vfmaddsubps512_mask"
| "__builtin_ia32_vfmaddsubpd512_mask"
| "__builtin_ia32_cmpsh_mask_round"
| "__builtin_ia32_vfmaddph512_mask"
| "__builtin_ia32_vfmaddsubph512_mask" => {
let mut new_args = args.to_vec();View on GitHub (pinned to 22057b88b0)
Solutions
- Ensure rustc_codegen_gcc backend revision matches the rustc toolchain it was built for.
- Pin the toolchain with `rustup default <matching-version>` or rust-toolchain.toml.
- Rebuild the backend from a commit that supports the current rustc intrinsic definitions.
- Avoid hand-written `llvm.x86.avx512.*.512` intrinsics; prefer `core::arch::x86_64::_mm512_*` which carry the correct arity.
Example fix
// before (intrinsic/llvm.rs:402)
let last_arg = new_args.pop().expect("last arg");
// after
let Some(last_arg) = new_args.pop() else {
sess.dcx().fatal(format!(
"`{}` reached masked arm with no rounding argument; \
rustc/GCC intrinsic arity mismatch",
gcc_func.get_name()
));
}; Defensive patterns
Strategy: validation
Validate before calling
// Validate argument count before invoking AVX-512 arithmetic intrinsics
// The GCC backend pops the last arg; if args is empty, it panics.
fn validate_intrinsic_argc(name: &str, args_provided: usize) -> Result<(), String> {
let required = match name {
"llvm.x86.avx512.add.ps.512"
| "llvm.x86.avx512.add.pd.512"
| "llvm.x86.avx512.sub.ps.512"
| "llvm.x86.avx512.mul.ps.512"
| "llvm.x86.avx512.div.ps.512"
| "llvm.x86.avx512.max.ps.512"
| "llvm.x86.avx512.min.ps.512" => 3, // src1, src2, rounding_control
_ => return Ok(()),
};
if args_provided < required {
return Err(format!(
"{} requires at least {} args but got {}",
name, required, args_provided
));
}
Ok(())
}
// In build.rs: probe whether the GCC backend handles your intrinsics
fn gcc_backend_probe() -> Result<(), String> {
let out = std::process::Command::new("rustc")
.args(["-Z", "codegen-backend=gcc", "--crate-type=lib", "-", "-o", "/dev/null"])
.stdin(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped())
.spawn()
.map_err(|e| format!("Cannot spawn rustc: {}", e))?;
// Feed a minimal AVX-512 test crate and check for panic
// If it panics, fall back to LLVM backend
Ok(())
} Prevention
- Avoid raw core::arch::x86_64 AVX-512 arithmetic intrinsics (_mm512_add_ps etc.) with the GCC backend — use core::simd operators instead which have separate code paths
- If you must use AVX-512 intrinsics, prefer the LLVM backend (-Ccodegen-backend=llvm) for those crates
- Run a probe compilation with the GCC backend in CI to detect unsupported intrinsic patterns before they reach production builds
When it happens
Trigger: Code lowering `llvm.x86.avx512.add.ps.512` / `pd.512` (and sub/mul/div/max/min) through rustc_codegen_gcc when rustc passes an argument list shorter than the adapter assumes, or when a non-masked form is incorrectly routed into the masked arm.
Common situations: Mismatched rustc/rustc_codegen_gcc checkout, a half-applied refactor of an LLVM intrinsic arity, or calling a raw `llvm.x86.avx512.*` intrinsic with a malformed argument list. End users hit it mainly after a rustup that bumped rustc past the rustc_codegen_gcc backend's supported version.
Related errors
- Called extract_element on a non-vector type
- vector type
- `NumScalableVectors(0)` is illformed
- `NumScalableVectors(N)` for N>8 is illformed
- first index in inbounds_gep
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/2cef4f0cbd0d91d5.json.
Report an issue: GitHub.