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

Upgrade to LLVM11 caused a codegen regression on Windows #78283

Closed
jrmuizel opened this issue Oct 23, 2020 · 23 comments
Closed

Upgrade to LLVM11 caused a codegen regression on Windows #78283

jrmuizel opened this issue Oct 23, 2020 · 23 comments
Assignees
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness O-windows-msvc Toolchain: MSVC, Operating system: Windows P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@jrmuizel
Copy link
Contributor

jrmuizel commented Oct 23, 2020

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.

@jonas-schievink jonas-schievink added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 23, 2020
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Oct 23, 2020
@jonas-schievink jonas-schievink added the regression-from-stable-to-stable Performance or correctness regression from one stable version to another. label Oct 23, 2020
@Mark-Simulacrum
Copy link
Member

cc @rust-lang/wg-llvm

@jrmuizel jrmuizel changed the title Upgrade to LLVM11 caused a codegen regression Upgrade to LLVM11 caused a codegen regression on Windows Oct 23, 2020
@wesleywiser wesleywiser added P-critical Critical priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Oct 23, 2020
@jrmuizel
Copy link
Contributor Author

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

@jrmuizel
Copy link
Contributor Author

jrmuizel commented Oct 23, 2020

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();
}

@mati865
Copy link
Contributor

mati865 commented Oct 23, 2020

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

@rustbot
Copy link
Collaborator

rustbot commented Oct 23, 2020

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.

@rustbot rustbot added the O-windows-msvc Toolchain: MSVC, Operating system: Windows label Oct 23, 2020
@jrmuizel
Copy link
Contributor Author

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

@jrmuizel
Copy link
Contributor Author

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.

@MSxDOS
Copy link

MSxDOS commented Oct 23, 2020

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

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

@jrmuizel
Copy link
Contributor Author

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

@jrmuizel
Copy link
Contributor Author

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

@jrmuizel
Copy link
Contributor Author

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;

@jrmuizel
Copy link
Contributor Author

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

@jrmuizel
Copy link
Contributor Author

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
   }

@jrmuizel
Copy link
Contributor Author

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.

@jrmuizel
Copy link
Contributor Author

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.

@jrmuizel
Copy link
Contributor Author

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.

 --- 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

@nikic
Copy link
Contributor

nikic commented Oct 26, 2020

Might be the same issue as #74498.

@jrmuizel
Copy link
Contributor Author

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

@jrmuizel
Copy link
Contributor Author

jrmuizel commented Nov 1, 2020

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);
}

@pnkfelix pnkfelix self-assigned this Nov 5, 2020
@pnkfelix
Copy link
Member

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.

@apiraino apiraino added P-high High priority and removed P-critical Critical priority labels Dec 31, 2020
@jrmuizel
Copy link
Contributor Author

jrmuizel commented Mar 5, 2021

This should be fixed now that #81451 has been merged.

@nikic
Copy link
Contributor

nikic commented Mar 6, 2021

@jrmuizel Would you be able to confirm that this is indeed fixed now? I don't have a Windows system to test.

@steveklabnik
Copy link
Member

steveklabnik commented Aug 5, 2021

So, I believe I hit this bug in some other code today (In an older nightly, fixed on master, no worries about a new regression popping up). However, I can confirm that the literal bug here has been fixed: #78283 (comment)

(note: 2021-03-04 is using llvm 11, 2021-03-05 is using llvm 12)

C:\Users\steve\Documents\tmp\is-this-ub> cargo +nightly-2021-03-04 rustc --release -- -C codegen-units=1
    Finished release [optimized] target(s) in 0.01s
C:\Users\steve\Documents\tmp\is-this-ub> .\target\release\is-this-ub.exe
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', src\main.rs:9:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
C:\Users\steve\Documents\tmp\is-this-ub> cargo +nightly-2021-03-05 rustc --release -- -C codegen-units=1
   Compiling is-this-ub v0.1.0 (C:\Users\steve\Documents\tmp\is-this-ub)
    Finished release [optimized] target(s) in 0.68s
C:\Users\steve\Documents\tmp\is-this-ub> .\target\release\is-this-ub.exe
C:\Users\steve\Documents\tmp\is-this-ub> rustc --version
rustc 1.52.1 (9bc8c42bb 2021-05-09)
C:\Users\steve\Documents\tmp\is-this-ub> cargo rustc --release -- -C codegen-units=1
   Compiling is-this-ub v0.1.0 (C:\Users\steve\Documents\tmp\is-this-ub)
    Finished release [optimized] target(s) in 0.94s
C:\Users\steve\Documents\tmp\is-this-ub> .\target\release\is-this-ub.exe
C:\Users\steve\Documents\tmp\is-this-ub>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness O-windows-msvc Toolchain: MSVC, Operating system: Windows P-high High priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests