llvm / llvm-project

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

[RISC-V] RISCVVectorPeephole::ensureDominates: Assertion `MO.getParent()->getParent() == Src.getParent()' failed. #110832

Closed hvdijk closed 2 days ago

hvdijk commented 2 days ago

Reduced from a real test that is too large to include here.

Please consider test.mir:

name: f
body: |
  bb.0:
    %0:gpr = IMPLICIT_DEF
    %1:vr = IMPLICIT_DEF
    %2:gpr = IMPLICIT_DEF
    $v0 = COPY %1
    %3:vrm4nov0 = PseudoVLSE32_V_M4_MASK $noreg, killed %0, %2, $v0, 16, 5 /* e32 */, 1 /* ta, mu */
  bb.1:
    %4:vrm4 = IMPLICIT_DEF
    $v0 = COPY %1
    %5:vrm4nov0 = PseudoVMERGE_VVM_M4 $noreg, killed %4, killed %3, $v0, 16, 5 /* e32 */

This is not handled by RISCVVectorPeephole:

$ llc -mtriple=riscv64-linux-gnu -mattr=+v -run-pass=riscv-vector-peephole -o /dev/null test.mir
llc: /home/harald/llvm-project/main/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp:548: bool {anonymous}::RISCVVectorPeephole::ensureDominates(const llvm::MachineOperand&, llvm::MachineInstr&) const: Assertion `MO.getParent()->getParent() == Src.getParent()' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.  Program arguments: bin/llc -mtriple=riscv64-linux-gnu -mattr=+v -run-pass=riscv-vector-peephole -o /dev/null test.mir
1.  Running pass 'Function Pass Manager' on module 'test.mir'.
2.  Running pass 'RISC-V Vector Peephole Optimization' on function '@f'
 #0 0x0000b4a971a947a8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (bin/llc+0x3cd47a8)
 #1 0x0000b4a971a91dbc SignalHandler(int) Signals.cpp:0:0
 #2 0x0000e5de7cf3d8f8 (linux-vdso.so.1+0x8f8)
 #3 0x0000e5de7ca17628 (/lib/aarch64-linux-gnu/libc.so.6+0x87628)
 #4 0x0000e5de7c9ccb3c raise (/lib/aarch64-linux-gnu/libc.so.6+0x3cb3c)
 #5 0x0000e5de7c9b7e00 abort (/lib/aarch64-linux-gnu/libc.so.6+0x27e00)
 #6 0x0000e5de7c9c5cbc (/lib/aarch64-linux-gnu/libc.so.6+0x35cbc)
 #7 0x0000e5de7c9c5d2c (/lib/aarch64-linux-gnu/libc.so.6+0x35d2c)
 #8 0x0000b4a96faed9dc (anonymous namespace)::RISCVVectorPeephole::ensureDominates(llvm::MachineOperand const&, llvm::MachineInstr&) const (.isra.0) RISCVVectorPeephole.cpp:0:0
 #9 0x0000b4a96faeddcc (anonymous namespace)::RISCVVectorPeephole::convertSameMaskVMergeToVMv(llvm::MachineInstr&) RISCVVectorPeephole.cpp:0:0
#10 0x0000b4a96faeed2c (anonymous namespace)::RISCVVectorPeephole::runOnMachineFunction(llvm::MachineFunction&) RISCVVectorPeephole.cpp:0:0
#11 0x0000b4a970a588fc llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) MachineFunctionPass.cpp:0:0
#12 0x0000b4a9710609e0 llvm::FPPassManager::runOnFunction(llvm::Function&) (bin/llc+0x32a09e0)
#13 0x0000b4a971060c5c llvm::FPPassManager::runOnModule(llvm::Module&) (bin/llc+0x32a0c5c)
#14 0x0000b4a97106178c llvm::legacy::PassManagerImpl::run(llvm::Module&) (bin/llc+0x32a178c)
#15 0x0000b4a96e91e89c compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#16 0x0000b4a96e8356fc main (bin/llc+0xa756fc)
#17 0x0000e5de7c9b84c4 (/lib/aarch64-linux-gnu/libc.so.6+0x284c4)
#18 0x0000e5de7c9b8598 __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x28598)
#19 0x0000b4a96e916c70 _start (bin/llc+0xb56c70)
Aborted

The assert is in the RISCVVectorPeephole::ensureDominates function which documents

/// If the register in \p MO doesn't dominate \p Src, try to move \p Src so it
/// does. Returns false if doesn't dominate and we can't move. \p MO must be in
/// the same basic block as \Src.

However, when this function is called, no logic is in place that would ensure that MO is in the same basic block as Src.

Is it the responsibility of previous passes to ensure that the PseudoVLSE32_V_M4_MASK is in the same basic block as the PseudoVMERGE_VVM_M4, or is it the responsibility of this pass to handle them being in different blocks?

llvmbot commented 2 days ago

@llvm/issue-subscribers-backend-risc-v

Author: Harald van Dijk (hvdijk)

Reduced from a real test that is too large to include here. Please consider `test.mir`: ```llvm-mir name: f body: | bb.0: %0:gpr = IMPLICIT_DEF %1:vr = IMPLICIT_DEF %2:gpr = IMPLICIT_DEF $v0 = COPY %1 %3:vrm4nov0 = PseudoVLSE32_V_M4_MASK $noreg, killed %0, %2, $v0, 16, 5 /* e32 */, 1 /* ta, mu */ bb.1: %4:vrm4 = IMPLICIT_DEF $v0 = COPY %1 %5:vrm4nov0 = PseudoVMERGE_VVM_M4 $noreg, killed %4, killed %3, $v0, 16, 5 /* e32 */ ``` This is not handled by RISCVVectorPeephole: ``` $ llc -mtriple=riscv64-linux-gnu -mattr=+v -run-pass=riscv-vector-peephole -o /dev/null test.mir llc: /home/harald/llvm-project/main/llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp:548: bool {anonymous}::RISCVVectorPeephole::ensureDominates(const llvm::MachineOperand&, llvm::MachineInstr&) const: Assertion `MO.getParent()->getParent() == Src.getParent()' failed. PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace. Stack dump: 0. Program arguments: bin/llc -mtriple=riscv64-linux-gnu -mattr=+v -run-pass=riscv-vector-peephole -o /dev/null test.mir 1. Running pass 'Function Pass Manager' on module 'test.mir'. 2. Running pass 'RISC-V Vector Peephole Optimization' on function '@f' #0 0x0000b4a971a947a8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (bin/llc+0x3cd47a8) #1 0x0000b4a971a91dbc SignalHandler(int) Signals.cpp:0:0 #2 0x0000e5de7cf3d8f8 (linux-vdso.so.1+0x8f8) #3 0x0000e5de7ca17628 (/lib/aarch64-linux-gnu/libc.so.6+0x87628) #4 0x0000e5de7c9ccb3c raise (/lib/aarch64-linux-gnu/libc.so.6+0x3cb3c) #5 0x0000e5de7c9b7e00 abort (/lib/aarch64-linux-gnu/libc.so.6+0x27e00) #6 0x0000e5de7c9c5cbc (/lib/aarch64-linux-gnu/libc.so.6+0x35cbc) #7 0x0000e5de7c9c5d2c (/lib/aarch64-linux-gnu/libc.so.6+0x35d2c) #8 0x0000b4a96faed9dc (anonymous namespace)::RISCVVectorPeephole::ensureDominates(llvm::MachineOperand const&, llvm::MachineInstr&) const (.isra.0) RISCVVectorPeephole.cpp:0:0 #9 0x0000b4a96faeddcc (anonymous namespace)::RISCVVectorPeephole::convertSameMaskVMergeToVMv(llvm::MachineInstr&) RISCVVectorPeephole.cpp:0:0 #10 0x0000b4a96faeed2c (anonymous namespace)::RISCVVectorPeephole::runOnMachineFunction(llvm::MachineFunction&) RISCVVectorPeephole.cpp:0:0 #11 0x0000b4a970a588fc llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) MachineFunctionPass.cpp:0:0 #12 0x0000b4a9710609e0 llvm::FPPassManager::runOnFunction(llvm::Function&) (bin/llc+0x32a09e0) #13 0x0000b4a971060c5c llvm::FPPassManager::runOnModule(llvm::Module&) (bin/llc+0x32a0c5c) #14 0x0000b4a97106178c llvm::legacy::PassManagerImpl::run(llvm::Module&) (bin/llc+0x32a178c) #15 0x0000b4a96e91e89c compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0 #16 0x0000b4a96e8356fc main (bin/llc+0xa756fc) #17 0x0000e5de7c9b84c4 (/lib/aarch64-linux-gnu/libc.so.6+0x284c4) #18 0x0000e5de7c9b8598 __libc_start_main (/lib/aarch64-linux-gnu/libc.so.6+0x28598) #19 0x0000b4a96e916c70 _start (bin/llc+0xb56c70) Aborted ``` The assert is in the `RISCVVectorPeephole::ensureDominates` function which documents ``` /// If the register in \p MO doesn't dominate \p Src, try to move \p Src so it /// does. Returns false if doesn't dominate and we can't move. \p MO must be in /// the same basic block as \Src. ``` However, when this function is called, no logic is in place that would ensure that `MO` is in the same basic block as `Src`. Is it the responsibility of previous passes to ensure that the `PseudoVLSE32_V_M4_MASK` is in the same basic block as the `PseudoVMERGE_VVM_M4`, or is it the responsibility of this pass to handle them being in different blocks?
lukel97 commented 2 days ago

Thanks for catching this. It shouldn't be the other passes' responsibility, RISCVVectorPeephole is doing something wrong here. It should only be considering operands within the same block since it's a local transform.