Issue 204585
Summary ICE from `#dbg_declare` of scalable vector alloca on -O0
Labels
Assignees
Reporter davidtwco
    In rustc, when emitting a `#dbg_declare` for an alloca of scalable vector types with `-O0`, we run into a "Cannot implicitly convert a scalable size to a fixed-width size in `TypeSize::operator ScalarTy()`" ICE. This appears to be due to GlobalISel being used on `-O0` and LLVM not properly falling back to SDAG, which supports scalable vectors.

```
#0 llvm::reportFatalInternalError (reason=reason@entry=0xfffff47c22f0 "Cannot implicitly convert a scalable size to a fixed-width size in `TypeSize::operator ScalarTy()`")
    at $HOME/rust/src/llvm-project/llvm/lib/Support/ErrorHandling.cpp:141
#1 0x0000ffffeecd7ddc in llvm::TypeSize::operator unsigned long (this=0xffffe4e9b100) at $HOME/rust/src/llvm-project/llvm/include/llvm/Support/TypeSize.h:377
#2 llvm::IRTranslator::getOrCreateFrameIndex (this=0xffffd00d6ff0, AI=...) at $HOME/rust/src/llvm-project/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp:259
#3 0x0000ffffeece3504 in llvm::IRTranslator::translateDbgDeclareRecord (this=0xffffd00d6ff0, Address=0xffffe0e3ec20, HasArgList=<optimised out>, Variable=0xffffe0e24408,
    _expression_=0xffffe0d78720, DL=..., MIRBuilder=...) at $HOME/rust/src/llvm-project/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp:3739
#4 0x0000ffffeece390c in llvm::IRTranslator::translateDbgInfo (this=0xffffd00d6ff0, Inst=..., MIRBuilder=...)
    at $HOME/rust/src/llvm-project/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp:3773
#5 0x0000ffffeecf1744 in llvm::IRTranslator::runOnMachineFunction (this=0xffffd00d6ff0, CurMF=...) at $HOME/rust/src/llvm-project/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp:4300
#6 0x0000ffffef2211c0 in llvm::MachineFunctionPass::runOnFunction (this=0xffffd00d6ff0, F=...) at $HOME/rust/src/llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp:108
#7 0x0000fffff0353840 in llvm::FPPassManager::runOnFunction (this=0xffffd00b99c0, F=...) at $HOME/rust/src/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1398
#8 0x0000fffff0353a6c in llvm::FPPassManager::runOnModule (this=0xffffd00b99c0, M=...) at $HOME/rust/src/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1444
#9 0x0000fffff0354264 in (anonymous namespace)::MPPassManager::runOnModule (M=..., this=0xffffd00c9030)
    at $HOME/rust/src/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1513
#10 llvm::legacy::PassManagerImpl::run (this=0xffffd00ca090, M=...) at $HOME/rust/src/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:531
#11 0x0000ffffee168db4 in LLVMRustWriteOutputFile (Target=0xffffe0e02230, PMR=0xffffd00c8860, M=0xffffe0dfe000, Path=<optimised out>, DwoPath=0x0, RustFileType=<optimised out>,
    VerifyIR=false) at llvm-wrapper/PassWrapper.cpp:496
#12 0x0000ffffee137684 in write_output_file () at compiler/rustc_codegen_llvm/src/back/write.rs:77
#13 0x0000ffffee13963c in codegen () at compiler/rustc_codegen_llvm/src/back/write.rs:1128
#14 0x0000ffffee03ee14 in execute_optimize_work_item<rustc_codegen_llvm::LlvmCodegenBackend> () at compiler/rustc_codegen_ssa/src/back/write.rs:842
```

Here's a reproduction on godbolt - https://godbolt.org/z/zxf8YcWz6 - though this might not continue to reproduce once rustc is patched to avoid this issue, but if you use "rustc 1.98.0-nightly (9e2abe0c6 2026-06-16)" (`rustup update nightly-2026-06-16`) then it should work (I just can't select that on godbolt).

<details><summary>Full LLVM IR</summary>
<p>

`#dbg_declare(ptr %_13, !240, !DIExpression(), !247)` is the specific line that causes the ICE.

```llvm
source_filename = "example.6be8c5fc5a3d8883-cgu.0"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128-Fn32"
target triple = "aarch64-unknown-linux-gnu"

@example[6be8c5fc5a3d8883]::I8_275 = internal constant [275 x i8] c"\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12\13\14\15\16\17\18\19\1A\1B\1C\1D\1E\1F !\22#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\7F\80\81\82\83\84\85\86\87\88\89\8A\8B\8C\8D\8E\8F\90\91\92\93\94\95\96\97\98\99\9A\9B\9C\9D\9E\9F\A0\A1\A2\A3\A4\A5\A6\A7\A8\A9\AA\AB\AC\AD\AE\AF\B0\B1\B2\B3\B4\B5\B6\B7\B8\B9\BA\BB\BC\BD\BE\BF\C0\C1\C2\C3\C4\C5\C6\C7\C8\C9\CA\CB\CC\CD\CE\CF\D0\D1\D2\D3\D4\D5\D6\D7\D8\D9\DA\DB\DC\DD\DE\DF\E0\E1\E2\E3\E4\E5\E6\E7\E8\E9\EA\EB\EC\ED\EE\EF\F0\F1\F2\F3\F4\F5\F6\F7\F8\F9\FA\FB\FC\FD\FE\FF\00\01\02\03\04\05\06\07\08\09\0A\0B\0C\0D\0E\0F\10\11\12", align 1, !dbg !0
@vtable.0 = private constant <{ [24 x i8], ptr, ptr, ptr }> <{ [24 x i8] c"\00\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00\08\00\00\00\00\00\00\00", ptr @<std[388427d468d10f42]::rt::lang_start<()>::{closure#0} as core[eb910544b23df3b9]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}, ptr @std[388427d468d10f42]::rt::lang_start::<()>::{closure#0}, ptr @std[388427d468d10f42]::rt::lang_start::<()>::{closure#0} }>, align 8, !dbg !8
@alloc_0bd83ae4d998a852bdd6080f4dbcd402 = private unnamed_addr constant [16 x i8] c"/app/example.rs\00", align 1
@alloc_c169e6ccc1c56e2ae1f93b887af40d28 = private unnamed_addr constant <{ ptr, [16 x i8] }> <{ ptr @alloc_0bd83ae4d998a852bdd6080f4dbcd402, [16 x i8] c"\0F\00\00\00\00\00\00\00\1E\00\00\008\00\00\00" }>, align 8
@alloc_1ec479bdab7be9e43fa833f69c453205 = private unnamed_addr constant <{ ptr, [16 x i8] }> <{ ptr @alloc_0bd83ae4d998a852bdd6080f4dbcd402, [16 x i8] c"\0F\00\00\00\00\00\00\00!\00\00\00\09\00\00\00" }>, align 8
@alloc_303930954b3aa3aea3ee2f3dab5b5b9f = private unnamed_addr constant <{ ptr, [16 x i8] }> <{ ptr @alloc_0bd83ae4d998a852bdd6080f4dbcd402, [16 x i8] c"\0F\00\00\00\00\00\00\00\22\00\00\001\00\00\00" }>, align 8
@__rustc_debug_gdb_scripts_section__ = linkonce_odr unnamed_addr constant [34 x i8] c"\01gdb_load_rust_pretty_printers.py\00", section ".debug_gdb_scripts", align 1

define hidden i64 @std[388427d468d10f42]::rt::lang_start::<()>(ptr %main, i64 %argc, ptr %argv, i8 %sigpipe) unnamed_addr #0 !dbg !42 {
start:
  %sigpipe.dbg.spill = alloca [1 x i8], align 1
  %argv.dbg.spill = alloca [8 x i8], align 8
 %argc.dbg.spill = alloca [8 x i8], align 8
  %main.dbg.spill = alloca [8 x i8], align 8
  %_7 = alloca [8 x i8], align 8
  store ptr %main, ptr %main.dbg.spill, align 8
    #dbg_declare(ptr %main.dbg.spill, !51, !DIExpression(), !57)
  store i64 %argc, ptr %argc.dbg.spill, align 8
 #dbg_declare(ptr %argc.dbg.spill, !52, !DIExpression(), !58)
  store ptr %argv, ptr %argv.dbg.spill, align 8
    #dbg_declare(ptr %argv.dbg.spill, !53, !DIExpression(), !59)
  store i8 %sigpipe, ptr %sigpipe.dbg.spill, align 1
    #dbg_declare(ptr %sigpipe.dbg.spill, !54, !DIExpression(), !60)
  store ptr %main, ptr %_7, align 8, !dbg !61
  %_0 = call i64 @std[388427d468d10f42]::rt::lang_start_internal(ptr %_7, ptr align 8 @vtable.0, i64 %argc, ptr %argv, i8 %sigpipe), !dbg !62
  ret i64 %_0, !dbg !63
}

define internal void @core[eb910544b23df3b9]::ptr::write::<core[eb910544b23df3b9]::core_arch::aarch64::sve::svint8_t>(ptr %dst, <vscale x 16 x i8> %src, ptr align 8 %0) unnamed_addr #1 !dbg !64 {
start:
  %src.dbg.spill = alloca <vscale x 16 x i8>, align 16
 %dst.dbg.spill = alloca [8 x i8], align 8
  store ptr %dst, ptr %dst.dbg.spill, align 8
    #dbg_declare(ptr %dst.dbg.spill, !111, !DIExpression(), !115)
  store <vscale x 16 x i8> %src, ptr %src.dbg.spill, align 16
    #dbg_declare(ptr %src.dbg.spill, !112, !DIExpression(), !116)
 store <vscale x 16 x i8> %src, ptr %dst, align 16, !dbg !117
  ret void, !dbg !118
}

define internal void @std[388427d468d10f42]::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>(ptr %f) unnamed_addr #2 !dbg !119 {
start:
  %dummy.dbg.spill = alloca [0 x i8], align 1
  %f.dbg.spill = alloca [8 x i8], align 8
 %result.dbg.spill = alloca [0 x i8], align 1
  %_2 = alloca [0 x i8], align 1
    #dbg_declare(ptr %result.dbg.spill, !127, !DIExpression(), !131)
 store ptr %f, ptr %f.dbg.spill, align 8
    #dbg_declare(ptr %f.dbg.spill, !126, !DIExpression(), !132)
    #dbg_declare(ptr %dummy.dbg.spill, !133, !DIExpression(), !140)
  call void @<fn() as core[eb910544b23df3b9]::ops::function::FnOnce<()>>::call_once(ptr %f) #10, !dbg !142
  call void asm sideeffect "", "~{memory}"(), !dbg !143, !srcloc !144
  ret void, !dbg !145
}

define internal <vscale x 16 x i8> @core[eb910544b23df3b9]::core_arch::aarch64::sve::generated::svext_s8::<0i32>(<vscale x 16 x i8> %op1, <vscale x 16 x i8> %op2) unnamed_addr #3 !dbg !146 {
start:
  %op2.dbg.spill = alloca <vscale x 16 x i8>, align 16
 %op1.dbg.spill = alloca <vscale x 16 x i8>, align 16
  store <vscale x 16 x i8> %op1, ptr %op1.dbg.spill, align 16
    #dbg_declare(ptr %op1.dbg.spill, !152, !DIExpression(), !154)
  store <vscale x 16 x i8> %op2, ptr %op2.dbg.spill, align 16
    #dbg_declare(ptr %op2.dbg.spill, !153, !DIExpression(), !155)
  %_0 = call <vscale x 16 x i8> @llvm.aarch64.sve.ext.nxv16i8(<vscale x 16 x i8> %op1, <vscale x 16 x i8> %op2, i32 0), !dbg !156
  ret <vscale x 16 x i8> %_0, !dbg !157
}

define internal i32 @std[388427d468d10f42]::rt::lang_start::<()>::{closure#0}(ptr align 8 %_1) unnamed_addr #1 !dbg !158 {
start:
  %self.dbg.spill = alloca [1 x i8], align 1
  %_1.dbg.spill = alloca [8 x i8], align 8
  store ptr %_1, ptr %_1.dbg.spill, align 8
    #dbg_declare(ptr %_1.dbg.spill, !164, !DIExpression(DW_OP_deref), !165)
  %_4 = load ptr, ptr %_1, align 8, !dbg !166
  call void @std[388427d468d10f42]::sys::backtrace::__rust_begin_short_backtrace::<fn(), ()>(ptr %_4) #11, !dbg !167
  %self = call i8 @<() as std[388427d468d10f42]::process::Termination>::report() #10, !dbg !168
 store i8 %self, ptr %self.dbg.spill, align 1, !dbg !168
    #dbg_declare(ptr %self.dbg.spill, !169, !DIExpression(), !186)
  %_0 = zext i8 %self to i32, !dbg !188
  ret i32 %_0, !dbg !196
}

define internal i32 @<std[388427d468d10f42]::rt::lang_start<()>::{closure#0} as core[eb910544b23df3b9]::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}(ptr %_1) unnamed_addr #1 !dbg !197 {
start:
  %_1.dbg.spill = alloca [8 x i8], align 8
  %_2 = alloca [0 x i8], align 1
  store ptr %_1, ptr %_1.dbg.spill, align 8
    #dbg_declare(ptr %_1.dbg.spill, !206, !DIExpression(), !211)
    #dbg_declare(ptr %_2, !207, !DIExpression(), !211)
  %0 = load ptr, ptr %_1, align 8, !dbg !211
  %_0 = call i32 @<std[388427d468d10f42]::rt::lang_start<()>::{closure#0} as core[eb910544b23df3b9]::ops::function::FnOnce<()>>::call_once(ptr %0) #10, !dbg !211
  ret i32 %_0, !dbg !211
}

define hidden void @example[6be8c5fc5a3d8883]::main() unnamed_addr #0 !dbg !212 {
start:
 %self.dbg.spill1.i = alloca [8 x i8], align 8
    #dbg_declare(ptr %_13, !240, !DIExpression(), !247)
  %self.dbg.spill.i4 = alloca [8 x i8], align 8
  %self.dbg.spill.i3 = alloca [8 x i8], align 8
  %count.dbg.spill.i = alloca [8 x i8], align 8
  %self.dbg.spill.i2 = alloca [8 x i8], align 8
 %self.dbg.spill.i = alloca [16 x i8], align 8
  %__c_return_value.dbg.spill = alloca <vscale x 16 x i8>, align 16
  %op1_val.dbg.spill = alloca <vscale x 16 x i8>, align 16
  %__pred.dbg.spill = alloca <vscale x 16 x i1>, align 16
  %_13 = alloca <vscale x 16 x i8>, align 16
  %__c_return_value = alloca <vscale x 16 x i8>, align 16
    #dbg_declare(ptr %__c_return_value, !220, !DIExpression(), !249)
  %__pred = call <vscale x 16 x i1> @core[eb910544b23df3b9]::core_arch::aarch64::sve::generated::svptrue_b8() #10, !dbg !250
  store <vscale x 16 x i1> %__pred, ptr %__pred.dbg.spill, align 16, !dbg !250
    #dbg_declare(ptr %__pred.dbg.spill, !214, !DIExpression(), !251)
  store ptr @example[6be8c5fc5a3d8883]::I8_275, ptr %self.dbg.spill.i, align 8
  %0 = getelementptr inbounds i8, ptr %self.dbg.spill.i, i64 8
  store i64 275, ptr %0, align 8
 #dbg_declare(ptr %self.dbg.spill.i, !252, !DIExpression(), !268)
  store ptr @example[6be8c5fc5a3d8883]::I8_275, ptr %self.dbg.spill.i2, align 8
 #dbg_declare(ptr %self.dbg.spill.i2, !270, !DIExpression(), !279)
  store i64 0, ptr %count.dbg.spill.i, align 8
    #dbg_declare(ptr %count.dbg.spill.i, !278, !DIExpression(), !281)
  %op1_val = call <vscale x 16 x i8> @core[eb910544b23df3b9]::core_arch::aarch64::sve::generated::svld1_s8(<vscale x 16 x i1> %__pred, ptr @example[6be8c5fc5a3d8883]::I8_275) #10, !dbg !282
 store <vscale x 16 x i8> %op1_val, ptr %op1_val.dbg.spill, align 16, !dbg !282
    #dbg_declare(ptr %op1_val.dbg.spill, !218, !DIExpression(), !283)
 store ptr %__c_return_value, ptr %self.dbg.spill.i3, align 8
 #dbg_declare(ptr %self.dbg.spill.i3, !284, !DIExpression(), !291)
  %_11 = call <vscale x 16 x i8> @core[eb910544b23df3b9]::core_arch::aarch64::sve::generated::svext_s8::<0i32>(<vscale x 16 x i8> %op1_val, <vscale x 16 x i8> %op1_val) #10, !dbg !293
  call void @core[eb910544b23df3b9]::ptr::write::<core[eb910544b23df3b9]::core_arch::aarch64::sve::svint8_t>(ptr %__c_return_value, <vscale x 16 x i8> %_11, ptr align 8 @alloc_1ec479bdab7be9e43fa833f69c453205) #10, !dbg !294
  call void @llvm.memcpy.p0.p0.i64(ptr align 16 %_13, ptr align 16 %__c_return_value, i64 16, i1 false), !dbg !295
  store ptr %_13, ptr %self.dbg.spill.i4, align 8, !dbg !296
    #dbg_declare(ptr %self.dbg.spill.i4, !297, !DIExpression(), !307)
  store ptr %_13, ptr %self.dbg.spill1.i, align 8, !dbg !309
 #dbg_declare(ptr %self.dbg.spill1.i, !310, !DIExpression(), !315)
 #dbg_declare(ptr %self.dbg.spill1.i, !317, !DIExpression(), !320)
  %_0.i = load <vscale x 16 x i8>, ptr %_13, align 16, !dbg !322
  store <vscale x 16 x i8> %_0.i, ptr %__c_return_value.dbg.spill, align 16, !dbg !323
 #dbg_declare(ptr %__c_return_value.dbg.spill, !238, !DIExpression(), !324)
 ret void, !dbg !325
}

define internal <vscale x 16 x i1> @core[eb910544b23df3b9]::core_arch::aarch64::sve::generated::svptrue_b8() unnamed_addr #3 !dbg !326 {
start:
  %_0 = call <vscale x 16 x i1> @llvm.aarch64.sve.ptrue.nxv16i1(i32 31), !dbg !329
  ret <vscale x 16 x i1> %_0, !dbg !332
}

define internal <vscale x 16 x i8> @core[eb910544b23df3b9]::core_arch::aarch64::sve::generated::svld1_s8(<vscale x 16 x i1> %pg, ptr %base) unnamed_addr #3 !dbg !333 {
start:
 %base.dbg.spill = alloca [8 x i8], align 8
  %pg.dbg.spill = alloca <vscale x 16 x i1>, align 16
  store <vscale x 16 x i1> %pg, ptr %pg.dbg.spill, align 16
    #dbg_declare(ptr %pg.dbg.spill, !337, !DIExpression(), !339)
 store ptr %base, ptr %base.dbg.spill, align 8
    #dbg_declare(ptr %base.dbg.spill, !338, !DIExpression(), !340)
  %_0 = call <vscale x 16 x i8> @llvm.aarch64.sve.ld1.nxv16i8(<vscale x 16 x i1> %pg, ptr %base), !dbg !341
  ret <vscale x 16 x i8> %_0, !dbg !342
}

define internal i8 @<() as std[388427d468d10f42]::process::Termination>::report() unnamed_addr #1 !dbg !343 {
start:
  %_1.dbg.spill = alloca [0 x i8], align 1
 #dbg_declare(ptr %_1.dbg.spill, !348, !DIExpression(), !349)
  ret i8 0, !dbg !350
}

define internal void @<fn() as core[eb910544b23df3b9]::ops::function::FnOnce<()>>::call_once(ptr %_1) unnamed_addr #1 !dbg !351 {
start:
  %_1.dbg.spill = alloca [8 x i8], align 8
  %_2 = alloca [0 x i8], align 1
  store ptr %_1, ptr %_1.dbg.spill, align 8
    #dbg_declare(ptr %_1.dbg.spill,<truncated>Please see the issue for the entire body.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to