Rust: Upgrade to LLVM11 caused a codegen regression on Windows

Created on 23 Oct 2020  路  20Comments  路  Source: rust-lang/rust

The following code is panicing for me in CI on Win64 and Win32 (not other platforms). I haven't been able to reproduce it locally, but we bisected it to #73526 (the LLVM 11 upgrade).

Code

    fn GetRgbInputBufferImpl(kSwapRB: bool, kHasAlpha: bool) -> (usize, Vec<u8>) {
        let colorSamples = [0, 5, 16, 43, 101, 127, 182, 255];
        let colorSampleMax = colorSamples.len();
        let pixelSize = if kHasAlpha { 4 } else { 3 };
        let pixelCount = colorSampleMax * colorSampleMax * 256 * 3;

        let mut outBuffer = vec![0; pixelCount * pixelSize];

        let kRIndex = if kSwapRB { 2 } else { 0 };
        let kGIndex = 1;
        let kBIndex = if kSwapRB { 0 } else { 2 };
        let kAIndex = 3;

        // Sample every red pixel value with a subset of green and blue.
        let mut color = &mut outBuffer[..];
        for r in 0..=255 {
            for &g in colorSamples.iter() {
                for &b in colorSamples.iter() {
                    color[kRIndex] = r;
                    color[kGIndex] = g;
                    color[kBIndex] = b;
                    if kHasAlpha {
                        color[kAIndex] = 0x80;
                    }
                    color = &mut color[pixelSize..];
                }
            }
        }

        // Sample every green pixel value with a subset of red and blue.
        let mut color = &mut outBuffer[..];
        for &r in colorSamples.iter() {
            for g in 0..=255 {
                for &b in colorSamples.iter() {
                    color[kRIndex] = r;
                    color[kGIndex] = g;
                    color[kBIndex] = b;
                    if kHasAlpha {
                        color[kAIndex] = 0x80;
                    }
                    color = &mut color[pixelSize..];
                }
            }
        }

        // Sample every blue pixel value with a subset of red and green.
        let mut color = &mut outBuffer[..];
        let mut i = 0;
        for &r in colorSamples.iter() {
            for &g in colorSamples.iter() {
                for b in 0..=255 {
                    if color.len() == 0 {
                        dbg!((i, r, g, b));
                    }
                    color[kRIndex] = r;
                    color[kGIndex] = g;
                    color[kBIndex] = b;
                    if kHasAlpha {
                        color[kAIndex] = 0x80;
                    }
                    i += pixelSize;
                    color = &mut color[pixelSize..];
                }
            }
        }

        (pixelCount, outBuffer)
    }
[task 2020-10-23T03:49:58.569Z] 03:49:58     INFO -  ---- gtest::test::sRGB_to_sRGB_precache stdout ----
[task 2020-10-23T03:49:58.569Z] 03:49:58     INFO -  [gfx\qcms\src\gtest.rs:455] (i, r, g, b) = (
[task 2020-10-23T03:49:58.570Z] 03:49:58     INFO -      147456,
[task 2020-10-23T03:49:58.571Z] 03:49:58     INFO -      0,
[task 2020-10-23T03:49:58.571Z] 03:49:58     INFO -      0,
[task 2020-10-23T03:49:58.572Z] 03:49:58     INFO -      0,
[task 2020-10-23T03:49:58.573Z] 03:49:58     INFO -  )
[task 2020-10-23T03:49:58.573Z] 03:49:58     INFO -  thread 'gtest::test::sRGB_to_sRGB_precache' panicked at 'index out of bounds: the len is 0 but the index is 0', gfx\qcms\src\gtest.rs:457:21
[task 2020-10-23T03:49:58.574Z] 03:49:58     INFO -  stack backtrace:
[task 2020-10-23T03:49:58.574Z] 03:49:58     INFO -     0:     0x7ff7b5a789de - std::backtrace_rs::backtrace::dbghelp::trace
[task 2020-10-23T03:49:58.575Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\..\..\backtrace\src\backtrace\dbghelp.rs:108
[task 2020-10-23T03:49:58.576Z] 03:49:58     INFO -     1:     0x7ff7b5a789de - std::backtrace_rs::backtrace::trace_unsynchronized
[task 2020-10-23T03:49:58.576Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66
[task 2020-10-23T03:49:58.577Z] 03:49:58     INFO -     2:     0x7ff7b5a789de - std::sys_common::backtrace::_print_fmt
[task 2020-10-23T03:49:58.578Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\sys_common\backtrace.rs:67
[task 2020-10-23T03:49:58.578Z] 03:49:58     INFO -     3:     0x7ff7b5a789de - std::sys_common::backtrace::_print::{{impl}}::fmt
[task 2020-10-23T03:49:58.579Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\sys_common\backtrace.rs:46
[task 2020-10-23T03:49:58.580Z] 03:49:58     INFO -     4:     0x7ff7b5a8da2b - core::fmt::write
[task 2020-10-23T03:49:58.580Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\core\src\fmt\mod.rs:1076
[task 2020-10-23T03:49:58.581Z] 03:49:58     INFO -     5:     0x7ff7b5a388c8 - std::io::Write::write_fmt<test::helpers::sink::Sink>
[task 2020-10-23T03:49:58.581Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\io\mod.rs:1516
[task 2020-10-23T03:49:58.582Z] 03:49:58     INFO -     6:     0x7ff7b5a71fe1 - std::io::impls::{{impl}}::write_fmt<Write>
[task 2020-10-23T03:49:58.583Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\io\impls.rs:179
[task 2020-10-23T03:49:58.583Z] 03:49:58     INFO -     7:     0x7ff7b5a7bc8d - std::sys_common::backtrace::_print
[task 2020-10-23T03:49:58.584Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\sys_common\backtrace.rs:49
[task 2020-10-23T03:49:58.585Z] 03:49:58     INFO -     8:     0x7ff7b5a7bc8d - std::sys_common::backtrace::print
[task 2020-10-23T03:49:58.585Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\sys_common\backtrace.rs:36
[task 2020-10-23T03:49:58.586Z] 03:49:58     INFO -     9:     0x7ff7b5a7bc8d - std::panicking::default_hook::{{closure}}
[task 2020-10-23T03:49:58.586Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\panicking.rs:208
[task 2020-10-23T03:49:58.587Z] 03:49:58     INFO -    10:     0x7ff7b5a7b807 - std::panicking::default_hook
[task 2020-10-23T03:49:58.588Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\panicking.rs:224
[task 2020-10-23T03:49:58.588Z] 03:49:58     INFO -    11:     0x7ff7b5a7c53f - std::panicking::rust_panic_with_hook
[task 2020-10-23T03:49:58.589Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\panicking.rs:577
[task 2020-10-23T03:49:58.589Z] 03:49:58     INFO -    12:     0x7ff7b5a7c0a5 - std::panicking::begin_panic_handler::{{closure}}
[task 2020-10-23T03:49:58.590Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\panicking.rs:484
[task 2020-10-23T03:49:58.591Z] 03:49:58     INFO -    13:     0x7ff7b5a7931f - std::sys_common::backtrace::__rust_end_short_backtrace<closure-0,!>
[task 2020-10-23T03:49:58.591Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\sys_common\backtrace.rs:141
[task 2020-10-23T03:49:58.592Z] 03:49:58     INFO -    14:     0x7ff7b5a7c059 - std::panicking::begin_panic_handler
[task 2020-10-23T03:49:58.592Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\panicking.rs:483
[task 2020-10-23T03:49:58.593Z] 03:49:58     INFO -    15:     0x7ff7b5a8c1f0 - core::panicking::panic_fmt
[task 2020-10-23T03:49:58.594Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\core\src\panicking.rs:85
[task 2020-10-23T03:49:58.594Z] 03:49:58     INFO -    16:     0x7ff7b5a8c1b7 - core::panicking::panic_bounds_check
[task 2020-10-23T03:49:58.595Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\core\src\panicking.rs:62
[task 2020-10-23T03:49:58.596Z] 03:49:58     INFO -    17:     0x7ff7b5a2818d - qcms::gtest::test::GetRgbInputBufferImpl
[task 2020-10-23T03:49:58.596Z] 03:49:58     INFO -                                 at z:\build\build\src\gfx\qcms\src\gtest.rs:457
[task 2020-10-23T03:49:58.597Z] 03:49:58     INFO -    18:     0x7ff7b5a2213c - qcms::gtest::test::GetRgbInputBuffer
[task 2020-10-23T03:49:58.597Z] 03:49:58     INFO -                                 at z:\build\build\src\gfx\qcms\src\gtest.rs:473
[task 2020-10-23T03:49:58.598Z] 03:49:58     INFO -    19:     0x7ff7b5a2213c - qcms::gtest::test::QcmsProfileTest::SetBuffers
[task 2020-10-23T03:49:58.598Z] 03:49:58     INFO -                                 at z:\build\build\src\gfx\qcms\src\gtest.rs:610
[task 2020-10-23T03:49:58.599Z] 03:49:58     INFO -    20:     0x7ff7b5a2213c - qcms::gtest::test::QcmsProfileTest::TransformPrecache
[task 2020-10-23T03:49:58.599Z] 03:49:58     INFO -                                 at z:\build\build\src\gfx\qcms\src\gtest.rs:695
[task 2020-10-23T03:49:58.600Z] 03:49:58     INFO -    21:     0x7ff7b5a2213c - qcms::gtest::test::sRGB_to_sRGB_precache
[task 2020-10-23T03:49:58.601Z] 03:49:58     INFO -                                 at z:\build\build\src\gfx\qcms\src\gtest.rs:797
[task 2020-10-23T03:49:58.601Z] 03:49:58     INFO -    22:     0x7ff7b5a2213c - qcms::gtest::test::sRGB_to_sRGB_precache::{{closure}}
[task 2020-10-23T03:49:58.602Z] 03:49:58     INFO -                                 at z:\build\build\src\gfx\qcms\src\gtest.rs:791
[task 2020-10-23T03:49:58.602Z] 03:49:58     INFO -    23:     0x7ff7b5a2213c - core::ops::function::FnOnce::call_once<closure-0,tuple<>>
[task 2020-10-23T03:49:58.603Z] 03:49:58     INFO -                                 at Z:\task_1603423771\fetches\rustc\lib\rustlib\src\rust\library\core\src\ops\function.rs:227
[task 2020-10-23T03:49:58.603Z] 03:49:58     INFO -    24:     0x7ff7b5a68b16 - core::ops::function::FnOnce::call_once
[task 2020-10-23T03:49:58.604Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\core\src\ops\function.rs:227
[task 2020-10-23T03:49:58.605Z] 03:49:58     INFO -    25:     0x7ff7b5a68b16 - test::__rust_begin_short_backtrace<fn()>
[task 2020-10-23T03:49:58.606Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\test\src\lib.rs:517
[task 2020-10-23T03:49:58.606Z] 03:49:58     INFO -    26:     0x7ff7b5a6645e - alloc::boxed::{{impl}}::call_once
[task 2020-10-23T03:49:58.607Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\alloc\src\boxed.rs:1042
[task 2020-10-23T03:49:58.607Z] 03:49:58     INFO -    27:     0x7ff7b5a6645e - std::panic::{{impl}}::call_once
[task 2020-10-23T03:49:58.608Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\panic.rs:308
[task 2020-10-23T03:49:58.608Z] 03:49:58     INFO -    28:     0x7ff7b5a6645e - std::panicking::try::do_call
[task 2020-10-23T03:49:58.609Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\panicking.rs:381
[task 2020-10-23T03:49:58.610Z] 03:49:58     INFO -    29:     0x7ff7b5a6645e - std::panicking::try
[task 2020-10-23T03:49:58.610Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\panicking.rs:345
[task 2020-10-23T03:49:58.611Z] 03:49:58     INFO -    30:     0x7ff7b5a6645e - std::panic::catch_unwind
[task 2020-10-23T03:49:58.612Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\panic.rs:382
[task 2020-10-23T03:49:58.612Z] 03:49:58     INFO -    31:     0x7ff7b5a6645e - test::run_test_in_process
[task 2020-10-23T03:49:58.613Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\test\src\lib.rs:544
[task 2020-10-23T03:49:58.613Z] 03:49:58     INFO -    32:     0x7ff7b5a6645e - test::run_test::run_test_inner::{{closure}}
[task 2020-10-23T03:49:58.614Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\test\src\lib.rs:450
[task 2020-10-23T03:49:58.614Z] 03:49:58     INFO -    33:     0x7ff7b5a37bd6 - std::sys_common::backtrace::__rust_begin_short_backtrace<closure-0,tuple<>>
[task 2020-10-23T03:49:58.615Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\sys_common\backtrace.rs:125
[task 2020-10-23T03:49:58.615Z] 03:49:58     INFO -    34:     0x7ff7b5a37bd6 - std::sys_common::backtrace::__rust_begin_short_backtrace<closure-0,tuple<>>
[task 2020-10-23T03:49:58.616Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\sys_common\backtrace.rs:125
[task 2020-10-23T03:49:58.617Z] 03:49:58     INFO -    35:     0x7ff7b5a3e93e - std::thread::{{impl}}::spawn_unchecked::{{closure}}::{{closure}}
[task 2020-10-23T03:49:58.617Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\thread\mod.rs:470
[task 2020-10-23T03:49:58.618Z] 03:49:58     INFO -    36:     0x7ff7b5a3e93e - std::panic::{{impl}}::call_once
[task 2020-10-23T03:49:58.618Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\panic.rs:308
[task 2020-10-23T03:49:58.619Z] 03:49:58     INFO -    37:     0x7ff7b5a3e93e - std::panicking::try::do_call
[task 2020-10-23T03:49:58.620Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\panicking.rs:381
[task 2020-10-23T03:49:58.621Z] 03:49:58     INFO -    38:     0x7ff7b5a3e93e - std::panicking::try
[task 2020-10-23T03:49:58.622Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\panicking.rs:345
[task 2020-10-23T03:49:58.623Z] 03:49:58     INFO -    39:     0x7ff7b5a3e93e - std::panic::catch_unwind
[task 2020-10-23T03:49:58.623Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\panic.rs:382
[task 2020-10-23T03:49:58.624Z] 03:49:58     INFO -    40:     0x7ff7b5a3e93e - std::thread::{{impl}}::spawn_unchecked::{{closure}}
[task 2020-10-23T03:49:58.625Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\std\src\thread\mod.rs:469
[task 2020-10-23T03:49:58.626Z] 03:49:58     INFO -    41:     0x7ff7b5a3e93e - core::ops::function::FnOnce::call_once<closure-0,tuple<>>
[task 2020-10-23T03:49:58.627Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\core\src\ops\function.rs:227
[task 2020-10-23T03:49:58.627Z] 03:49:58     INFO -    42:     0x7ff7b5a85627 - alloc::boxed::{{impl}}::call_once
[task 2020-10-23T03:49:58.628Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\alloc\src\boxed.rs:1042
[task 2020-10-23T03:49:58.629Z] 03:49:58     INFO -    43:     0x7ff7b5a85627 - alloc::boxed::{{impl}}::call_once
[task 2020-10-23T03:49:58.630Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\library\alloc\src\boxed.rs:1042
[task 2020-10-23T03:49:58.630Z] 03:49:58     INFO -    44:     0x7ff7b5a85627 - std::sys::windows::thread::{{impl}}::new::thread_start
[task 2020-10-23T03:49:58.631Z] 03:49:58     INFO -                                 at /rustc/31530e5d132ebcc3654baf2e5460599681520af0\/library\std\src\sys\windows\thread.rs:56
[task 2020-10-23T03:49:58.631Z] 03:49:58     INFO -    45:     0x7ffe280e13d2 - BaseThreadInitThunk
[task 2020-10-23T03:49:58.631Z] 03:49:58     INFO -    46:     0x7ffe2a1c54e4 - RtlUserThreadStart

It still fails on Nightly.

https://bugzilla.mozilla.org/show_bug.cgi?id=1672813 has some more details.

A-LLVM C-bug I-unsound 馃挜 O-windows-msvc P-critical T-compiler regression-from-stable-to-stable

Most helpful comment

I have a patch that fixes (what I believe to be) the underlying LLVM bug; see https://bugs.llvm.org/show_bug.cgi?id=46943 ; I'm working on making a LLVM unit test and then I'll put up a patch for the llvm-devs to review.

All 20 comments

cc @rust-lang/wg-llvm

I can now reproduce this locally. I'll try to come up with a standalone test case.

Running the following on win64 with --release and codegen-units=1 panics.

fn inner() -> Vec<u8> {
    let color_sample_max = 4;
    let pixel_size = 4;
    let mut out = vec![0; color_sample_max * 256 * pixel_size];

    let mut color = &mut out[..];
    for _ in 0..color_sample_max {
        for b in 0..=255 {
            color[0] = 0x80;
            color[1] = 0x80;
            color[2] = b;
            color[3] = 0x80;

            color = &mut color[pixel_size..];
        }
    }
    out
}

fn f1()  {
    inner();
}

fn f2()  {
    inner();
}

fn main() {
    f1();
    f2();
}

Affects only MSVC:

$ rustc -O -C codegen-units=1 test.rs && ./test

$ rustc -O -C codegen-units=1 test.rs --target x86_64-pc-windows-msvc && ./test
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', test.rs:21:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

@rustbot modify labels: +O-windows-msvc

Error: Label Windows-msvc can only be set by Rust team members

Please let @rust-lang/release know if you're having trouble with this bot.

I compared the generated code between x86_64-pc-windows-gnu and x86_64-pc-windows-msvc and the msvc version drops the ret path and has a testq instead of a testb

Interestingly, there does not seem to be any real differences between the llvm-ir of the two versions which suggests that things are going wrong late in the pipeline.

Running the following on win64 with --release and codegen-units=1 panics.

Doesn't panic here with LTO, either thin or fat.

It looks like the codegen difference is caused by the attribute (...)* @__CxxFrameHandler3 vs (%"unwind::libunwind::EXCEPTION_RECORD"*, i8*, %"unwind::libunwind::CONTEXT"*, %"unwind::libunwind::DISPATCHER_CONTEXT"*)* @rust_eh_personality on @_ZN3out5inner17h

Or more specifically, using the name __CxxFrameHandler3 changing the name to __CxxFramHandler3 makes the difference go away.

Here's the diff from taking the results from rustc --target x86_64-pc-windows-msvc -O -C codegen-units=1 --emit=llvm-ir out.rs and renaming __CxxFrameHandler3 to __CxxFramHandler3 and then compiling with llc:

--- bad.s   2020-10-25 18:48:19.000000000 -0400
+++ good.s  2020-10-25 18:47:59.000000000 -0400
@@ -12,7 +12,9 @@
    .endef
    .p2align    4, 0x90                         # -- Begin function _ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h39f1d54c4354cfb7E
 _ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h39f1d54c4354cfb7E: # @_ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h39f1d54c4354cfb7E
+.Lfunc_begin0:
 .seh_proc _ZN3std10sys_common9backtrace28__rust_begin_short_backtrace17h39f1d54c4354cfb7E
+   .seh_handler __CxxFramHandler3, @unwind, @except
 # %bb.0:                                # %start
    subq    $40, %rsp
    .seh_stackalloc 40
@@ -23,9 +25,26 @@
    #NO_APP
    addq    $40, %rsp
    retq
+.Lfunc_end0:
    .seh_handlerdata
    .text
    .seh_endproc
+   .section    .xdata,"dr"
+   .p2align    2
+GCC_except_table0:
+.Lexception0:
+   .byte   255                             # @LPStart Encoding = omit
+   .byte   255                             # @TType Encoding = omit
+   .byte   1                               # Call site Encoding = uleb128
+   .uleb128 .Lcst_end0-.Lcst_begin0
+.Lcst_begin0:
+   .uleb128 .Lfunc_begin0-.Lfunc_begin0    # >> Call Site 1 <<
+   .uleb128 .Lfunc_end0-.Lfunc_begin0      #   Call between .Lfunc_begin0 and .Lfunc_end0
+   .byte   0                               #     has no landing pad
+   .byte   0                               #   On action: cleanup
+.Lcst_end0:
+   .p2align    2
+   .text
                                         # -- End function
    .def     _ZN3std2rt10lang_start17h44748352664c46c2E;
    .scl    2;
@@ -107,24 +126,30 @@
    .endef
    .p2align    4, 0x90                         # -- Begin function _ZN3out5inner17h353a9cc7a3c23810E
 _ZN3out5inner17h353a9cc7a3c23810E:      # @_ZN3out5inner17h353a9cc7a3c23810E
+.Lfunc_begin1:
 .seh_proc _ZN3out5inner17h353a9cc7a3c23810E
+   .seh_handler __CxxFramHandler3, @unwind, @except
 # %bb.0:                                # %start
    pushq   %rsi
    .seh_pushreg %rsi
+   pushq   %rdi
+   .seh_pushreg %rdi
+   pushq   %rbx
+   .seh_pushreg %rbx
    subq    $32, %rsp
    .seh_stackalloc 32
    .seh_endprologue
-   movq    %rcx, %rsi
+   movq    %rcx, %rbx
    movl    $4096, %ecx                     # imm = 0x1000
    movl    $1, %edx
    callq   __rust_alloc_zeroed
    testq   %rax, %rax
-   je  .LBB5_17
+   je  .LBB5_18
 # %bb.1:                                # %_ZN5alloc3vec9from_elem17h74690dcc847adf77E.exit
-   movq    %rax, (%rsi)
-   movq    $4096, 8(%rsi)                  # imm = 0x1000
-   movq    $4096, 16(%rsi)                 # imm = 0x1000
-   movq    $-4096, %r8                     # imm = 0xF000
+   movq    %rax, (%rbx)
+   movq    $4096, 8(%rbx)                  # imm = 0x1000
+   movq    $4096, 16(%rbx)                 # imm = 0x1000
+   movq    $-4096, %rdx                    # imm = 0xF000
    xorl    %ecx, %ecx
    .p2align    4, 0x90
 .LBB5_2:                                # %bb2.i
@@ -137,7 +162,7 @@
    movb    %cl, 6(%rax)
    movb    $-128, 7(%rax)
    addq    $8, %rax
-   addq    $8, %r8
+   addq    $8, %rdx
    incb    %cl
    jne .LBB5_2
 # %bb.3:                                # %bb2.i.1.preheader
@@ -150,16 +175,16 @@
    movb    %sil, 2(%rax,%rsi,4)
    movw    $-32640, 3(%rax,%rsi,4)         # imm = 0x8080
    movb    $-128, 5(%rax,%rsi,4)
-   leal    1(%rsi), %edx
-   movb    %dl, 6(%rax,%rsi,4)
+   leal    1(%rsi), %edi
+   movb    %dil, 6(%rax,%rsi,4)
    movb    $-128, 7(%rax,%rsi,4)
    addq    $-8, %rcx
    addq    $2, %rsi
-   cmpb    $-1, %dl
+   cmpb    $-1, %dil
    jne .LBB5_4
 # %bb.5:                                # %bb2.i.2.preheader
    subq    %rcx, %rax
-   subq    %r8, %rcx
+   subq    %rdx, %rcx
    xorl    %edx, %edx
    .p2align    4, 0x90
 .LBB5_6:                                # %bb2.i.2
@@ -177,32 +202,41 @@
    jne .LBB5_6
 # %bb.7:                                # %bb2.i.3.preheader
    xorl    %edx, %edx
-   testq   %rcx, %rcx
-   je  .LBB5_9
    .p2align    4, 0x90
-.LBB5_13:                               # %bb16.3
+.LBB5_8:                                # %bb2.i.3
                                         # =>This Inner Loop Header: Depth=1
+   testq   %rcx, %rcx
+   je  .LBB5_9
+# %bb.13:                               # %bb16.3
+                                        #   in Loop: Header=BB5_8 Depth=1
    movb    $-128, (%rax)
    cmpq    $1, %rcx
    je  .LBB5_10
 # %bb.14:                               # %bb17.3
-                                        #   in Loop: Header=BB5_13 Depth=1
+                                        #   in Loop: Header=BB5_8 Depth=1
    leal    1(%rdx), %esi
    movb    $-128, 1(%rax)
    cmpq    $3, %rcx
    jb  .LBB5_11
 # %bb.15:                               # %bb18.3
-                                        #   in Loop: Header=BB5_13 Depth=1
+                                        #   in Loop: Header=BB5_8 Depth=1
    movb    %dl, 2(%rax)
    je  .LBB5_12
 # %bb.16:                               # %bb19.3
-                                        #   in Loop: Header=BB5_13 Depth=1
+                                        #   in Loop: Header=BB5_8 Depth=1
    movb    $-128, 3(%rax)
    addq    $-4, %rcx
    addq    $4, %rax
    movl    %esi, %edx
-   testq   %rcx, %rcx
-   jne .LBB5_13
+   testb   %sil, %sil
+   jne .LBB5_8
+# %bb.17:                               # %bb4.loopexit.3
+   movq    %rbx, %rax
+   addq    $32, %rsp
+   popq    %rbx
+   popq    %rdi
+   popq    %rsi
+   retq
 .LBB5_9:                                # %panic
    leaq    .Lalloc20(%rip), %r8
    xorl    %ecx, %ecx
@@ -223,14 +257,27 @@
    movl    $3, %ecx
    movl    $3, %edx
    callq   _ZN4core9panicking18panic_bounds_check17h2d25ebb349b8ce6eE
-.LBB5_17:                               # %bb20.i.i.i.i.i
+.LBB5_18:                               # %bb20.i.i.i.i.i
    movl    $4096, %ecx                     # imm = 0x1000
    movl    $1, %edx
    callq   _ZN5alloc5alloc18handle_alloc_error17h71c060cff7245371E
    int3
+.Lfunc_end1:
    .seh_handlerdata
    .text
    .seh_endproc
+   .section    .xdata,"dr"
+   .p2align    2
+GCC_except_table5:
+.Lexception1:
+   .byte   255                             # @LPStart Encoding = omit
+   .byte   255                             # @TType Encoding = omit
+   .byte   1                               # Call site Encoding = uleb128
+   .uleb128 .Lcst_end1-.Lcst_begin1
+.Lcst_begin1:
+.Lcst_end1:
+   .p2align    2
+   .text
                                         # -- End function
    .def     _ZN3out4main17ha1c9ae0fb8136a1fE;
    .scl    3;

It looks like this difference is introduced in the winehprepare pass.

where this transformation happens:

@@ -241,12 +241,8 @@
     %scevgep2 = getelementptr i8, i8* %color.sroa.0.164.in.3, i64 3
     store i8 -128, i8* %scevgep2, align 1
     %_7.i.i.i.i.3 = add i64 %color.sroa.13.163.3, -4
-    %.not.3 = icmp eq i8 %24, 0
     %scevgep3 = getelementptr i8, i8* %color.sroa.0.164.in.3, i64 4
-    br i1 %.not.3, label %bb4.loopexit.3, label %bb2.i.3
-  
-  bb4.loopexit.3:                                   ; preds = %bb19.3
-    ret void
+    br label %bb2.i.3
   }

The winehprepare pass in llc from llvm-10 has the same behaviour so it could be that this pass is just exposing a bug that happens earlier in the pipeline.

It looks like the standalone version of this test case started panicing back in rust 1.38. My guess is the LLVM11 upgrade caused the initial code to start hitting the broken path.

It looks like rust 1.38 changes some u8 adds to add nuw and this causes causes the problem:

The following patch to the 1.37 ir to make it more like the 1.37 ir is sufficient to trigger the panic.

diff --- main.ll 2020-10-26 12:25:05 -0400 +++ main-1.37-nuw.ll 2020-10-26 12:24:24 -0400 @@ -211,7 +211,7 @@ %color.sroa.13.159.3 = phi i64 [ %53, %bb22.3 ], [ %42, %bb3.i.2 ] %iter1.sroa.0.058.3 = phi i8 [ %44, %bb22.3 ], [ 0, %bb3.i.2 ] %43 = icmp eq i8 %iter1.sroa.0.058.3, -1 - %44 = add i8 %iter1.sroa.0.058.3, 1 + %44 = add nuw i8 %iter1.sroa.0.058.3, 1 %45 = icmp eq i64 %color.sroa.13.159.3, 0 br i1 %45, label %panic, label %bb18.3, !prof !13

Might be the same issue as #74498.

Yeah, it certainly looks related. https://bugs.llvm.org/show_bug.cgi?id=46943 is the upstream bug.

Here's a further reduced version:

const color_sample_max: usize = 2;
const pixel_size: usize  = 4;

#[inline(never)]
fn inner(mut out: &mut [u8])  {

    let mut color = &mut out[..];
    for _ in 0..color_sample_max {
        for b in 0..=255 {
            unsafe {
            if color.len() < 1 { panic!() }
            *color.get_unchecked_mut(0) = 0x80;
            if color.len() < 2 { panic!() }
            *color.get_unchecked_mut(1) = 0x80;
            if color.len() < 3 { panic!() }
            *color.get_unchecked_mut(2) = b;
            *color.get_unchecked_mut(3) = 0x80;
            }
            color = &mut color[pixel_size..];
        }
    }
}


fn main() {
    let mut out = vec![0; color_sample_max * 256 * pixel_size];
    let out = inner(&mut out);
}

I have a patch that fixes (what I believe to be) the underlying LLVM bug; see https://bugs.llvm.org/show_bug.cgi?id=46943 ; I'm working on making a LLVM unit test and then I'll put up a patch for the llvm-devs to review.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SharplEr picture SharplEr  路  3Comments

nikomatsakis picture nikomatsakis  路  3Comments

mcarton picture mcarton  路  3Comments

drewcrawford picture drewcrawford  路  3Comments

pedrohjordao picture pedrohjordao  路  3Comments