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

[WASM] Vector Multiplication Crash for SIMD128 #61780

Closed
HazyFish opened this issue Mar 28, 2023 · 5 comments
Closed

[WASM] Vector Multiplication Crash for SIMD128 #61780

HazyFish opened this issue Mar 28, 2023 · 5 comments
Assignees

Comments

@HazyFish
Copy link
Contributor

Description

The following code targeting wasm32 or wasm64 with simd128 feature crashes LLC with assertion error (LaneBits == 64 || Val >= -(1ll << (LaneBits - 1))) && "Unexpected out of bounds negative value" failed.

Minimal Repoduction

https://godbolt.org/z/fdvE7jqcd

Code

define void @f(ptr %0, ptr %pr) {
BB:
  %v0 = load <4 x i32>, ptr %0
  %v1 = icmp ugt <4 x i32> %v0, <i32 0, i32 1, i32 2, i32 3>
  %v2 = zext <4 x i1> %v1 to <4 x i8>
  %v3 = ashr <4 x i8> <i8 16, i8 16, i8 16, i8 16>, %v2
  %v4 = mul <4 x i8> %v3, %v3
  store <4 x i8> %v4, ptr %pr
  ret void
}

Stack Trace

llc: /home/henry/IRFuzzer/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp:2151: llvm::SDValue llvm::WebAssemblyTargetLowering::LowerBUILD_VECTOR(llvm::SDValue, llvm::SelectionDAG &) const: Assertion `(LaneBits == 64 || Val >= -(1ll << (LaneBits - 1))) && "Unexpected out of bounds negative value"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: ./llvm-project/build-debug/bin/llc --mtriple=wasm32 --mattr=+simd128 ./tmp/crash-reports/2.ll
1.	Running pass 'Function Pass Manager' on module './tmp/crash-reports/2.ll'.
2.	Running pass 'WebAssembly Instruction Selection' on function '@f'
 #0 0x00007ffb3e69969d llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) /home/henry/IRFuzzer/llvm-project/llvm/lib/Support/Unix/Signals.inc:565:11
 #1 0x00007ffb3e699b2b PrintStackTraceSignalHandler(void*) /home/henry/IRFuzzer/llvm-project/llvm/lib/Support/Unix/Signals.inc:639:1
 #2 0x00007ffb3e697db6 llvm::sys::RunSignalHandlers() /home/henry/IRFuzzer/llvm-project/llvm/lib/Support/Signals.cpp:104:5
 #3 0x00007ffb3e69a345 SignalHandler(int) /home/henry/IRFuzzer/llvm-project/llvm/lib/Support/Unix/Signals.inc:410:1
 #4 0x00007ffb3de98520 (/lib/x86_64-linux-gnu/libc.so.6+0x42520)
 #5 0x00007ffb3deeca7c pthread_kill (/lib/x86_64-linux-gnu/libc.so.6+0x96a7c)
 #6 0x00007ffb3de98476 gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x42476)
 #7 0x00007ffb3de7e7f3 abort (/lib/x86_64-linux-gnu/libc.so.6+0x287f3)
 #8 0x00007ffb3de7e71b (/lib/x86_64-linux-gnu/libc.so.6+0x2871b)
 #9 0x00007ffb3de8fe96 (/lib/x86_64-linux-gnu/libc.so.6+0x39e96)
#10 0x00007ffb46a443a0 llvm::WebAssemblyTargetLowering::LowerBUILD_VECTOR(llvm::SDValue, llvm::SelectionDAG&) const /home/henry/IRFuzzer/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp:2152:13
#11 0x00007ffb46a406a8 llvm::WebAssemblyTargetLowering::LowerOperation(llvm::SDValue, llvm::SelectionDAG&) const /home/henry/IRFuzzer/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp:1427:12
#12 0x00007ffb42d924ad (anonymous namespace)::SelectionDAGLegalize::LegalizeOp(llvm::SDNode*) /home/henry/IRFuzzer/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1294:29
#13 0x00007ffb42d90ba4 llvm::SelectionDAG::Legalize() /home/henry/IRFuzzer/llvm-project/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:5130:13
#14 0x00007ffb43001a75 llvm::SelectionDAGISel::CodeGenAndEmitDAG() /home/henry/IRFuzzer/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:904:3
#15 0x00007ffb430008fd llvm::SelectionDAGISel::SelectBasicBlock(llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void>, false, true>, llvm::ilist_iterator<llvm::ilist_detail::node_options<llvm::Instruction, true, false, void>, false, true>, bool&) /home/henry/IRFuzzer/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:700:1
#16 0x00007ffb4300038e llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) /home/henry/IRFuzzer/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1638:11
#17 0x00007ffb42ffd8c0 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) /home/henry/IRFuzzer/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:480:3
#18 0x00007ffb46a302ca (anonymous namespace)::WebAssemblyDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) /home/henry/IRFuzzer/llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp:60:5
#19 0x00007ffb41f5d9c5 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) /home/henry/IRFuzzer/llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp:91:8
#20 0x00007ffb3f0e4486 llvm::FPPassManager::runOnFunction(llvm::Function&) /home/henry/IRFuzzer/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1430:23
#21 0x00007ffb3f0e92b2 llvm::FPPassManager::runOnModule(llvm::Module&) /home/henry/IRFuzzer/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1476:16
#22 0x00007ffb3f0e4d59 (anonymous namespace)::MPPassManager::runOnModule(llvm::Module&) /home/henry/IRFuzzer/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1545:23
#23 0x00007ffb3f0e48cd llvm::legacy::PassManagerImpl::run(llvm::Module&) /home/henry/IRFuzzer/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:535:16
#24 0x00007ffb3f0e9591 llvm::legacy::PassManager::run(llvm::Module&) /home/henry/IRFuzzer/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1672:3
#25 0x000055d527591650 compileModule(char**, llvm::LLVMContext&) /home/henry/IRFuzzer/llvm-project/llvm/tools/llc/llc.cpp:736:41
#26 0x000055d52758fa2d main /home/henry/IRFuzzer/llvm-project/llvm/tools/llc/llc.cpp:420:13
#27 0x00007ffb3de7fd90 (/lib/x86_64-linux-gnu/libc.so.6+0x29d90)
#28 0x00007ffb3de7fe40 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e40)
#29 0x000055d52758f205 _start (./llvm-project/build-debug/bin/llc+0x19205)
@HazyFish
Copy link
Contributor Author

@DataCorrupted

@llvmbot
Copy link
Collaborator

llvmbot commented Mar 28, 2023

@llvm/issue-subscribers-backend-webassembly

@DataCorrupted
Copy link
Member

DataCorrupted commented Mar 30, 2023

<i8 16, i8 16, i8 16, i8 16> is translated into t28: v16i8 = BUILD_VECTOR Constant:i32<16>, Constant:i32<16>, Constant:i32<16>, Constant:i32<16>, undef:i32, undef:i32, undef:i32, undef:i32, undef:i32, undef:i32, undef:i32, undef:i32, undef:i32, undef:i32, undef:i32, undef:i32 in LegalizeTypes.cpp:807.

Then in the next CurDAG->Combine(...)LegalizeTypes.cpp:831 it is combined into t50: v16i8 = splat_vector Constant:i32<16>.

This vector will be used for self-mul (%v4 = mul <4 x i8> %v3, %v3), which renders 16 * 16 = 256 out of bound of i8.
Therefore, in WebAssemblyIselLowering.cpp:L2154 auto NewVal = ((uint64_t)Val % (1ll << LaneBits)) - (1ll << LaneBits); converts it to -256 (Val == 256, LaneBits == 8), which should've been 0.

@DataCorrupted DataCorrupted self-assigned this Mar 30, 2023
@DataCorrupted
Copy link
Member

Previous commit https://reviews.llvm.org/D108669

@DataCorrupted
Copy link
Member

Candidate patch: https://reviews.llvm.org/D147208

DataCorrupted added a commit that referenced this issue Mar 31, 2023
Constants in BUILD_VECTOR may be down cast into a smaller value that fits LaneBits, i.e., the bit width of elements in the vector.
This cast didn't consider 2^N where it would be cast into -2^N, which still doesn't fit into LaneBits after casting.
This will cause an assertion in later legalization.

2^N should be cast into 0, and this patch reflects such behavior.
This patch also includes a test to reflect the fix.
This patch fixes [issue 61780](#61780)

Related patch: https://reviews.llvm.org/D108669

Reviewed By: tlively

Differential Revision: https://reviews.llvm.org/D147208
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants