rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.35k stars 12.59k forks source link

LLVM Assertion in autovectorization when compiling with release + overflow-checks since 1.73 #120813

Closed DavidBJaffe closed 7 months ago

DavidBJaffe commented 8 months ago

Using Rust 1.76.0 on an Apple M1 Pro with OSX 14.3, using cargo b with opt-level = 3:

fn main() {
    let mut slobber = Vec::<([u8; 52], [u8; 16], usize)>::new();
    slobber.push(([0; 52], [0; 16], 0));
    let mut dels = Vec::<([u8; 16], [u8; 10], i8)>::new();
    let i = 0;
    while i < slobber.len() {
        let j = slobber.len();
        let mut counts = Vec::<(usize, [u8; 16], usize)>::new();
        let mut k = i;
        while k < j {
            let l = slobber.len();
            counts.push((0, [0; 16], 0));
            k = l;
        }
        for u in 1..counts.len() {
            let (b1, b2) = (counts[0].1, counts[u].1);
            let mut diffs = 0;
            for m in 0..16 {
                if b1[m] != b2[m] {
                    diffs += 1;
                }
            }
            if diffs <= 0 {
                dels.push(([0; 16], [0; 10], 0));
            }
        }
    }
}

this happens

mac% cargo b
   Compiling bugsy v0.0.1 (/Users/davidjaffe/repos/infinimmune/bugsy)
error: could not compile `bugsy` (bin "bugsy")

Caused by:
  process didn't exit successfully: `/Users/davidjaffe/.rustup/toolchains/1.76.0-aarch64-apple-darwin/bin/rustc --crate-name bugsy src/main.rs --error-format=json --json=diagnostic-rendered-ansi,artifacts,future-incompat --diagnostic-width=100 --crate-type bin --emit=dep-info,link -C opt-level=3 -C embed-bitcode=no -C debuginfo=2 -C split-debuginfo=unpacked -C debug-assertions=on -C metadata=188901b3f11ecd49 -C extra-filename=-188901b3f11ecd49 --out-dir /Users/davidjaffe/repos/infinimmune/bugsy/target/debug/deps -C incremental=/Users/davidjaffe/repos/infinimmune/bugsy/target/debug/incremental -L dependency=/Users/davidjaffe/repos/infinimmune/bugsy/target/debug/deps` (signal: 5, SIGTRAP: trace/breakpoint trap)

The error depends on the optimization level and overflow checking.

saethlin commented 8 months ago

This is an LLVM assertion that can be hit by compiling for the aarch64-unknown-linux-gnu as well. I suspect any aarch64 target would hit it.

The regression is in nightly-2023-08-09, which is when https://github.com/rust-lang/rust/issues/114048, the LLVM 17 update landed.

#5  0x00007dc16fedbd46 in __assert_fail (
    assertion=0x7dc167ca4fce <.L.str.95> "VT.isVector() == N1.getValueType().isVector() && \"TRUNCATE result type type should be vector iff the operand \" \"type is vector!\"", 
    file=0x7dc167e993bd <str.6.llvm> "/checkout/src/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp", line=5734, 
    function=0x7dc1672a701b <.L__PRETTY_FUNCTION__._ZN4llvm12SelectionDAG7getNodeEjRKNS_5SDLocENS_3EVTENS_7SDValueENS_11SDNodeFlagsE> "SDValue llvm::SelectionDAG::getNode(unsigned int, const SDLoc &, EVT, SDValue, const SDNodeFlags)") at assert.c:103
#6  0x00007dc16ecf7219 in llvm::SelectionDAG::getNode(unsigned int, llvm::SDLoc const&, llvm::EVT, llvm::SDValue, llvm::SDNodeFlags) [clone .cold.0] () from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#7  0x00007dc16e070915 in llvm::SelectionDAG::getZExtOrTrunc(llvm::SDValue, llvm::SDLoc const&, llvm::EVT) ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#8  0x00007dc16ca33838 in llvm::AArch64TargetLowering::ReplaceBITCASTResults(llvm::SDNode*, llvm::SmallVectorImpl<llvm::SDValue>&, llvm::SelectionDAG&) const ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#9  0x00007dc16ece7e31 in llvm::DAGTypeLegalizer::PromoteIntegerResult(llvm::SDNode*, unsigned int) [clone .cold.0] ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#10 0x00007dc16de03705 in llvm::DAGTypeLegalizer::run() ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#11 0x00007dc16e2812c9 in llvm::SelectionDAG::LegalizeTypes() ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#12 0x00007dc16e2819ca in llvm::SelectionDAGISel::CodeGenAndEmitDAG() ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#13 0x00007dc16e48aa1a in llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#14 0x00007dc16e1461f9 in llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#15 0x00007dc16de332c0 in llvm::MachineFunctionPass::runOnFunction(llvm::Function&) ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#16 0x00007dc16e24a4be in llvm::FPPassManager::runOnFunction(llvm::Function&) ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#17 0x00007dc16e2493b2 in llvm::FPPassManager::runOnModule(llvm::Module&) ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#18 0x00007dc16e4f957a in llvm::legacy::PassManagerImpl::run(llvm::Module&) ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/libLLVM-17-rust-1.78.0-nightly.so
#19 0x00007dc171362893 in LLVMRustWriteOutputFile ()
   from /home/ben/rust-master/build/x86_64-unknown-linux-gnu/stage1/lib/librustc_driver-0bac2e639c27cdd1.so
DianQK commented 7 months ago

A reduced case:

target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-gnu"

define void @foo(ptr %0, <16 x i1> %1) {
bb1.i:
  %.bc = bitcast <16 x i1> %1 to <2 x i8>
  %.extract100 = extractelement <2 x i8> %.bc, i64 0
  %_47 = icmp eq i8 %.extract100, 0
  br i1 %_47, label %bb20, label %bb23

bb20:                                             ; preds = %bb1.i
  store <16 x i8> zeroinitializer, ptr %0, align 1
  br label %bb23

bb23:                                             ; preds = %bb20, %bb1.i
  ret void
}

https://llvm.godbolt.org/z/narrKadhK

Upstream issue: https://github.com/llvm/llvm-project/issues/81216

(I'm on vacation, and I'm not familiar with it. So I won't be assigning it to myself for a while. :) )

apiraino commented 7 months ago

WG-prioritization assigning priority (Zulip discussion).

@rustbot label -I-prioritize +P-high

nikic commented 7 months ago

Should be fixed in beta & nightly.