Repository navigation
portable simd: -Zmir-opt-level=3 causes LLVM ERROR #98016
Description
Activity
- addedI-crashIssue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics.A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.A-SIMDArea: SIMD (Single Instruction Multiple Data)Area: SIMD (Single Instruction Multiple Data)C-bugCategory: This is a bug.Category: This is a bug.A-mir-optArea: MIR optimizationsArea: MIR optimizationsPG-portable-simdProject group: Portable SIMD (https://github.com/rust-lang/project-portable-simd)Project group: Portable SIMD (https://github.com/rust-lang/project-portable-simd)
on Jun 12, 2022 - changed the title
[-]simd: -Zmir-opt-level=3 causes LLVM ERROR[/-][+]portable simd: -Zmir-opt-level=3 causes LLVM ERROR[/+]on Jun 12, 2022 Due to inlining of
Simd::<u8, 8>::to_array:al@eggy rust % rustc +nightly ./src/test/codegen/simd-wide-sum.rs --edition=2021 -Zmir-opt-level=3 -Zvalidate-mir -Zfuel=simd_wide_sum=46 warning: optimization-fuel-exhausted: Inline Instance { def: Item(WithOptConstParam { did: DefId(2:23390 ~ core[a873]::core_simd::vector::{impl#0}::to_array), const_param_did: None }), substs: [u8, Const { ty: usize, val: Value(Scalar(0x0000000000000008)) }] } into MirSource { instance: Item(WithOptConstParam { did: DefId(0:10 ~ simd_wide_sum[31d5]::wider_reduce_into_iter), const_param_did: None }), promoted: None } warning: 1 warning emitted al@eggy rust % rustc +nightly ./src/test/codegen/simd-wide-sum.rs --edition=2021 -Zmir-opt-level=3 -Zvalidate-mir -Zfuel=simd_wide_sum=47 warning: optimization-fuel-exhausted: Inline Instance { def: Item(WithOptConstParam { did: DefId(2:8403 ~ core[a873]::iter::traits::iterator::Iterator::map), const_param_did: None }), substs: [std::array::IntoIter<u8, 8_usize>, u16, fn(u8) -> u16 {<u16 as std::convert::From<u8>>::from}] } into MirSource { instance: Item(WithOptConstParam { did: DefId(0:10 ~ simd_wide_sum[31d5]::wider_reduce_into_iter), const_param_did: None }), promoted: None } Invalid bitcast %6 = bitcast <8 x i8> %5 to [8 x i8] in function wider_reduce_into_iter LLVM ERROR: Broken function found, compilation aborted! al@eggy rust % rustc +nightly --version --verbose rustc 1.63.0-nightly (99930ac7f 2022-06-11) binary: rustc commit-hash: 99930ac7f8cbb5d9b319b2e2e92794fd6f24f556 commit-date: 2022-06-11 host: x86_64-apple-darwin release: 1.63.0-nightly LLVM version: 14.0.5does the no_mangle attr have done kind of effect? can't check on mobile right now
I think it's more likely the
Simdstruct'srepr(simd)being ignored when performing that field access. cc #27731A slightly simplified example:
#![crate_type = "lib"] #![feature(repr_simd)] #[repr(simd)] pub struct Simd([u8; 8]); fn to_array_inner<T>(x: Simd) -> [u8; 8] { x.0 } pub fn to_array_outer(x: Simd) -> [u8; 8] { to_array_inner::<()>(x) }
It only arises when inlining a generic function (in this case
to_array_inner) that bitcasts arepr(simd).The difference seems to be that
x.0bitcasts a pointer to a vector, while the inlinedto_array_innerbitcasts a vector directly. I suspect that the extra move that happens whento_array_inneris inlined causes vector value to be stored behind a pointer. I can reproduce the crash using just#![crate_type = "lib"] #![feature(repr_simd)] #[repr(simd)] pub struct Simd([u8; 8]); pub fn to_array_outer(x: Simd) -> [u8; 8] { let y = x; y.0 }
to force an extra move. As for why
to_array_innerputs the vector behind a pointer, the default rust abi passes vector types by-ref to ensure that changing target features doesn't change the abi.Reacted by eggyalWith
--emit llvm-ir -Cno-prepopulate-passes -Zverify-llvm-irthat crashes atInvalid bitcast %1 = bitcast <8 x i8> %y to [8 x i8], !dbg !11 LLVM ERROR: Broken module found, compilation aborted! Compiler returned: 101and without
-Zverify-llvm-irit gives the following LLVM ir:define i64 @_ZN7example14to_array_outer17h4eae74749e7c0538E(<8 x i8>* %x) unnamed_addr #0 !dbg !5 { %0 = alloca [8 x i8], align 1 %y = load <8 x i8>, <8 x i8>* %x, align 8, !dbg !10 %1 = bitcast <8 x i8> %y to [8 x i8], !dbg !11 store [8 x i8] %1, [8 x i8]* %0, align 1, !dbg !11 %2 = bitcast [8 x i8]* %0 to i64*, !dbg !13 %3 = load i64, i64* %2, align 1, !dbg !13 ret i64 %3, !dbg !13 }
As for why
to_array_innerputs the vector behind a pointer, the default rust abi passes vector types by-ref to ensure that changing target features doesn't change the abi.It's interesting that the failure (in my example) required
to_array_innerto be generic—that shouldn't affect the ABI of the monomorphized function, should it?Indeed. It shouldn't affect the ABI.
- addedglacierICE tracked in rust-lang/glacier.ICE tracked in rust-lang/glacier.
on Jun 24, 2022 The original no longer crashes since #96451, but #98016 (comment) still does
Triage: The above mentioned example now compiles fine with the latest nightly, I guess #107449 is related. Marking as
E-needs-test.- addedE-needs-testCall for participation: An issue has been fixed and does not reproduce, but no test has been added.Call for participation: An issue has been fixed and does not reproduce, but no test has been added.
on Feb 17, 2023
I tried this code:
code originally from
./src/test/codegen/simd-wide-sum.rsMeta
rustc --version --verbose:When compile with
-Zmir-opt-level=3, there is aLLVM_ERRORwhich does not occur with-Zmir-opt-level=2rustc ./src/test/codegen/simd-wide-sum.rs --edition=2021 -Zmir-opt-level=3 -Zvalidate-mir