Closed
Description
STR
$ cat foo.rs
#![crate_type = "lib"]
#[no_mangle]
pub fn foo() -> ! {
extern "Rust" {
fn bar() -> !;
}
unsafe { bar() }
}
$ rustc -C panic=abort --emit=llvm-ir,link -C opt-level=3 foo.rs
$ cat foo.ll
; ModuleID = 'foo0-8787f43e282added376259c1adb08b80.rs'
source_filename = "foo0-8787f43e282added376259c1adb08b80.rs"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: noreturn nounwind
define void @foo() unnamed_addr #0 {
start:
tail call void @bar()
unreachable
}
; Function Attrs: noreturn nounwind
declare void @bar() unnamed_addr #0
attributes #0 = { noreturn nounwind "probe-stack"="__rust_probestack" }
Is the unreachable
after calling bar
really necessary? bar
is noreturn nounwind
.
$ objdump -Cd libfoo.rlib
In archive libfoo.rlib:
foo.foo0.rcgu.o: file format elf64-x86-64
Disassembly of section .text.foo:
0000000000000000 <foo>:
0: 50 push %rax
1: e8 00 00 00 00 callq 6 <foo+0x6>
6: 0f 0b ud2
The ud2
instruction is dead code because bar
never returns.
If I manually use llc
on the optimized .ll
file I get this:
$ llc -filetype=obj foo.ll
$ objdump -Cd foo.o
foo.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <foo>:
0: 50 push %rax
1: e8 00 00 00 00 callq 6 <foo+0x6>
(I see the same if I run llc
on an unoptimized .ll
file)
Which is what I expected to get from rustc
. Is there some LLVM pass that we are disabling that
prevents LLVM from removing the ud2
instruction? I also observe this behavior when compiling for ARM.
Meta
$ rustc -V
rustc 1.29.0-nightly (97085f9fb 2018-08-01)
$ # the llc is from a Rust build I had around
$ llc -version | head -n5
LLVM (http://llvm.org/):
LLVM version 7.0.0svn
Optimized build.
Default target: x86_64-unknown-linux-gnu
Host CPU: skylake
cc @nagisa