Change:
On nightly 2021-03-05, with , I am experiencing undefined behaviour which seems to be based around . I ran this code: I expected to see the following output: I get the above output on stable 1.50.0, or on the same nightly version if I remove at least one of the three listed above. With all three flags present, on nightly 2021-03-05 I see the following output: The exact bytes count varies, so this looks like UB to me. : </p</details
Regressed since rustc 1.52.0-nightly ( 2021-03-04). At a glance, might be related.
Compiling with nightly-2021-03-05 on : I am not able to reproduce the crash, though the result is still incorrect: console $ RUSTFLAGS="-Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code" cargo +nightly run Compiling issue82833 v0.1.0 (/Users/tous/Documents/Dev/rustcissues/issue82833) Finished dev [unoptimized + debuginfo] target(s) in 46.25s Running [] ch = '' [] string = "u{0}u{0}u{0}u{0}"
is indeed the culprit:
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 [instructions]: https://rustc-dev- cc
Through an experiment wherein I link a produced from to a test program such as this: I verified that this issue is caused by something in the function itself, rather than the test glue in . Sadly, this is pretty hard to actually root cause because any attempts to remove and out of equation end up fixing this :(
I had to additionally use to reproduce the issue. The length of slice returned from is passed incorrectly to ; it is read from a stack slot that is uninitialized.
Assigning .
To illustrate what is saying: you can see that the and are stashed in some place on the stack, and the arguments are filled/reloaded from another area. This won't happen when we compile the LLVM IR with from LLVM head. I haven't tried with an LLVM build from our fork, but I'm not at all confident it'll help in reducing the problem.
Relevant IR: Under this gives the suspicious stack manipulations. And if you drop the there is an assertion failure:
Reducing the assertion failure gives: Running with we get: The kill flag on the MOV64mr is not correct. Possibly FastISel related.
Upstream report: Fixing this does seem to fix the original case as well.
also assigning just to doubly-ensure backport (from LLVM upstream to Rust's LLVM fork) for fixing this P-critical bug happens.

Discussion:
<del> Subproject commit 5f958e150d377e608d2f1f208b86110218d5da3c </del> <ins> Subproject commit 62a1ddde22c267249eda72184520a21ad2052f0b </ins>

<ins> // run-pass // compile-flags: -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Copt-level=0 -Cdebuginfo=2 // ignore-tidy-linelength // Make sure LLVM does not miscompile this. fn make_string(ch: char) -> String { let mut bytes = [0u8; 4]; ch.encode_utf8(&mut bytes).into() } fn main() { let ch = '😃'; dbg!(ch); let string = make_string(ch); dbg!(string); } </ins>

<ins> // run-pass // compile-flags: -Copt-level=0 -Cdebuginfo=2 // Make sure LLVM does not miscompile this. fn indirect_get_slice() -> &'static [usize] { &[] } #[inline(always)] fn get_slice() -> &'static [usize] { let ret = indirect_get_slice(); ret } fn main() { let output = get_slice().len(); assert_eq!(output, 0); } </ins>