rust-lang/rust · error

`rustc_codegen_gcc` doesn't support scalable vectors yet

Error message

`rustc_codegen_gcc` doesn't support scalable vectors yet

What it means

Builder::vscale (builder.rs:1464) is explicitly unimplemented with the message "rustc_codegen_gcc doesn't support scalable vectors yet". vscale returns the runtime scaling factor for scalable vector types (SVE on AArch64, RISC-V V extension). GCC's libgccjit exposure used by this backend does not model scalable vectors, so the call is intentionally a panic rather than silent miscompilation.

Solutions

  1. Use the LLVM backend (the only backend here that supports scalable vectors) when compiling SVE/RISC-V-V code.
  2. Disable scalable-vector features for the build target (e.g. remove +sve, +sve2, or +v from target-features) so only fixed-width vectors are used.
  3. Avoid the specific std::arch intrinsics or libraries (e.g. wide, std::simd scalable types) that lower to vscale.
  4. Track upstream support for scalable vectors in rustc_codegen_gcc; do not attempt to patch without gccjit API support.

Example fix

// before: target with scalable vectors, codegen via gcc backend
// RUSTFLAGS="-Zcodegen-backend=gcc -Ctarget-feature=+sve"

// after: drop the gcc backend for SVE code, or drop SVE
// RUSTFLAGS="-Ctarget-feature=+sve"   # LLVM backend (default)
// or
// RUSTFLAGS="-Zcodegen-backend=gcc"   # no +sve
Defensive patterns

Strategy: validation

Validate before calling

# Before building with the gcc backend, ensure no scalable-vector features.
if echo "$RUSTFLAGS" | grep -q '+sve\|+sve2\|+v\|scalable'; then
  echo 'Scalable vectors are unsupported by rustc_codegen_gcc; remove the feature or use LLVM.'
  exit 1
fi

Try / catch

if ! RUSTFLAGS="-Zcodegen-backend=gcc" cargo build 2>err.log; then
  grep -q 'scalable vectors' err.log && {
    echo 'Scalable vectors need the LLVM backend; retrying without gcc backend'
    RUSTFLAGS="${RUSTFLAGS//-Zcodegen-backend=gcc/}" cargo build
  }
fi

Prevention

When it happens

Trigger: Compiling code that references the SVE or RISC-V vector intrinsic vscale, or that lowers to scalable-vector MIR types, on the GCC backend. Triggered explicitly when std::arch intrinsics for scalable vectors are codegenned.

Common situations: Targeting aarch64 with SVE-enabled code, RISC-V with the V extension, or any path that produces scalable vector types and using -Zcodegen-backend=gcc. Also seen when a dependency auto-detects and emits SVE intrinsics.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/b7ad13b005048293. Report an issue: GitHub.

Appendix: source

Thrown at compiler/rustc_codegen_gcc/src/builder.rs:1464

        size: RValue<'gcc>,
        _align: Align,
        flags: MemFlags,
    ) {
        assert!(!flags.contains(MemFlags::NONTEMPORAL), "non-temporal memset not supported");
        let _is_volatile = flags.contains(MemFlags::VOLATILE);
        let ptr = self.pointercast(ptr, self.type_i8p());
        let memset = self.context.get_builtin_function("memset");
        // FIXME(antoyo): handle align and is_volatile.
        let fill_byte = self.context.new_cast(self.location, fill_byte, self.i32_type);
        let size = self.intcast(size, self.type_size_t(), false);
        self.block.add_eval(
            self.location,
            self.context.new_call(self.location, memset, &[ptr, fill_byte, size]),
        );
    }

    fn vscale(&mut self, _: Self::Type) -> Self::Value {
        unimplemented!("`rustc_codegen_gcc` doesn't support scalable vectors yet")
    }

    fn select(
        &mut self,
        cond: RValue<'gcc>,
        then_val: RValue<'gcc>,
        mut else_val: RValue<'gcc>,
    ) -> RValue<'gcc> {
        let func = self.current_func();
        let variable = func.new_local(self.location, then_val.get_type(), "selectVar");
        let then_block = func.new_block("then");
        let else_block = func.new_block("else");
        let after_block = func.new_block("after");
        self.llbb().end_with_conditional(self.location, cond, then_block, else_block);

        then_block.add_assignment(self.location, variable, then_val);
        then_block.end_with_jump(self.location, after_block);

View on GitHub (pinned to 7088e4b63a)