llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.3k stars 12.11k forks source link

Crash when trying to compile i32x4 type with VE backend #64420

Closed lenawanel closed 1 year ago

lenawanel commented 1 year ago

compiling the following code with llc:

; ModuleID = 'bugpoint-reduced-simplified.bc'
source_filename = "adler.707c2e002c6e23cc-cgu.0"
target datalayout = "e-m:e-i64:64-n32:64-S128-v64:64:64-v128:64:64-v256:64:64-v512:64:64-v1024:64:64-v2048:64:64-v4096:64:64-v8192:64:64-v16384:64:64"
target triple = "ve-unknown-linux-gnu"

define dso_local void @_ZN5adler4algo5U32X44from17heee8ff6a15a219acE(ptr %_0) unnamed_addr #0 {
start:
  br i1 poison, label %bb7, label %panic3

bb7:                                              ; preds = %start
  store <4 x i32> zeroinitializer, ptr %_0, align 4
  ret void

panic3:                                           ; preds = %start
  unreachable
}

attributes #0 = { "target-features"="+vpu" }

!llvm.ident = !{!0}

!0 = !{!"rustc version 1.73.0-dev"}

crashes with

Do not know how to custom type legalize this operation!
UNREACHABLE executed at /home/lena/GitClone/llvm-project/llvm/lib/Target/VE/VEISelLowering.cpp:1963!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
backtrace

``` Stack dump: 0. Program arguments: ./build/bin/llc /home/lena/test.ll 1. Running pass 'Function Pass Manager' on module '/home/lena/test.ll'. 2. Running pass 'VE DAG->DAG Pattern Instruction Selection' on function '@_ZN5adler4algo5U32X44from17heee8ff6a15a219acE' #0 0x000055ea921280ce llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/lena/GitClone/llvm-project/llvm/lib/Support/Unix/Signals.inc:602:22 #1 0x000055ea9212849f PrintStackTraceSignalHandler(void*) /home/lena/GitClone/llvm-project/llvm/lib/Support/Unix/Signals.inc:675:1 #2 0x000055ea92125b5f llvm::sys::RunSignalHandlers() /home/lena/GitClone/llvm-project/llvm/lib/Support/Signals.cpp:104:20 #3 0x000055ea92127a33 SignalHandler(int) /home/lena/GitClone/llvm-project/llvm/lib/Support/Unix/Signals.inc:413:1 #4 0x00007f6437a4fab0 (/usr/lib/libc.so.6+0x39ab0) #5 0x00007f6437a9f26c (/usr/lib/libc.so.6+0x8926c) #6 0x00007f6437a4fa08 raise (/usr/lib/libc.so.6+0x39a08) #7 0x00007f6437a38538 abort (/usr/lib/libc.so.6+0x22538) #8 0x000055ea9206c7aa bindingsErrorHandler(void*, char const*, bool) /home/lena/GitClone/llvm-project/llvm/lib/Support/ErrorHandling.cpp:221:55 #9 0x000055ea90738f2f llvm::VETargetLowering::ReplaceNodeResults(llvm::SDNode*, llvm::SmallVectorImpl&, llvm::SelectionDAG&) const /home/lena/GitClone/llvm-project/llvm/lib/Target/VE/VEISelLowering.cpp:1960:5 #10 0x000055ea91f68ab5 llvm::DAGTypeLegalizer::CustomLowerNode(llvm::SDNode*, llvm::EVT, bool) /home/lena/GitClone/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:931:27 #11 0x000055ea91f86603 llvm::DAGTypeLegalizer::SplitVectorResult(llvm::SDNode*, unsigned int) /home/lena/GitClone/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp:972:3 #12 0x000055ea91f653ef llvm::DAGTypeLegalizer::run() /home/lena/GitClone/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:283:17 #13 0x000055ea91f69a58 llvm::SelectionDAG::LegalizeTypes() /home/lena/GitClone/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:1059:37 #14 0x000055ea91ed11d8 llvm::SelectionDAGISel::CodeGenAndEmitDAG() /home/lena/GitClone/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:807:36 #15 0x000055ea91ed06b2 llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator, false, true>, llvm::ilist_iterator, false, true>, bool&) /home/lena/GitClone/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:702:1 #16 0x000055ea91ed63b2 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) /home/lena/GitClone/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1705:33 #17 0x000055ea91ecf0df llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) /home/lena/GitClone/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:483:7 #18 0x000055ea90726e1a (anonymous namespace)::VEDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) /home/lena/GitClone/llvm-project/llvm/lib/Target/VE/VEISelDAGToDAG.cpp:46:3 #19 0x000055ea90f96169 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) /home/lena/GitClone/llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp:91:33 #20 0x000055ea917742d8 llvm::FPPassManager::runOnFunction(llvm::Function&) /home/lena/GitClone/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1435:20 #21 0x000055ea917745aa llvm::FPPassManager::runOnModule(llvm::Module&) /home/lena/GitClone/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1481:13 #22 0x000055ea917749ff (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) /home/lena/GitClone/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1550:20 #23 0x000055ea9176f608 llvm::legacy::PassManagerImpl::run(llvm::Module&) /home/lena/GitClone/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:535:13 #24 0x000055ea917752d1 llvm::legacy::PassManager::run(llvm::Module&) /home/lena/GitClone/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1678:1 #25 0x000055ea9016cb4e compileModule(char**, llvm::LLVMContext&) /home/lena/GitClone/llvm-project/llvm/tools/llc/llc.cpp:754:66 #26 0x000055ea9016a37a main /home/lena/GitClone/llvm-project/llvm/tools/llc/llc.cpp:416:35 #27 0x00007f6437a39850 (/usr/lib/libc.so.6+0x23850) #28 0x00007f6437a3990a __libc_start_main (/usr/lib/libc.so.6+0x2390a) #29 0x000055ea90168f25 _start (./build/bin/llc+0x592f25) [1] 1802379 IOT instruction (core dumped) ./build/bin/llc ~/test.ll ```

this issue was encountered while trying to port rust to the NEC Vector Engine and doesn't occur when using SX-Aurora TSUBASA Research's llvm fork.

this requires llvm to be built with the VE backend enabled. (-DLLVM_TARGETS_TO_BUILD="X86;VE")

tested on commit 16a0fc2bb81f1d66ff66f08053e45d8857afd66d.

efocht commented 1 year ago

I'm sorry, but the VE backend doesn't handle the fixed length SIMD type vectors from LLVM-IR. It needs VP intrinsics like mentioned in https://llvm.org/docs/Proposals/VectorPredication.html

lenawanel commented 1 year ago

are there plans to support them? currently rustc uses fixed length vectors to avoid memcpy for small integer arrays and clang emits them when using ve intrinsics. The second occurrence may be superseded by VP intrinsics, but the first most likely won't, and going back to using memcpy in rustc will worsen codegen.

bjorn3 commented 1 year ago

The unstable portable simd support of rust also uses fixed length vectors.

kaz7 commented 1 year ago

Hi @lenawanel , thank you for the informing problem for us. I have a similar error if I run llc like below.

$ ./build-debug/bin/llc -mtriple=ve tp.ll -debug
...
Legalizing node: t15: v256i1 = VEISD::VEC_BROADCAST Constant:i32<-1>, Constant:i32<256>
Analyzing result type: v256i1
Split node result: t15: v256i1 = VEISD::VEC_BROADCAST Constant:i32<-1>, Constant:i32<256>

t15: v256i1 = VEISD::VEC_BROADCAST Constant:i32<-1>, Constant:i32<256>
Do not know how to custom type legalize this operation!
UNREACHABLE executed at /home/jam/llvm-upstream/llvm-project/llvm/lib/Target/VE/VEISelLowering.cpp:1963!
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.

Our implementation has following two problems.

  1. The llc for VE requires -mattr=+vpu flag to support vector registers.
  2. VP part is not upstreamed completely.

If I use -mattr=+vpu flag, I get following errors slightly differet.

$ ./build-debug/bin/llc -mtriple=ve tp.ll -debug -mattr=+vpu
...
Legalizing node: t18: ch = VEISD::VVP_STORE t0, t2, t4, Constant:i64<4>, t15, t17
Analyzing result type: ch
Legal result type
Analyzing operand: t0: ch,glue = EntryToken
Legal operand
Analyzing operand: t2: v4i32 = BUILD_VECTOR Constant:i32<0>, Constant:i32<0>, Constant:i32<0>, Constant:i32<0>
Widen node operand 1: t18: ch = VEISD::VVP_STORE t0, t2, t4, Constant:i64<4>, t15, t17

::LowerOperationt18: ch = <<Unknown Node #469>> t0, t2, t4, Constant:i64<4>, t15, t17::LowerOperation_VVPt18: ch = <<Unknown Node #469>> t0, t2, t4, Constant:i64<4>, t15, t17llc: /home/jam/llvm-upstream/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp:648: void llvm::DAGTypeLegalizer::ReplaceValueWith(llvm::SDValue, llvm::SDValue): Assertion `From.getNode() != To.getNode() && "Potential legalization loop!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.

This error caused by 2nd reason, "VP part is not upstreamed completely."

I'll investigate it this week to see what I can do for this.

kaz7 commented 1 year ago

Just an update, we have following 3 problems actually. I've fixed 1 and 2. Both are merged upstream. I'm working on 3 now.

  1. llvm for VE vectorize code even if the compiler is not in vectorize mode.
  2. llvm for VE disable vector mode by default.
  3. vectorizer of llvm for VE is not completely upstreamed yet.

So, if you want to run your TP under scalar mode, it works fine like below now.

$ ./build/bin/llc -mtriple=ve tp.ll -mattr=-vpu  # need -vpu to use scalar mode now.
$
lenawanel commented 1 year ago

alright, thank you very much. I'm closing the issue now, since you gave a solution.

kaz7 commented 1 year ago

@lenawanel -san, I've fixed 3rd problem at 2e2395651e4327eec820424f9d647b856745aeb4 and merged it also.

$ ./build/bin/llc -mtriple=ve tp.ll
$ cat tp.s
...
# %bb.0:                                # %start
        or %s1, 0, (0)1
        brne.w 0, %s1, .LBB0_2
# %bb.1:                                # %bb7
        lea %s1, 256
        lvl %s1
        vbrd %v0, 0
        or %s1, 4, (0)1
        lvl %s1
        vstl %v0, 4, %s0
        b.l.t (, %s10)

Need to optimize it, though. I'll improve it to broadcast to v4i32 instead of v256i32 and use scalar code if the length is not long enough.