Skip to content

Commit 0a956db

Browse files
committed
Restrict the spilling of scalable types to the problematic ones.
Rather than not spilling any scalable SIMD types for debug info, we only avoid spilling the ones that are going to cause a problem. Currently the only ones known to cause a problem are the internal svbool types for AArch64.
1 parent 0324ff4 commit 0a956db

File tree

1 file changed

+17
-4
lines changed

1 file changed

+17
-4
lines changed

compiler/rustc_codegen_ssa/src/mir/debuginfo.rs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -350,10 +350,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
350350
if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
351351
return;
352352
}
353-
// FIXME: Don't spill scalable simd, this works for most of them however,
354-
// some intermediate types can't be spilled e.g. `<vscale x 4 x i1>`
355-
if operand.layout.ty.is_scalable_simd() {
356-
return;
353+
354+
// LLVM doesn't handle stores on some of the internal SVE types that we are required
355+
// to use. Spilling to the stack here to create debug info for them will cause
356+
// errors during instruction selection. The types that can't be spilled are an
357+
// internal implementation detail to the intrinsic, the user should never see these
358+
// types, and therefore shouldn't need any debug info for them.
359+
if operand.layout.ty.is_scalable_simd() && bx.sess().target.arch == "aarch64" {
360+
if let ty::Adt(adt, args) = &operand.layout.ty.kind() {
361+
if let Some(f0) = adt.non_enum_variant().fields.get(FieldIdx::from_u32(0)) {
362+
let f0_ty = f0.ty(bx.tcx(), args);
363+
if let ty::Slice(e_ty) = f0_ty.kind() {
364+
if e_ty.is_bool() && adt.repr().scalable != Some(16) {
365+
return;
366+
}
367+
}
368+
}
369+
}
357370
}
358371

359372
Self::spill_operand_to_stack(*operand, name, bx)

0 commit comments

Comments
 (0)