Closed workingjubilee closed 3 years ago
During my reduction, this nice error popped up which is, at least I think so, the real error message behind this ICE:
error[E0511]: invalid monomorphization of `simd_reduce_mul_ordered` intrinsic: expected return type `i8` (element of input `Simd<i8, 16_usize>`), found `i32`
--> src\main.rs:37:26
|
37 | let a = unsafe { crate::simd_reduce_mul_ordered(crate::Simd::<i8, 16>::from_array(x), 1) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
I post my code in ~10 Minutes, after cleaning it up
This ICE is very fragile, even removing the biteq
mod makes that this ICE will not appear anymore... Anyway, here it is:
#![feature(platform_intrinsics, repr_simd)]
extern "platform-intrinsic" {
pub(crate) fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
}
#[repr(simd)]
pub struct Simd<T, const LANES: usize>([T; LANES]);
impl<T, const LANES: usize> Simd<T, LANES> {
pub fn new(array: [T; LANES]) -> Self {
Self(array)
}
}
mod biteq {
pub trait BitEq {
fn biteq(&self, other: &Self) -> bool;
}
impl BitEq for i8 {
fn biteq(&self, _: &Self) -> bool {
false
}
}
pub struct BitEqWrapper<T>(pub T);
impl<T: BitEq> PartialEq for BitEqWrapper<T> {
fn eq(&self, _: &Self) -> bool {
false
}
}
}
fn main() {
pub fn implementation(x: [i8; 16]) {
use crate::biteq::BitEqWrapper;
let a = unsafe { crate::simd_reduce_mul_ordered(crate::Simd::<i8, 16>::new(x), 1) };
let b = 0;
let left = BitEqWrapper(a);
let right = BitEqWrapper(b);
let _ = left == right;
}
implementation([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
}
cargo build --release
is needed. But it isn't limited to windows, it also crashes under linux:
based on the error message:
@rustbot modify labels: I-crash I-monomorphization
rustc: llvm/include/llvm/Support/Casting.h:104: static bool llvm::isa_impl_cl<To, const From*>::doit(const From*) [with To = llvm::PoisonValue; From = llvm::Constant]: Assertion `Val && "isa<> used on a null pointer"' failed.
is the assertion being triggered (with @hellow554's minimization)
I do not understand how that is finding a null pointer or how it is getting a poison value out of this.
Thank you for your work on the minimization though! I just... is it because it starts as an array and then it tries to constant fold that? And why only vectors of 8-bit values? The test is the same for larger ones.
As a note, this crash only reproduces with cargo build
(or similar, such as cargo rustc
) at the moment, it doesn't when rustc
is invoked directly.
I can repro with this:
curl -sS https://gist.githubusercontent.com/eddyb/08ea4736082d9b2326a984c4cb828a08/raw/6a2b96cd8422950fa2b160e518671df66965a863/issue-88769-min.rs | rustc -O -
But only on rustc 1.57.0-nightly (fdf65053e 2021-09-07)
, not rustc 1.56.0-nightly (0035d9dce 2021-08-16)
which I had before rustup update nightly
, so it must be relatively recent (though I may have been pre-LLVM 13, which wouldn't narrow it down much).
Running with -Z verify-llvm-ir
doesn't result in a verifier error, so assume that's still working, this must be a LLVM bug.
These series of steps reproduce the crash outside rustc
, which should allow minimizing the LLVM IR with e.g. bugpoint
:
mkdir issue-88769
cd issue-88769
curl -sSO https://gist.githubusercontent.com/eddyb/08ea4736082d9b2326a984c4cb828a08/raw/6a2b96cd8422950fa2b160e518671df66965a863/issue-88769-min.rs
rustup toolchain install nightly-2021-09-08 -c llvm-tools-preview
# This will crash - ignore the crash and keep going, `-C save-temps` works.
rustc +nightly-2021-09-08 issue-88769-min.rs -O -C save-temps
# This reproduces the crash using the `.bc` from `-C save-temps`.
~/.rustup/toolchains/nightly-2021-09-08-x*64*/lib/rustlib/x*64*/bin/opt -O3 issue-88769-min.*-cgu.3.rcgu.no-opt.bc > opt.bc
Sadly we don't ship bugpoint
with llvm-tools-preview
, but if you have it installed:
bugpoint --opt-command=$(echo ~/.rustup/toolchains/nightly-2021-09-08-x*64*/lib/rustlib/x*64*/bin/opt) -O3 issue-88769-min.*-cgu.3.rcgu.no-opt.bc
After a lot of crashes, it ends in:
*** Found crashing pass: -early-cse-memssa
Emitted bitcode to 'bugpoint-reduced-simplified.bc'
*** You can reproduce the problem with: opt bugpoint-reduced-simplified.bc -early-cse-memssa
Running llvm-dis
on that file gives:
; ModuleID = 'bugpoint-reduced-simplified.bc'
source_filename = "issue_88769_min.61742fa9-cgu.3"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define dso_local void @_ZN15issue_88769_min4main17h9167823f857de443E() unnamed_addr #0 {
%1 = call i8 @llvm.vector.reduce.mul.v16i8(<16 x i8> bitcast (<1 x i128> <i128 20011376718272490338853433276725592320> to <16 x i8>))
store i8 %1, i8* undef, align 1
ret void
}
; Function Attrs: nofree nosync nounwind readnone willreturn
declare i8 @llvm.vector.reduce.mul.v16i8(<16 x i8>) #1
attributes #0 = { "target-cpu"="x86-64" }
attributes #1 = { nofree nosync nounwind readnone willreturn }
!llvm.module.flags = !{!0}
!0 = !{i32 2, !"RtLibUseGOT", i32 1}
cc @nikic (opt -early-cse-memssa
on the above LLVM IR reduction reproduces the crash)
Just to confirm: crash repros on cargo +nightly-2021-08-22 build --release
but not the nightly before that, so I believe you can use
mkdir issue-88769
cd issue-88769
curl -sSO https://gist.githubusercontent.com/eddyb/08ea4736082d9b2326a984c4cb828a08/raw/6a2b96cd8422950fa2b160e518671df66965a863/issue-88769-min.rs
rustup toolchain install nightly-2021-08-22 -c llvm-tools-preview
# This will crash - ignore the crash and keep going, `-C save-temps` works.
rustc +nightly-2021-08-22 issue-88769-min.rs -O -C save-temps
# This reproduces the crash using the `.bc` from `-C save-temps`.
~/.rustup/toolchains/nightly-2021-08-22-x*64*/lib/rustlib/x*64*/bin/opt -O3 issue-88769-min.*-cgu.3.rcgu.no-opt.bc > opt.bc
@eddyb Thanks for the reduction, upstream issue filed in https://bugs.llvm.org/show_bug.cgi?id=51811.
Should be fixed by #88765.
Okay, trying to compile our test still appears to crash rustc 1.57.0-nightly (51e514c0f 2021-09-12)
, which appears to include the submodule update.
The LLVM-level repro and hellow's minimization both seem to be fixed.
The reduction above now works on nightly, but portable-simd still fails on the same test with the same error as the original report. I'm guessing the bug is only partially fixed in LLVM?
I can confirm that my reduced testcase is indeed fixed, but portable-simd still fails on linux and windows. I'll try it again :)
It seems not to be a llvm issue anymore, but a rust (jobserver) one? It panicks with a SIGTRAP under linux, here's the backtrace:
thread1:
[#0] 0x7ffff7d0bfe9 → __futex_abstimed_wait_common64(private=0x0, cancel=0x1, abstime=0x0, op=0x189, expected=0x0, futex_word=0x5555565fddf8)
[#1] 0x7ffff7d0bfe9 → __futex_abstimed_wait_common(cancel=0x1, private=0x0, abstime=0x0, clockid=0x0, expected=0x0, futex_word=0x5555565fddf8)
[#2] 0x7ffff7d0bfe9 → __GI___futex_abstimed_wait_cancelable64(futex_word=0x5555565fddf8, expected=0x0, clockid=0x0, abstime=0x0, private=0x0)
[#3] 0x7ffff7d0e920 → __pthread_cond_wait_common(abstime=0x0, clockid=0x0, mutex=0x5555566dab50, cond=0x5555565fddd0)
[#4] 0x7ffff7d0e920 → ___pthread_cond_wait(cond=0x5555565fddd0, mutex=0x5555566dab50)
[#5] 0x555555ecec31 → jobserver::HelperState::for_each_request()
[#6] 0x555555ecff1c → std::sys_common::backtrace::__rust_begin_short_backtrace()
[#7] 0x555555ecf81a → core::ops::function::FnOnce::call_once{{vtable.shim}}()
[#8] 0x555555f09fc3 → alloc::boxed::{impl#44}::call_once<(), dyn core::ops::function::FnOnce<(), Output=()>, alloc::alloc::Global>()
[#9] 0x555555f09fc3 → alloc::boxed::{impl#44}::call_once<(), alloc::boxed::Box<dyn core::ops::function::FnOnce<(), Output=()>, alloc::alloc::Global>, alloc::alloc::Global>()
thread2:
#0 __futex_abstimed_wait_common64 (private=0x565f7170, cancel=0x1, abstime=0x7fffffff82e8, op=0x89, expected=0x0, futex_word=0x5555565fddfc) at futex-internal.c:57
57 in futex-internal.c
gef➤ bt
#0 __futex_abstimed_wait_common64 (private=0x565f7170, cancel=0x1, abstime=0x7fffffff82e8, op=0x89, expected=0x0, futex_word=0x5555565fddfc) at futex-internal.c:57
#1 __futex_abstimed_wait_common (cancel=0x1, private=0x565f7170, abstime=0x7fffffff82e8, clockid=0x7fff, expected=0x0, futex_word=0x5555565fddfc) at futex-internal.c:87
#2 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x5555565fddfc, expected=expected@entry=0x0, clockid=clockid@entry=0x1, abstime=abstime@entry=0x7fffffff82e8, private=private@entry=0x0) at futex-internal.c:139
#3 0x00007ffff7d0ed7e in __pthread_cond_wait_common (abstime=0x7fffffff82e8, clockid=0x1, mutex=0x5555566dab50, cond=0x5555565fddd0) at pthread_cond_wait.c:504
#4 ___pthread_cond_timedwait64 (cond=0x5555565fddd0, mutex=0x5555566dab50, abstime=0x7fffffff82e8) at pthread_cond_wait.c:653
#5 0x0000555555f04105 in std::sys::unix::condvar::Condvar::wait_timeout () at library/std/src/sys/unix/condvar.rs:114
#6 0x0000555555ecd9a2 in jobserver::imp::Helper::join ()
#7 0x0000555555ece9c3 in <jobserver::HelperThread as core::ops::drop::Drop>::drop ()
#8 0x00005555559cee07 in <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once ()
#9 0x000055555575619c in crossbeam_utils::thread::scope ()
#10 0x000055555568479c in cargo::core::compiler::job_queue::JobQueue::execute ()
#11 0x000055555562a0c4 in cargo::core::compiler::context::Context::compile ()
#12 0x000055555595361d in cargo::ops::cargo_compile::compile_ws ()
#13 0x0000555555953356 in cargo::ops::cargo_compile::compile ()
#14 0x00005555559a6c3e in cargo::ops::cargo_test::run_tests ()
#15 0x00005555555d3c13 in cargo::commands::test::exec ()
#16 0x00005555555c5cbd in cargo::cli::main ()
#17 0x00005555555ee715 in cargo::main ()
#18 0x00005555555b6813 in std::sys_common::backtrace::__rust_begin_short_backtrace ()
#19 0x00005555555e6eb9 in std::rt::lang_start::{{closure}} ()
#20 0x0000555555f0283a in core::ops::function::impls::{impl#2}::call_once<(), (dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> () at /rustc/9bb77da74dac4768489127d21e32db19b59ada5b/library/core/src/ops/function.rs:259
#21 std::panicking::try::do_call<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> () at library/std/src/panicking.rs:403
#22 std::panicking::try<i32, &(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe)> () at library/std/src/panicking.rs:367
#23 std::panic::catch_unwind<&(dyn core::ops::function::Fn<(), Output=i32> + core::marker::Sync + core::panic::unwind_safe::RefUnwindSafe), i32> () at library/std/src/panic.rs:129
#24 std::rt::lang_start_internal::{closure#2} () at library/std/src/rt.rs:45
#25 std::panicking::try::do_call<std::rt::lang_start_internal::{closure#2}, isize> () at library/std/src/panicking.rs:403
#26 std::panicking::try<isize, std::rt::lang_start_internal::{closure#2}> () at library/std/src/panicking.rs:367
#27 std::panic::catch_unwind<std::rt::lang_start_internal::{closure#2}, isize> () at library/std/src/panic.rs:129
#28 std::rt::lang_start_internal () at library/std/src/rt.rs:45
#29 0x00005555555f0902 in main ()
MCVE:
#![feature(platform_intrinsics, repr_simd)]
#[repr(simd)]
pub struct Simd<T, const LANES: usize>([T; LANES]);
impl<const LANES: usize> Simd<i8, LANES> {
pub fn horizontal_product(self) -> i8 {
extern "platform-intrinsic" {
fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
}
unsafe { simd_reduce_mul_ordered(self, 1) }
}
}
fn cb(x: [i8; 16]) {
let a: i8 = Simd(x).horizontal_product();
let _ = a.to_string();
}
fn main() {
let x = [0; 16];
let _ = std::panic::catch_unwind(|| cb(x));
}
Regressed in db002a06ae9154a35d410550bc5132df883d7baa so it is an llvm issue after all?
cc #87570 @nikic
Reduced:
RUN: llc < %s
define i8 @test(i128 %arg) {
%vec = bitcast i128 %arg to <16 x i8>
%red = tail call i8 @llvm.vector.reduce.mul.v16i8(<16 x i8> %vec)
ret i8 %red
}
declare i8 @llvm.vector.reduce.mul.v16i8(<16 x i8>)
Upstream report: https://bugs.llvm.org/show_bug.cgi?id=51858
What appears to be a fix? is now present upstream at https://github.com/llvm/llvm-project/commit/dcba99418438ec1d624ad207674234bd2e9e3394
Should be fixed by #89130 -- unless there's a third bug?
I re-ran a test and it appears fixed, thanks! I'll wait for @workingjubilee to confirm.
Ditto! No third bug this time. 😅 Thank you so much!
Hello, we have encountered an issue in the portable-simd CI unique to tests on our
i8xN
andu8xN
types on x86_64. It emits a SIGTRAP, or sometimes a SIGILL, or on Windows, a STATUS_ACCESS_VIOLATION! How exciting! I can reproduce this locally. Our other tests do not do this, and it only happens in--release
, so I suspect this is a miscompilation by LLVM 13 inappropriately optimizing something. Full command to repro:cargo test --release --test [iu]8_ops
I am going to try to minimize this from "literally the entire test suite" but I might take a bit. The issue became apparent about 7 days ago. Tests were passing about 20~30 days ago (August 8~18) judging by the last green in https://github.com/rust-lang/portable-simd/pull/155. I believe the time frame is correct for this to have been due to https://github.com/rust-lang/rust/pull/87570
More minutiae
RUSTFLAGS="-Copt-level=1"
passes with the above tests.RUSTFLAGS="-Copt-level=2"
crashes with them.Version it worked on
It most recently worked on: Rust 1.56 nightly (2021-07-17)
Version with regression
rustc --version --verbose
:but it also happened on rustc 1.57.0-nightly 2021-09-01
Sample Crash