Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SelectionDAGBuilder.cpp's llvm_unreachable is quite reachable, actually #104718

Closed
workingjubilee opened this issue Aug 18, 2024 · 3 comments · Fixed by #104757
Closed

SelectionDAGBuilder.cpp's llvm_unreachable is quite reachable, actually #104718

workingjubilee opened this issue Aug 18, 2024 · 3 comments · Fixed by #104757

Comments

@workingjubilee
Copy link
Contributor

This IR:

source_filename = "example.1c26dad09674458a-cgu.0"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-none-elf"

@llvm.used = appending global [1 x ptr] [ptr @asan.module_ctor], section "llvm.metadata"
@llvm.global_ctors = appending global [1 x { i32, ptr, ptr }] [{ i32, ptr, ptr } { i32 1, ptr @asan.module_ctor, ptr null }]

define x86_intrcc void @_ZN7example18page_fault_handler17hdb4acb34a86c6a8bE(ptr byval([8 x i8]) align 8 %0, i64 %1) unnamed_addr #0 !dbg !8 {
start:
  %Arg0.byval = alloca [8 x i8], align 8, !dbg !13
  call void @llvm.memcpy.p0.p0.i64(ptr align 8 %Arg0.byval, ptr align 8 %0, i64 8, i1 false), !dbg !13
  call void asm sideeffect alignstack inteldialect "ud2", "~{dirflag},~{fpsr},~{flags},~{memory}"(), !dbg !13, !srcloc !14
  unreachable, !dbg !13
}

declare void @__asan_report_load_n(i64, i64)
declare void @__asan_loadN(i64, i64)
declare void @__asan_report_load1(i64)
declare void @__asan_load1(i64)
declare void @__asan_report_load2(i64)
declare void @__asan_load2(i64)
declare void @__asan_report_load4(i64)
declare void @__asan_load4(i64)
declare void @__asan_report_load8(i64)
declare void @__asan_load8(i64)
declare void @__asan_report_load16(i64)
declare void @__asan_load16(i64)
declare void @__asan_report_store_n(i64, i64)
declare void @__asan_storeN(i64, i64)
declare void @__asan_report_store1(i64)
declare void @__asan_store1(i64)
declare void @__asan_report_store2(i64)
declare void @__asan_store2(i64)
declare void @__asan_report_store4(i64)
declare void @__asan_store4(i64)
declare void @__asan_report_store8(i64)
declare void @__asan_store8(i64)
declare void @__asan_report_store16(i64)
declare void @__asan_store16(i64)
declare void @__asan_report_exp_load_n(i64, i64, i32)
declare void @__asan_exp_loadN(i64, i64, i32)
declare void @__asan_report_exp_load1(i64, i32)
declare void @__asan_exp_load1(i64, i32)
declare void @__asan_report_exp_load2(i64, i32)
declare void @__asan_exp_load2(i64, i32)
declare void @__asan_report_exp_load4(i64, i32)
declare void @__asan_exp_load4(i64, i32)
declare void @__asan_report_exp_load8(i64, i32)
declare void @__asan_exp_load8(i64, i32)
declare void @__asan_report_exp_load16(i64, i32)
declare void @__asan_exp_load16(i64, i32)
declare void @__asan_report_exp_store_n(i64, i64, i32)
declare void @__asan_exp_storeN(i64, i64, i32)
declare void @__asan_report_exp_store1(i64, i32)
declare void @__asan_exp_store1(i64, i32)
declare void @__asan_report_exp_store2(i64, i32)
declare void @__asan_exp_store2(i64, i32)
declare void @__asan_report_exp_store4(i64, i32)
declare void @__asan_exp_store4(i64, i32)
declare void @__asan_report_exp_store8(i64, i32)
declare void @__asan_exp_store8(i64, i32)
declare void @__asan_report_exp_store16(i64, i32)
declare void @__asan_exp_store16(i64, i32)
declare ptr @memmove(ptr, ptr, i64)
declare ptr @memcpy(ptr, ptr, i64)
declare ptr @memset(ptr, i32, i64)
declare void @__asan_handle_no_return()
declare void @__sanitizer_ptr_cmp(i64, i64)
declare void @__sanitizer_ptr_sub(i64, i64)
declare i1 @llvm.amdgcn.is.shared(ptr nocapture) #1
declare i1 @llvm.amdgcn.is.private(ptr nocapture) #1
declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #2
declare void @__asan_before_dynamic_init(i64)
declare void @__asan_after_dynamic_init()
declare void @__asan_register_globals(i64, i64)
declare void @__asan_unregister_globals(i64, i64)
declare void @__asan_register_image_globals(i64)
declare void @__asan_unregister_image_globals(i64)
declare void @__asan_register_elf_globals(i64, i64, i64)
declare void @__asan_unregister_elf_globals(i64, i64, i64)

define internal void @asan.module_ctor() #3 {
  ret void
}

attributes #0 = { naked nocf_check noinline noredzone nounwind nonlazybind sanitize_address "probe-stack"="inline-asm" "target-cpu"="x86-64" "target-features"="-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-avx,-avx2,+soft-float" }
attributes #1 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
attributes #2 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
attributes #3 = { nounwind }

!llvm.module.flags = !{!0, !1, !2, !3, !4}
!llvm.ident = !{!5}
!llvm.dbg.cu = !{!6}

!0 = !{i32 8, !"PIC Level", i32 2}
!1 = !{i32 1, !"Code Model", i32 2}
!2 = !{i32 2, !"RtLibUseGOT", i32 1}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{!"rustc version 1.82.0-nightly (2c93fabd9 2024-08-15)"}
!6 = distinct !DICompileUnit(language: DW_LANG_Rust, file: !7, producer: "clang LLVM (rustc version 1.82.0-nightly (2c93fabd9 2024-08-15))", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
!7 = !DIFile(filename: "/app/example.rs/@/example.1c26dad09674458a-cgu.0", directory: "/app")
!8 = distinct !DISubprogram(name: "page_fault_handler", linkageName: "_ZN7example18page_fault_handler17hdb4acb34a86c6a8bE", scope: !10, file: !9, line: 6, type: !11, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !6, templateParams: !12)
!9 = !DIFile(filename: "example.rs", directory: "/app", checksumkind: CSK_MD5, checksum: "85bf207046f646941a20021898b6c9b6")
!10 = !DINamespace(name: "example", scope: null)
!11 = !DISubroutineType(types: !12)
!12 = !{}
!13 = !DILocation(line: 8, column: 9, scope: !8)
!14 = !{i32 187}

Hits this llvm_unreachable:

llvm_unreachable("Can't get register for value!");

If you don't enable trap on llvm_unreachable in the CMake, we get this instead:

PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-trunk/bin/llc -o /app/output.s -x86-asm-syntax=intel <source>
1.	Running pass 'Function Pass Manager' on module '<source>'.
2.	Running pass 'X86 Assembly Printer' on function '@_ZN7example18page_fault_handler17hdb4acb34a86c6a8bE'
 #0 0x00000000037ec688 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-trunk/bin/llc+0x37ec688)
 #1 0x00000000037ea02c SignalHandler(int) Signals.cpp:0:0
 #2 0x00007f26b2442520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #3 0x0000000002306054 (anonymous namespace)::X86MCCodeEmitter::emitPrefixImpl(unsigned int&, llvm::MCInst const&, llvm::MCSubtargetInfo const&, llvm::SmallVectorImpl<char>&) const X86MCCodeEmitter.cpp:0:0
 #4 0x00000000023093e8 (anonymous namespace)::X86MCCodeEmitter::encodeInstruction(llvm::MCInst const&, llvm::SmallVectorImpl<char>&, llvm::SmallVectorImpl<llvm::MCFixup>&, llvm::MCSubtargetInfo const&) const X86MCCodeEmitter.cpp:0:0
 #5 0x0000000001b8b846 llvm::X86AsmPrinter::emitInstruction(llvm::MachineInstr const*) (/opt/compiler-explorer/clang-trunk/bin/llc+0x1b8b846)
 #6 0x000000000261e787 llvm::AsmPrinter::emitFunctionBody() (/opt/compiler-explorer/clang-trunk/bin/llc+0x261e787)
 #7 0x0000000001b7dedb llvm::X86AsmPrinter::runOnMachineFunction(llvm::MachineFunction&) (/opt/compiler-explorer/clang-trunk/bin/llc+0x1b7dedb)
 #8 0x00000000028aac6b llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) MachineFunctionPass.cpp:0:0
 #9 0x0000000002df8272 llvm::FPPassManager::runOnFunction(llvm::Function&) (/opt/compiler-explorer/clang-trunk/bin/llc+0x2df8272)
#10 0x0000000002df8531 llvm::FPPassManager::runOnModule(llvm::Module&) (/opt/compiler-explorer/clang-trunk/bin/llc+0x2df8531)
#11 0x0000000002df77cb llvm::legacy::PassManagerImpl::run(llvm::Module&) (/opt/compiler-explorer/clang-trunk/bin/llc+0x2df77cb)
#12 0x0000000000859e94 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#13 0x000000000074c296 main (/opt/compiler-explorer/clang-trunk/bin/llc+0x74c296)
#14 0x00007f26b2429d90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#15 0x00007f26b2429e40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#16 0x0000000000851f1e _start (/opt/compiler-explorer/clang-trunk/bin/llc+0x851f1e)
Program terminated with signal: SIGSEGV
Compiler returned: 139

It seems to me, given the frequency with which code hits this, that LLVM prefers to put this macro in reachable branches of code. May I suggest renaming it, or perhaps removing the feature that it causes undefined behavior if reached at runtime?

@workingjubilee
Copy link
Contributor Author

workingjubilee commented Aug 18, 2024

Mind, it is probably the case that rustc should not emit the IR in question, but it seems incorrect to call something unreachable if it isn't. Especially if this causes errors to flow downstream to places in the machine optimizer and emitter which probably shouldn't be asked to handle such questionably-formed IR, and it should instead be eagerly rejected, perhaps with an inquiry as to why the author ever thought that LLVMIR would pass muster.

@nikic
Copy link
Contributor

nikic commented Aug 19, 2024

Reduced test case:

define void @test(ptr %ptr) naked {
  getelementptr i8, ptr %ptr, i64 1
  call void @llvm.trap()
  unreachable
}

Probably the IR verifier should check that the arguments of a naked function are not used?

We don't lower arguments for naked functions, so everything in the backend will blow up if you try to use them.

@topperc
Copy link
Collaborator

topperc commented Aug 19, 2024

Should we change SelectionDAGBuilder to have a report_fatal_error instead of llvm_unreachable too? That way compiler optimizations can't send the code down some random path the next time something like this happens?

@nikic nikic closed this as completed in 472c79c Aug 20, 2024
@EugeneZelenko EugeneZelenko added llvm:ir and removed llvm:SelectionDAG SelectionDAGISel as well labels Aug 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants