I was having fun compiling rust-analyser for maximizing performance on my machine.
Compiling commit ec645f2d75d2939a2f64959019dd916750f1ec00 of rust-analyser with lto=fat seems to work as expected.
But this configuration on windows:
[profile.release]
lto = "thin"
#incremental = true
debug = 0 # set this to 1 or 2 to get more useful backtraces in debugger
Result in rust-analyser segfaut:
Access violation executing location 0x0000000100785A4D.
rustc 1.43.0 (4fb7144ed 2020-04-20)
binary: rustc
commit-hash: 4fb7144ed159f94491249e86d5bbd033b5d60550
commit-date: 2020-04-20
host: x86_64-pc-windows-msvc
release: 1.43.0
LLVM version: 9.0
Backtrace
> rust-analyzer.exe!_ZN7globset8pathutil9file_name17h08d0f1900ad67247E
() Unknown Non-user code. Symbols loaded.
rust-analyzer.exe!_ZN7globset7GlobSet8is_match17hf1cf9a1f69ce8dd2E
() Unknown Non-user code. Symbols loaded.
rust-analyzer.exe!_ZN77_$LT$rust_analyzer..vfs_glob..RustPackageFilter$u20$as$u20$ra_vfs..Filter$GT$11include_dir17ha6495721bf18fe0eE
() Unknown Non-user code. Symbols loaded.
rust-analyzer.exe!_ZN6ra_vfs5roots16to_relative_path17hb9707874d497bdc4E
() Unknown Non-user code. Symbols loaded.
rust-analyzer.exe!_ZN106_$LT$core..iter..adapters..chain..Chain$LT$A$C$B$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$8try_fold17hac44483bd652ee40E
() Unknown Non-user code. Symbols loaded.
rust-analyzer.exe!_ZN108_$LT$walkdir..FilterEntry$LT$walkdir..IntoIter$C$P$GT$$u20$as$u20$core..iter..traits..iterator..Iterator$GT$4next17ha136f9b20c380477E
() Unknown Non-user code. Symbols loaded.
rust-analyzer.exe!_ZN6ra_vfs2io13handle_change17h8a81e482afc2c09bE
() Unknown Non-user code. Symbols loaded.
rust-analyzer.exe!_ZN6ra_vfs2io10watch_root17h425c73dcf2ce2dd1E
() Unknown Non-user code. Symbols loaded.
rust-analyzer.exe!_ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17hb0fd61dddb6f5a20E.llvm.14564221459209632736
() Unknown Non-user code. Symbols loaded.
rust-analyzer.exe!_ZN4core3mem4drop17hab46961f8567a42bE.llvm.1531302937598756963
() Unknown Non-user code. Symbols loaded.
rust-analyzer.exe!alloc::boxed::{{impl}}::call_once<(),FnOnce<()>>() Line 1017 Unknown Symbols loaded.
[Inline Frame] rust-analyzer.exe!alloc::boxed::{{impl}}::call_once() Line 1017 Unknown Symbols loaded.
[Inline Frame] rust-analyzer.exe!std::sys_common::thread::start_thread() Line 13 Unknown Symbols loaded.
rust-analyzer.exe!std::sys::windows::thread::{{impl}}::new::thread_start() Line 51 Unknown Symbols loaded.
Frame 0 Assembly
_ZN7globset8pathutil9file_name17h08d0f1900ad67247E:
00007FF66A5D76B0 push rbp
00007FF66A5D76B1 push r15
00007FF66A5D76B3 push r14
00007FF66A5D76B5 push r12
00007FF66A5D76B7 push rsi
00007FF66A5D76B8 push rdi
00007FF66A5D76B9 push rbx
00007FF66A5D76BA sub rsp,60h
00007FF66A5D76BE lea rbp,[rsp+60h]
00007FF66A5D76C3 mov qword ptr [rbp-8],0FFFFFFFFFFFFFFFEh
00007FF66A5D76CB mov r12,rcx
00007FF66A5D76CE mov rsi,qword ptr [rdx]
00007FF66A5D76D1 mov rdi,qword ptr [rdx+10h]
00007FF66A5D76D5 cmp rsi,1
00007FF66A5D76D9 mov rbx,qword ptr [rdx+18h]
00007FF66A5D76DD mov r8,rdi
00007FF66A5D76E0 cmove r8,rbx
00007FF66A5D76E4 test r8,r8
00007FF66A5D76E7 je _ZN7globset8pathutil9file_name17h08d0f1900ad67247E+45h (07FF66A5D76F5h)
00007FF66A5D76E9 mov r15,qword ptr [rdx+8]
00007FF66A5D76ED cmp byte ptr [r8+r15-1],2Eh
00007FF66A5D76F3 jne _ZN7globset8pathutil9file_name17h08d0f1900ad67247E+52h (07FF66A5D7702h)
00007FF66A5D76F5 mov qword ptr [r12],2
00007FF66A5D76FD jmp _ZN7globset8pathutil9file_name17h08d0f1900ad67247E+14Fh (07FF66A5D77FFh)
00007FF66A5D7702 mov rax,qword ptr [__imp__ZN6memchr3x867memrchr2FN17h7699f2e42a7ae581E (07FF66BBC73B0h)]
00007FF66A5D7709 mov rax,qword ptr [rax]
00007FF66A5D770C mov cl,2Fh
00007FF66A5D770E mov rdx,r15
00007FF66A5D7711 call rax <<< rax is garbage
00007FF66A5D7713 mov r14,rdx
00007FF66A5D7716 add r14,1
Frame 0 Registers
RBX聽=聽00000238EB8D2FE0
RSI聽=聽0000000000000000
RDI聽=聽0000000000000005
R12聽=聽000000C631DFE620
R13聽=聽000000C631DFE790
R14聽=聽0000000000000008
R15聽=聽00000238EB8D2FE0
RIP聽=聽00007FF66A5D7713
RSP聽=聽000000C631DFE540
RBP聽=聽000000C631DFE5A0
So this function seams to be miss compiled:
pub fn file_name<'a>(path: &Cow<'a, [u8]>) -> Option<Cow<'a, [u8]>> {
if path.is_empty() {
return None;
} else if path.last_byte() == Some(b'.') {
return None;
}
let last_slash = path.rfind_byte(b'/').map(|i| i + 1).unwrap_or(0);
Some(match *path {
Cow::Borrowed(path) => Cow::Borrowed(&path[last_slash..]),
Cow::Owned(ref path) => {
let mut path = path.clone();
path.drain_bytes(..last_slash);
Cow::Owned(path)
}
})
}
In particular this line:
let last_slash = path.rfind_byte(b'/').map(|i| i + 1).unwrap_or(0);
00007FF66A5D7702 mov rax,qword ptr [__imp__ZN6memchr3x867memrchr2FN17h7699f2e42a7ae581E (07FF66BBC73B0h)]
00007FF66A5D7709 mov rax,qword ptr [rax]
00007FF66A5D770C mov cl,2Fh
00007FF66A5D770E mov rdx,r15
00007FF66A5D7711 call rax <<< rax is garbage
I managed to create a smaller reproducer:
[package]
name = "rust-71504"
version = "0.1.0"
authors = ["Vincent Rouill茅 <[email protected]>"]
edition = "2018"
[dependencies]
globset = "0.4.5"
[profile.release]
lto = "thin"
use globset::GlobSetBuilder;
fn main() {
assert!(GlobSetBuilder::new().build().unwrap().is_match("src/tests"));
}
cargo run --release
Compiling rust-71504 v0.1.0 (C:\Development\GitHub\rust-71504)
Finished release [optimized] target(s) in 4.19s
Running `target\release\rust-71504.exe`
error: process didn't exit successfully: `target\release\rust-71504.exe` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)
Does this reproduce on nightly?
Yes with rustc 1.44.0-nightly (b2e36e6c2 2020-04-22)
And the generated code that crash is the same:
00007FF694210542 mov rax,qword ptr [__imp__ZN6memchr3x867memrchr2FN17h93ee2fcbd3a00cdaE (07FF6943143B0h)]
00007FF694210549 mov rax,qword ptr [rax]
00007FF69421054C mov cl,2Fh
00007FF69421054E mov rdx,r15
00007FF694210551 call rax
globset::pathutil::file_name llvm-ir
@_ZN6memchr3x867memrchr2FN17h5bc0baf729fbe004E = external dllimport local_unnamed_addr global %"core::sync::atomic::AtomicPtr<()>"
; globset::pathutil::file_name
; Function Attrs: uwtable
define void @_ZN7globset8pathutil9file_name17hbcd7b89f83326b91E(%"core::option::Option<alloc::borrow::Cow<[u8]>>"* noalias nocapture sret dereferenceable(32), %"alloc::borrow::Cow<[u8]>"* noalias nocapture readonly align 8 dereferenceable(32) %path) unnamed_addr #0 personality i32 (...)* @__CxxFrameHandler3 {
start:
%vector.i.i.i = alloca %"alloc::vec::Vec<u8>", align 8
%path1 = alloca %"alloc::vec::Vec<u8>", align 8
%1 = getelementptr inbounds %"alloc::borrow::Cow<[u8]>", %"alloc::borrow::Cow<[u8]>"* %path, i64 0, i32 0, i64 0
%_3.i = load i64, i64* %1, align 8, !range !2, !alias.scope !5129
%switch.i = icmp eq i64 %_3.i, 1
%owned.i = getelementptr inbounds %"alloc::borrow::Cow<[u8]>", %"alloc::borrow::Cow<[u8]>"* %path, i64 0, i32 2
%2 = getelementptr inbounds %"alloc::borrow::Cow<[u8]>", %"alloc::borrow::Cow<[u8]>"* %path, i64 0, i32 2, i64 1
%3 = getelementptr inbounds %"alloc::borrow::Cow<[u8]>", %"alloc::borrow::Cow<[u8]>"* %path, i64 0, i32 2, i64 2
%_2.sroa.0.0.in.i = bitcast [3 x i64]* %owned.i to [0 x i8]**
%_2.sroa.0.0.i = load [0 x i8]*, [0 x i8]** %_2.sroa.0.0.in.i, align 8, !alias.scope !5129, !nonnull !1
%.val.i = load i64, i64* %3, align 8, !alias.scope !5129
%.val3.i = load i64, i64* %2, align 8, !alias.scope !5129
%_2.sroa.5.0.i = select i1 %switch.i, i64 %.val.i, i64 %.val3.i
%4 = icmp eq i64 %_2.sroa.5.0.i, 0
br i1 %4, label %bb5, label %"_ZN70_$LT$core..option..Option$LT$T$GT$$u20$as$u20$core..cmp..PartialEq$GT$2eq17h38574dfda84b4f2cE.exit"
"_ZN70_$LT$core..option..Option$LT$T$GT$$u20$as$u20$core..cmp..PartialEq$GT$2eq17h38574dfda84b4f2cE.exit": ; preds = %start
%5 = add i64 %_2.sroa.5.0.i, -1
%6 = getelementptr inbounds [0 x i8], [0 x i8]* %_2.sroa.0.0.i, i64 0, i64 %5
%.val.i.i = load i8, i8* %6, align 1, !alias.scope !5132
%7 = icmp eq i8 %.val.i.i, 46
br i1 %7, label %bb12, label %_ZN4bstr9ext_slice9ByteSlice10rfind_byte17h49aefeba57a625e8E.exit
bb5: ; preds = %start
%8 = getelementptr inbounds %"core::option::Option<alloc::borrow::Cow<[u8]>>", %"core::option::Option<alloc::borrow::Cow<[u8]>>"* %0, i64 0, i32 0, i64 0
store i64 2, i64* %8, align 8
br label %bb6
bb6: ; preds = %bb5, %bb12, %bb25
ret void
_ZN4bstr9ext_slice9ByteSlice10rfind_byte17h49aefeba57a625e8E.exit: ; preds = %"_ZN70_$LT$core..option..Option$LT$T$GT$$u20$as$u20$core..cmp..PartialEq$GT$2eq17h38574dfda84b4f2cE.exit"
%9 = load atomic i64, i64* bitcast (i8** getelementptr inbounds (%"core::sync::atomic::AtomicPtr<()>", %"core::sync::atomic::AtomicPtr<()>"* @_ZN6memchr3x867memrchr2FN17h5bc0baf729fbe004E, i64 0, i32 1) to i64*) monotonic, align 8, !noalias !5137
%10 = inttoptr i64 %9 to { i64, i64 } (i8, [0 x i8]*, i64)*
%11 = icmp ne i64 %9, 0
tail call void @llvm.assume(i1 %11), !noalias !5137
%12 = tail call { i64, i64 } %10(i8 47, [0 x i8]* noalias nonnull readonly align 1 %_2.sroa.0.0.i, i64 %_2.sroa.5.0.i)
%.fca.0.extract.i.i = extractvalue { i64, i64 } %12, 0
%.fca.1.extract.i.i = extractvalue { i64, i64 } %12, 1
%switch.i41 = icmp eq i64 %.fca.0.extract.i.i, 0
%13 = add i64 %.fca.1.extract.i.i, 1
%..i = select i1 %switch.i41, i64 0, i64 %13
br i1 %switch.i, label %bb17, label %bb19
bb12: ; preds = %"_ZN70_$LT$core..option..Option$LT$T$GT$$u20$as$u20$core..cmp..PartialEq$GT$2eq17h38574dfda84b4f2cE.exit"
%14 = getelementptr inbounds %"core::option::Option<alloc::borrow::Cow<[u8]>>", %"core::option::Option<alloc::borrow::Cow<[u8]>>"* %0, i64 0, i32 0, i64 0
store i64 2, i64* %14, align 8
br label %bb6
bb17: ; preds = %_ZN4bstr9ext_slice9ByteSlice10rfind_byte17h49aefeba57a625e8E.exit
%15 = bitcast %"alloc::vec::Vec<u8>"* %path1 to i8*
call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %15)
%16 = bitcast %"alloc::vec::Vec<u8>"* %vector.i.i.i to i8*
call void @llvm.lifetime.start.p0i8(i64 24, i8* nonnull %16), !noalias !5146
%_15.i.i.i.i.i.i = icmp eq i64 %.val.i, 0
br i1 %_15.i.i.i.i.i.i, label %"_ZN5alloc3vec12Vec$LT$T$GT$13with_capacity17hc96a68e01ada40f4E.exit.i.i.i", label %"_ZN62_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..AllocRef$GT$5alloc17h2d3f07a62eac3ef8E.exit.i.i.i.i.i.i"
"_ZN62_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..AllocRef$GT$5alloc17h2d3f07a62eac3ef8E.exit.i.i.i.i.i.i": ; preds = %bb17
%17 = tail call i8* @__rust_alloc(i64 %.val.i, i64 1) #16, !noalias !5156
%18 = icmp eq i8* %17, null
br i1 %18, label %bb18.i.i.i.i.i.i, label %"_ZN5alloc3vec12Vec$LT$T$GT$13with_capacity17hc96a68e01ada40f4E.exit.i.i.i"
bb18.i.i.i.i.i.i: ; preds = %"_ZN62_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..AllocRef$GT$5alloc17h2d3f07a62eac3ef8E.exit.i.i.i.i.i.i"
; call alloc::alloc::handle_alloc_error
tail call void @_ZN5alloc5alloc18handle_alloc_error17h31c2c94a892ecbd6E(i64 %.val.i, i64 1) #16, !noalias !5156
unreachable
"_ZN5alloc3vec12Vec$LT$T$GT$13with_capacity17hc96a68e01ada40f4E.exit.i.i.i": ; preds = %"_ZN62_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..AllocRef$GT$5alloc17h2d3f07a62eac3ef8E.exit.i.i.i.i.i.i", %bb17
%ptr.0.i.i.i.i.i.i = phi i8* [ inttoptr (i64 1 to i8*), %bb17 ], [ %17, %"_ZN62_$LT$alloc..alloc..Global$u20$as$u20$core..alloc..AllocRef$GT$5alloc17h2d3f07a62eac3ef8E.exit.i.i.i.i.i.i" ]
%19 = bitcast %"alloc::vec::Vec<u8>"* %vector.i.i.i to i8**
store i8* %ptr.0.i.i.i.i.i.i, i8** %19, align 8, !alias.scope !5159, !noalias !5146
%20 = getelementptr inbounds %"alloc::vec::Vec<u8>", %"alloc::vec::Vec<u8>"* %vector.i.i.i, i64 0, i32 1, i32 1
store i64 %.val.i, i64* %20, align 8, !alias.scope !5159, !noalias !5146
%21 = getelementptr inbounds %"alloc::vec::Vec<u8>", %"alloc::vec::Vec<u8>"* %vector.i.i.i, i64 0, i32 3
store i64 0, i64* %21, align 8, !alias.scope !5159, !noalias !5146
; invoke alloc::vec::Vec<T>::reserve
invoke fastcc void @"_ZN5alloc3vec12Vec$LT$T$GT$7reserve17h8328aa9ad9c26b4cE"(%"alloc::vec::Vec<u8>"* nonnull align 8 dereferenceable(24) %vector.i.i.i, i64 %.val.i)
to label %"_ZN63_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$core..clone..Clone$GT$5clone17ha8687e9b953bbe67E.exit" unwind label %funclet_bb5.i.i.i, !noalias !5146
funclet_bb5.i.i.i: ; preds = %"_ZN5alloc3vec12Vec$LT$T$GT$13with_capacity17hc96a68e01ada40f4E.exit.i.i.i"
%cleanuppad.i.i.i = cleanuppad within none []
call fastcc void bitcast (void (%"alloc::string::String"*)* @_ZN4core3ptr13drop_in_place17h16849cb7958e75d3E to void (%"alloc::vec::Vec<u8>"*)*)(%"alloc::vec::Vec<u8>"* nonnull %vector.i.i.i) #22 [ "funclet"(token %cleanuppad.i.i.i) ], !noalias !5146
cleanupret from %cleanuppad.i.i.i unwind to caller
"_ZN63_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$core..clone..Clone$GT$5clone17ha8687e9b953bbe67E.exit": ; preds = %"_ZN5alloc3vec12Vec$LT$T$GT$13with_capacity17hc96a68e01ada40f4E.exit.i.i.i"
%22 = getelementptr inbounds [0 x i8], [0 x i8]* %_2.sroa.0.0.i, i64 0, i64 0
%self.idx.val.i.i.i.i.i = load i64, i64* %21, align 8, !noalias !5160
%_13.i.i.i.i.i = add i64 %self.idx.val.i.i.i.i.i, %.val.i
store i64 %_13.i.i.i.i.i, i64* %21, align 8, !noalias !5160
%23 = bitcast %"alloc::vec::Vec<u8>"* %vector.i.i.i to [0 x i8]**
%_3.idx.val.i1.i.i.i.i.i.i = load [0 x i8]*, [0 x i8]** %23, align 8, !noalias !5160, !nonnull !1
%24 = getelementptr inbounds [0 x i8], [0 x i8]* %_3.idx.val.i1.i.i.i.i.i.i, i64 0, i64 %self.idx.val.i.i.i.i.i
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 1 %24, i8* nonnull align 1 %22, i64 %.val.i, i1 false) #16, !noalias !5163
call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull align 8 %15, i8* nonnull align 8 %16, i64 24, i1 false), !noalias !5164
call void @llvm.lifetime.end.p0i8(i64 24, i8* nonnull %16), !noalias !5146
%self.idx.i.i = getelementptr inbounds %"alloc::vec::Vec<u8>", %"alloc::vec::Vec<u8>"* %path1, i64 0, i32 3
%self.idx.val.i.i = load i64, i64* %self.idx.i.i, align 8, !noalias !5165
%_26.i.i = icmp ult i64 %self.idx.val.i.i, %..i
br i1 %_26.i.i, label %bb19.i.i, label %bb22
bb19.i.i: ; preds = %"_ZN63_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$core..clone..Clone$GT$5clone17ha8687e9b953bbe67E.exit"
; invoke core::panicking::panic
invoke void @_ZN4core9panicking5panic17h07bec01df8643458E([0 x i8]* noalias nonnull readonly align 1 bitcast (<{ [28 x i8] }>* @anon.aed952bceef054ab22098ec10f8b5504.48 to [0 x i8]*), i64 28, %"core::panic::Location"* noalias readonly align 8 dereferenceable(24) bitcast (<{ i8*, [16 x i8] }>* @anon.aed952bceef054ab22098ec10f8b5504.40 to %"core::panic::Location"*))
to label %.noexc unwind label %funclet_bb23
.noexc: ; preds = %bb19.i.i
unreachable
bb19: ; preds = %_ZN4bstr9ext_slice9ByteSlice10rfind_byte17h49aefeba57a625e8E.exit
%_3.i.i.i = icmp ult i64 %.val3.i, %..i
br i1 %_3.i.i.i, label %bb2.i.i.i, label %"_ZN4core5slice74_$LT$impl$u20$core..ops..index..Index$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$5index17h358af9de6dfcb22eE.exit"
bb2.i.i.i: ; preds = %bb19
; call core::slice::slice_index_order_fail
tail call void @_ZN4core5slice22slice_index_order_fail17h3334b3335c3bd3ecE(i64 %..i, i64 %.val3.i)
unreachable
"_ZN4core5slice74_$LT$impl$u20$core..ops..index..Index$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$5index17h358af9de6dfcb22eE.exit": ; preds = %bb19
%25 = getelementptr inbounds [0 x i8], [0 x i8]* %_2.sroa.0.0.i, i64 0, i64 %..i
%_8.i.i.i.i = sub i64 %.val3.i, %..i
%26 = bitcast i8* %25 to [0 x i8]*
br label %bb25
bb22: ; preds = %"_ZN63_$LT$alloc..vec..Vec$LT$T$GT$$u20$as$u20$core..clone..Clone$GT$5clone17ha8687e9b953bbe67E.exit"
store i64 0, i64* %self.idx.i.i, align 8, !noalias !5165
%27 = bitcast %"alloc::vec::Vec<u8>"* %path1 to [0 x i8]**
%_3.idx.val.i22.i.i = load [0 x i8]*, [0 x i8]** %27, align 8, !noalias !5165, !nonnull !1
%_43.i.i = sub i64 %self.idx.val.i.i, %..i
%_4.i.i.i.i.i = icmp eq i64 %_43.i.i, 0
%28 = getelementptr inbounds [0 x i8], [0 x i8]* %_3.idx.val.i22.i.i, i64 0, i64 0
br i1 %_4.i.i.i.i.i, label %bb24, label %bb2.i.i.i.i.i
bb2.i.i.i.i.i: ; preds = %bb22
%_11.i.i.i.i.i = icmp eq i64 %..i, 0
br i1 %_11.i.i.i.i.i, label %bb11.i.i.i.i.i, label %bb5.i.i.i.i.i
bb5.i.i.i.i.i: ; preds = %bb2.i.i.i.i.i
%29 = getelementptr inbounds [0 x i8], [0 x i8]* %_3.idx.val.i22.i.i, i64 0, i64 %..i
tail call void @llvm.memmove.p0i8.p0i8.i64(i8* nonnull align 1 %28, i8* nonnull align 1 %29, i64 %_43.i.i, i1 false) #16
br label %bb11.i.i.i.i.i
bb11.i.i.i.i.i: ; preds = %bb5.i.i.i.i.i, %bb2.i.i.i.i.i
store i64 %_43.i.i, i64* %self.idx.i.i, align 8
br label %bb24
bb24: ; preds = %bb11.i.i.i.i.i, %bb22
%_36.sroa.4.0..sroa_idx16 = getelementptr inbounds %"alloc::vec::Vec<u8>", %"alloc::vec::Vec<u8>"* %path1, i64 0, i32 1, i32 1
%_36.sroa.4.0.copyload = load i64, i64* %_36.sroa.4.0..sroa_idx16, align 8
call void @llvm.lifetime.end.p0i8(i64 24, i8* nonnull %15)
br label %bb25
bb25: ; preds = %"_ZN4core5slice74_$LT$impl$u20$core..ops..index..Index$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$5index17h358af9de6dfcb22eE.exit", %bb24
%_20.sroa.8.0 = phi i64 [ undef, %"_ZN4core5slice74_$LT$impl$u20$core..ops..index..Index$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$5index17h358af9de6dfcb22eE.exit" ], [ %_43.i.i, %bb24 ]
%_20.sroa.7.0 = phi i64 [ %_8.i.i.i.i, %"_ZN4core5slice74_$LT$impl$u20$core..ops..index..Index$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$5index17h358af9de6dfcb22eE.exit" ], [ %_36.sroa.4.0.copyload, %bb24 ]
%_20.sroa.5.0 = phi [0 x i8]* [ %26, %"_ZN4core5slice74_$LT$impl$u20$core..ops..index..Index$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$5index17h358af9de6dfcb22eE.exit" ], [ %_3.idx.val.i22.i.i, %bb24 ]
%_20.sroa.0.0 = phi i64 [ 0, %"_ZN4core5slice74_$LT$impl$u20$core..ops..index..Index$LT$I$GT$$u20$for$u20$$u5b$T$u5d$$GT$5index17h358af9de6dfcb22eE.exit" ], [ 1, %bb24 ]
%_20.sroa.0.0..sroa_idx = getelementptr inbounds %"core::option::Option<alloc::borrow::Cow<[u8]>>", %"core::option::Option<alloc::borrow::Cow<[u8]>>"* %0, i64 0, i32 0, i64 0
store i64 %_20.sroa.0.0, i64* %_20.sroa.0.0..sroa_idx, align 8
%_20.sroa.5.0..sroa_idx5 = getelementptr inbounds %"core::option::Option<alloc::borrow::Cow<[u8]>>", %"core::option::Option<alloc::borrow::Cow<[u8]>>"* %0, i64 0, i32 2
%_20.sroa.5.0..sroa_cast = bitcast [3 x i64]* %_20.sroa.5.0..sroa_idx5 to [0 x i8]**
store [0 x i8]* %_20.sroa.5.0, [0 x i8]** %_20.sroa.5.0..sroa_cast, align 8
%30 = getelementptr inbounds %"core::option::Option<alloc::borrow::Cow<[u8]>>", %"core::option::Option<alloc::borrow::Cow<[u8]>>"* %0, i64 0, i32 2, i64 1
store i64 %_20.sroa.7.0, i64* %30, align 8
%31 = getelementptr inbounds %"core::option::Option<alloc::borrow::Cow<[u8]>>", %"core::option::Option<alloc::borrow::Cow<[u8]>>"* %0, i64 0, i32 2, i64 2
store i64 %_20.sroa.8.0, i64* %31, align 8
br label %bb6
funclet_bb23: ; preds = %bb19.i.i
%cleanuppad = cleanuppad within none []
call fastcc void bitcast (void (%"alloc::string::String"*)* @_ZN4core3ptr13drop_in_place17h16849cb7958e75d3E to void (%"alloc::vec::Vec<u8>"*)*)(%"alloc::vec::Vec<u8>"* nonnull %path1) #22 [ "funclet"(token %cleanuppad) ]
cleanupret from %cleanuppad unwind to caller
}
memchr::x86::memrchr::detect llvm-ir
@_ZN6memchr3x867memrchr2FN17h5bc0baf729fbe004E = local_unnamed_addr global <{ i8*, [0 x i8] }> <{ i8* bitcast ({ i64, i64 } (i8, [0 x i8]*, i64)* @_ZN6memchr3x867memrchr6detect17h517e20eb83e5ca39E to i8*), [0 x i8] zeroinitializer }>, align 8
@"\01__imp__ZN6memchr3x867memrchr2FN17h5bc0baf729fbe004E" = global i8* bitcast (<{ i8*, [0 x i8] }>* @_ZN6memchr3x867memrchr2FN17h5bc0baf729fbe004E to i8*)
; memchr::x86::memrchr::detect
; Function Attrs: uwtable
define internal { i64, i64 } @_ZN6memchr3x867memrchr6detect17h517e20eb83e5ca39E(i8 %n1, [0 x i8]* noalias nonnull readonly align 1 %haystack.0, i64 %haystack.1) unnamed_addr #2 personality i32 (...)* @__CxxFrameHandler3 {
start:
%0 = load atomic i64, i64* getelementptr inbounds ([2 x %"std::std_detect::detect::cache::Cache"], [2 x %"std::std_detect::detect::cache::Cache"]* @_ZN3std10std_detect6detect5cache5CACHE17h36155bdd5a985257E, i64 0, i64 0, i32 1, i32 1) seq_cst, align 8
%1 = icmp eq i64 %0, -1
br i1 %1, label %bb7.i.i.i, label %_ZN3std10std_detect6detect4arch21__is_feature_detected4avx217hc0fbd12b9336552cE.exit
bb7.i.i.i: ; preds = %start
; call std::std_detect::detect::os::detect_features
%2 = tail call i64 @_ZN3std10std_detect6detect2os15detect_features17h30d1c684eca000e9E()
%_6.i.i.i.i.i = and i64 %2, 9223372036854775807
store atomic i64 %_6.i.i.i.i.i, i64* getelementptr inbounds ([2 x %"std::std_detect::detect::cache::Cache"], [2 x %"std::std_detect::detect::cache::Cache"]* @_ZN3std10std_detect6detect5cache5CACHE17h36155bdd5a985257E, i64 0, i64 0, i32 1, i32 1) seq_cst, align 8
%_15.i.i.i.i.i = lshr i64 %2, 63
store atomic i64 %_15.i.i.i.i.i, i64* getelementptr inbounds ([2 x %"std::std_detect::detect::cache::Cache"], [2 x %"std::std_detect::detect::cache::Cache"]* @_ZN3std10std_detect6detect5cache5CACHE17h36155bdd5a985257E, i64 0, i64 1, i32 1, i32 1) seq_cst, align 8
br label %_ZN3std10std_detect6detect4arch21__is_feature_detected4avx217hc0fbd12b9336552cE.exit
_ZN3std10std_detect6detect4arch21__is_feature_detected4avx217hc0fbd12b9336552cE.exit: ; preds = %start, %bb7.i.i.i
%3 = load atomic i64, i64* getelementptr inbounds ([2 x %"std::std_detect::detect::cache::Cache"], [2 x %"std::std_detect::detect::cache::Cache"]* @_ZN3std10std_detect6detect5cache5CACHE17h36155bdd5a985257E, i64 0, i64 0, i32 1, i32 1) seq_cst, align 8
%4 = trunc i64 %3 to i16
%5 = icmp slt i16 %4, 0
%.sink = select i1 %5, i64 ptrtoint ({ i64, i64 } (i8, [0 x i8]*, i64)* @_ZN6memchr3x863avx7memrchr17h082fa08fb3cf7b05E to i64), i64 ptrtoint ({ i64, i64 } (i8, [0 x i8]*, i64)* @_ZN6memchr3x864sse27memrchr17h62035a598a168baeE to i64)
%6 = select i1 %5, { i64, i64 } (i8, [0 x i8]*, i64)* @_ZN6memchr3x863avx7memrchr17h082fa08fb3cf7b05E, { i64, i64 } (i8, [0 x i8]*, i64)* @_ZN6memchr3x864sse27memrchr17h62035a598a168baeE
store atomic i64 %.sink, i64* bitcast (<{ i8*, [0 x i8] }>* @_ZN6memchr3x867memrchr2FN17h5bc0baf729fbe004E to i64*) monotonic, align 8
%7 = tail call { i64, i64 } %6(i8 %n1, [0 x i8]* noalias nonnull readonly align 1 %haystack.0, i64 %haystack.1)
ret { i64, i64 } %7
}
Probable relevant part:
%9 = load atomic i64, i64* bitcast (i8** getelementptr inbounds (%"core::sync::atomic::AtomicPtr<()>", %"core::sync::atomic::AtomicPtr<()>"* @_ZN6memchr3x867memrchr2FN17h5bc0baf729fbe004E, i64 0, i32 1) to i64*) monotonic, align 8, !noalias !5137
%10 = inttoptr i64 %9 to { i64, i64 } (i8, [0 x i8]*, i64)*
%11 = icmp ne i64 %9, 0
tail call void @llvm.assume(i1 %11), !noalias !5137
Assembly and llvm-ir files: deps.zip
Let's have more people to try and minimize that.
@rustbot ping cleanup
@rustbot ping llvm
Hey Cleanup Crew ICE-breakers! This bug has been identified as a good
"Cleanup ICE-breaking candidate". In case it's useful, here are some
[instructions] for tackling these sorts of bugs. Maybe take a look?
Thanks! <3
cc @AminArria @chrissimpkins @contrun @DutchGhost @elshize @ethanboxx @h-michael @HallerPatrick @hdhoang @hellow554 @imtsuki @jakevossen5 @kanru @KarlK90 @LeSeulArtichaut @MAdrianMattocks @matheus-consoli @mental32 @nmccarty @Noah-Kennedy @pard68 @PeytonT @pierreN @Redblueflame @RobbieClarken @RobertoSnap @robjtede @SarthakSingh31 @senden9 @shekohex @sinato @spastorino @turboladen @woshilapin @yerke
@rustbot ping llvm
Hey LLVM ICE-breakers! This bug has been identified as a good
"LLVM ICE-breaking candidate". In case it's useful, here are some
[instructions] for tackling these sorts of bugs. Maybe take a look?
Thanks! <3
cc @comex @CrazyDebugger @cuviper @DutchGhost @hanna-kruppe @hdhoang @heyrutvik @JOE1994 @jryans @mmilenko @nagisa @nikic @Noah-Kennedy @SiavoshZarrasvand @spastorino @vertexclique
Assigning P-critical as discussed as part of the Prioritization Working Group process and removing I-prioritize.
I've used the example code in https://github.com/rust-lang/rust/issues/71504#issuecomment-618941146, but can't reproduce. Neither in stable nor in nightly for windows and macOS.
$> cargo run --release
Finished release [optimized] target(s) in 0.03s
Running `target\release\i71504.exe`
thread 'main' panicked at 'assertion failed: GlobSetBuilder::new().build().unwrap().is_match("src/tests")', src\main.rs:4:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
error: process didn't exit successfully: `target\release\i71504.exe` (exit code: 101)
$> rustc -vV
rustc 1.43.0 (4fb7144ed 2020-04-20)
binary: rustc
commit-hash: 4fb7144ed159f94491249e86d5bbd033b5d60550
commit-date: 2020-04-20
host: x86_64-pc-windows-msvc
release: 1.43.0
LLVM version: 9.0
I'm sorry, I forgot to unset my global linker setting, I was using "lld-link".
With the official link.exe, this bug doesn't occur.
So this is an lld (LLVM 10) bug, the first I encounter. So I guess this is out of rust-lang scope.
I there any target where lld is the official linker? Might be a COFF only bug tho.
Changing the linker back to the default one, also fixed the compilation of rust-analyser, lto=fat, target-cpu=native btw (52s total vs 100s with the official build, I'm happy).
cc @Gankra (relevant to the LLD-by-default plans)
Removing I-unsound as this is an upstream bug. Maybe it should be closed outright, since having an issue for every problem in LLVM isn't terribly helpful, but with the plans for using LLD by default this might be helpful.
I there any target where lld is the official linker?
Yes, embedded ARM targets use it by default. They're ELF targets though, and LLD's ELF backend is fairly reliable (I've only witnessed it corrupting debuginfo once, not cause crashes like this).
Well I'have been using lld-link as default rust linker on windows for about 2 years now: no issue.
PS: I was able to reproduce it with lld-link 9.0.1 and 10.0.0
After some discussion during triage meeting, we've decided to change the priority to P-high.
I was able to repro this with the following steps:
rustup update nightly
Install lld-link.exe. On Windows, the easiest thing I found was to install LLVM from their downloads page. I did not add LLVM to my system path.
Setup the repro crate as described in https://github.com/rust-lang/rust/issues/71504#issuecomment-618941146
Inside the root of the repro crate, create .cargo/config and put this in it:
[target.x86_64-pc-windows-msvc]
linker = "lld-link.exe"
$ PATH=/c/Program\ Files/LLVM/bin/:$PATH cargo +nightly run --release
Compiling memchr v2.3.3
Compiling log v0.4.8
Compiling regex-syntax v0.6.17
Compiling aho-corasick v0.7.10
Compiling bstr v0.2.12
Compiling regex v1.3.7
Compiling globset v0.4.5
Compiling test_ice v0.1.0 (C:\projects\temp\test_ice)
Finished release [optimized] target(s) in 16.54s
Running `target\release\test_ice.exe`
error: process didn't exit successfully: `target\release\test_ice.exe` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)
Segmentation fault
I can confirm that this is lld specific, using the native Windows linker does not cause an issue.
This no longer occurs on the latest nightly. I bisected the fix to https://github.com/rust-lang/rust/commit/63d03779946a07d8c418a361278168a6d3a1f4d2 (in nightly-2020-05-08)
The relevant change seems to be https://github.com/rust-lang/cargo/pull/8192. Were the 'unused' object files somehow affecting LTO?
Minimized:
fn main() {
memchr::memrchr(b'a', b"b");
}
given "memchr" = "2.1.2", and the setup described in https://github.com/rust-lang/rust/issues/71504#issuecomment-622422103
Minimized even further:
// lib.rs
use std::sync::atomic::{AtomicPtr, Ordering};
#[inline(always)]
pub fn memrchr() {
fn detect() {}
static FN: AtomicPtr<()> = AtomicPtr::new(detect as *mut ());
unsafe {
let fun = FN.load(Ordering::SeqCst);
std::mem::transmute::<*mut (), fn()>(fun)()
}
}
// main.rs
fn main() {
badlld::memrchr();
}
These functions must be in two different crates, and be compiled with the setup described in https://github.com/rust-lang/rust/issues/71504#issuecomment-622422103
Most helpful comment
I was able to repro this with the following steps:
rustup update nightlyInstall
lld-link.exe. On Windows, the easiest thing I found was to install LLVM from their downloads page. I did not add LLVM to my system path.Setup the repro crate as described in https://github.com/rust-lang/rust/issues/71504#issuecomment-618941146
Inside the root of the repro crate, create
.cargo/configand put this in it:I can confirm that this is
lldspecific, using the native Windows linker does not cause an issue.