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

Segmentation fault in MIPS64-gnuabi64 SelectionDAG #63608

Closed
Noratrieb opened this issue Jun 29, 2023 · 14 comments
Closed

Segmentation fault in MIPS64-gnuabi64 SelectionDAG #63608

Noratrieb opened this issue Jun 29, 2023 · 14 comments
Assignees
Labels
backend:MIPS crash Prefer [crash-on-valid] or [crash-on-invalid]

Comments

@Noratrieb
Copy link

Noratrieb commented Jun 29, 2023

This been causing lots of spurious failures in Rust's CI recently, see rust-lang/rust#113065

; ModuleID = 'reduced.bc'
target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"
target triple = "mips64-unknown-linux-gnuabi64"

define internal fastcc void @uwu(<5 x i32> %self.8.val) {
start:
  store <5 x i32> %self.8.val, ptr null, align 4
  ret void
}

llc code.ll

PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: llc reduced.ll
1.	Running pass 'Function Pass Manager' on module 'reduced.ll'.
2.	Running pass 'MIPS DAG->DAG Pattern Instruction Selection' on function '@uwu'
 #0 0x00007fead70ba06e llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x10ba06e)
 #1 0x00007fead70b78eb SignalHandler(int) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x10b78eb)
 #2 0x00007fead5a52d60 __restore_rt (/nix/store/dg8mpqqykmw9c7l0bgzzb5znkymlbfjw-glibc-2.37-8/lib/libc.so.6+0x38d60)
 #3 0x00007fead7b058b2 llvm::SelectionDAG::createOperands(llvm::SDNode*, llvm::ArrayRef<llvm::SDValue>) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x1b058b2)
 #4 0x00007fead7b2332d llvm::SelectionDAG::getNode(unsigned int, llvm::SDLoc const&, llvm::EVT, llvm::ArrayRef<llvm::SDValue>, llvm::SDNodeFlags) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x1b2332d)
 #5 0x00007fead7b386c9 llvm::SelectionDAG::getNode(unsigned int, llvm::SDLoc const&, llvm::EVT, llvm::ArrayRef<llvm::SDUse>) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x1b386c9)
 #6 0x00007fead796b7ec (anonymous namespace)::DAGCombiner::visitEXTRACT_SUBVECTOR(llvm::SDNode*) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x196b7ec)
 #7 0x00007fead7977a5d (anonymous namespace)::DAGCombiner::combine(llvm::SDNode*) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x1977a5d)
 #8 0x00007fead797914f llvm::SelectionDAG::Combine(llvm::CombineLevel, llvm::AAResults*, llvm::CodeGenOpt::Level) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x197914f)
 #9 0x00007fead7b52771 llvm::SelectionDAGISel::CodeGenAndEmitDAG() (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x1b52771)
#10 0x00007fead7b5550f llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x1b5550f)
#11 0x00007fead7b57cd5 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (.part.0) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x1b57cd5)
#12 0x00007feada38553a llvm::MipsDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x438553a)
#13 0x00007fead7564171 llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x1564171)
#14 0x00007fead723b530 llvm::FPPassManager::runOnFunction(llvm::Function&) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x123b530)
#15 0x00007fead723b65c llvm::FPPassManager::runOnModule(llvm::Module&) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x123b65c)
#16 0x00007fead723bfdd llvm::legacy::PassManagerImpl::run(llvm::Module&) (/nix/store/33zbbqa7n6qfbliy77d4c53fcvd2bym9-llvm-16.0.1-lib/lib/libLLVM-16.so+0x123bfdd)
#17 0x0000000000411a33 main (/nix/store/l39q5l25yclps25kdwim670mmviiaa6i-llvm-16.0.1/bin/llc+0x411a33)
#18 0x00007fead5a3dace __libc_start_call_main (/nix/store/dg8mpqqykmw9c7l0bgzzb5znkymlbfjw-glibc-2.37-8/lib/libc.so.6+0x23ace)
#19 0x00007fead5a3db89 __libc_start_main@GLIBC_2.2.5 (/nix/store/dg8mpqqykmw9c7l0bgzzb5znkymlbfjw-glibc-2.37-8/lib/libc.so.6+0x23b89)
#20 0x0000000000412215 _start (/nix/store/l39q5l25yclps25kdwim670mmviiaa6i-llvm-16.0.1/bin/llc+0x412215)
fish: Job 1, 'llc reduced.ll' terminated by signal SIGSEGV (Address boundary error)

the issue was originally discovered and reproduced on x86-64 Ubuntu 20 on LLVM 22897bc, I've done the reduction on NixOS using its llvmPackages_16 package.

@Noratrieb Noratrieb changed the title Segmentation fault in MIPS SelectionDAG Segmentation fault in MIPS64-gnuabi64 SelectionDAG Jun 29, 2023
@EugeneZelenko EugeneZelenko added backend:MIPS crash Prefer [crash-on-valid] or [crash-on-invalid] and removed new issue labels Jun 29, 2023
@llvmbot
Copy link
Member

llvmbot commented Jun 29, 2023

@llvm/issue-subscribers-backend-mips

@chenx97
Copy link

chenx97 commented Jul 3, 2023

LLVM version 15.0.7 can reproduce this behavior😢

@workingjubilee
Copy link
Contributor

llc 14.0.0 appears to reject this IR unless you pass -opaque-pointers, which replicates the bug.

llc 13.0.0 seems to complete isel with the following output in Godbolt:

uwu:                                    # @uwu
        daddiu  $1, $zero, 1
        dsll    $1, $1, 32
        daddiu  $1, $1, -1
        dsll    $2, $6, 32
        daddiu  $3, $zero, 8
        sdl     $2, 0($3)
        and     $1, $5, $1
        dsll    $3, $4, 32
        or      $1, $1, $3
        sdl     $1, 0($zero)
        daddiu  $3, $zero, 15
        sdr     $2, 0($3)
        daddiu  $2, $zero, 7
        jr      $ra
        sdr     $1, 0($2)

@chenx97
Copy link

chenx97 commented Jul 3, 2023

It appears to break when the vector is oddly sized, except for 1 x i32 which just returns a 0.

@cbeuw
Copy link

cbeuw commented Jul 3, 2023

Hits a debug assertion: https://llvm.godbolt.org/z/ebPz7WP9e

llc: /root/llvm-project/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp:407: llvm::SDValue getCopyFromPartsVector(llvm::SelectionDAG&, const llvm::SDLoc&, const llvm::SDValue*, unsigned int, llvm::MVT, llvm::EVT, const llvm::Value*, std::optional<unsigned int>): Assertion `(PartEVT.getVectorElementCount().getKnownMinValue() > ValueVT.getVectorElementCount().getKnownMinValue()) && (PartEVT.getVectorElementCount().isScalable() == ValueVT.getVectorElementCount().isScalable()) && "Cannot narrow, it would be a lossy transformation"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /opt/compiler-explorer/clang-assertions-trunk/bin/llc -o /app/output.s -x86-asm-syntax=intel <source>
1.	Running pass 'Function Pass Manager' on module '<source>'.
2.	Running pass 'MIPS DAG->DAG Pattern Instruction Selection' on function '@uwu'
 #0 0x000055ddb3a733af llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x352a3af)
 #1 0x000055ddb3a70b04 SignalHandler(int) Signals.cpp:0:0
 #2 0x00007f91e0ac6420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #3 0x00007f91e059300b raise (/lib/x86_64-linux-gnu/libc.so.6+0x4300b)
 #4 0x00007f91e0572859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x22859)
 #5 0x00007f91e0572729 (/lib/x86_64-linux-gnu/libc.so.6+0x22729)
 #6 0x00007f91e0583fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #7 0x000055ddb37637bc getCopyFromParts(llvm::SelectionDAG&, llvm::SDLoc const&, llvm::SDValue const*, unsigned int, llvm::MVT, llvm::EVT, llvm::Value const*, std::optional<unsigned int>, std::optional<llvm::ISD::NodeType>) (.isra.0) SelectionDAGBuilder.cpp:0:0
 #8 0x000055ddb378aa4f llvm::SelectionDAGISel::LowerArguments(llvm::Function const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x3241a4f)
 #9 0x000055ddb383f0c7 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x32f60c7)
#10 0x000055ddb3840352 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) (.part.0) SelectionDAGISel.cpp:0:0
#11 0x000055ddb1b8df9f llvm::MipsDAGToDAGISel::runOnMachineFunction(llvm::MachineFunction&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x1644f9f)
#12 0x000055ddb2d1478e llvm::MachineFunctionPass::runOnFunction(llvm::Function&) (.part.0) MachineFunctionPass.cpp:0:0
#13 0x000055ddb32adcd1 llvm::FPPassManager::runOnFunction(llvm::Function&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x2d64cd1)
#14 0x000055ddb32adf19 llvm::FPPassManager::runOnModule(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x2d64f19)
#15 0x000055ddb32ae792 llvm::legacy::PassManagerImpl::run(llvm::Module&) (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x2d65792)
#16 0x000055ddb0dde434 compileModule(char**, llvm::LLVMContext&) llc.cpp:0:0
#17 0x000055ddb0d26eb6 main (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x7ddeb6)
#18 0x00007f91e0574083 __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24083)
#19 0x000055ddb0dd481e _start (/opt/compiler-explorer/clang-assertions-trunk/bin/llc+0x88b81e)

@nikic
Copy link
Contributor

nikic commented Jul 3, 2023

The vector is passed on three i64 registers. getCopyFromPartsVector() will produce a BUILD_VECTOR to v3i64 and then tries to convert that into v5i32. In this case one would need to BITCAST that to v6i32 first, before performing the EXTRACT_SUBVECTOR to v5i32. The current code doesn't support this.

@nikic
Copy link
Contributor

nikic commented Jul 3, 2023

I believe https://gist.github.com/nikic/fe10841e5e82f30421f2fc9358875025 should fix the argument lowering side of this, but the same issue also needs to be fixed for call lowering in getCopyToPartsVector().

@nikic nikic self-assigned this Jul 3, 2023
@cuviper
Copy link
Member

cuviper commented Jul 3, 2023

llc 14.0.0 appears to reject this IR unless you pass -opaque-pointers, which replicates the bug.

It's simple to add typed pointers:

; ModuleID = 'reduced.bc'
target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"
target triple = "mips64-unknown-linux-gnuabi64"

define internal fastcc void @uwu(<5 x i32> %self.8.val) {
start:
  store <5 x i32> %self.8.val, <5 x i32>* null, align 4
  ret void
}

That still crashes with llc-14, but it's ok with llc-13, with the same godbolt output as before.

@Cyanoxygen
Copy link
Contributor

Cyanoxygen commented Jul 4, 2023

I believe https://gist.github.com/nikic/fe10841e5e82f30421f2fc9358875025 should fix the argument lowering side of this, but the same issue also needs to be fixed for call lowering in getCopyToPartsVector().

I built the LLVM git against the patch you have published. It no longer crashes, the resulting assembly is shown below:

Output of llc test.ll
uwu:                                    # @uwu
        .cfi_startproc
        .frame  $sp,0,$ra
        .mask   0x00000000,0
        .fmask  0x00000000,0
        .set    noreorder
        .set    nomacro
        .set    noat
# %bb.0:                                # %start
        daddiu  $1, $zero, 8
        sdl     $5, 0($1)
        sdl     $4, 0($zero)
        dsrl    $1, $6, 32
        daddiu  $2, $zero, 16
        sw      $1, 0($2)
        daddiu  $1, $zero, 15
        sdr     $5, 0($1)
        daddiu  $1, $zero, 7
        jr      $ra
        sdr     $4, 0($1)
        .set    at
        .set    macro
        .set    reorder
        .end    uwu

Which looks good (at least to) me.

@nikic
Copy link
Contributor

nikic commented Jul 4, 2023

This patch handles the original case on both the call and argument side: https://gist.github.com/nikic/a52f764ee0ba211ddfd98a50e3df009d

However, this breaks down when combined with illegal integer types. For example, mips is trying to pass v7i18 as two i64 values. This significantly complicates the situation, as v7i18 and v2i64 don't have the same size, so we would probably have to round-trip via bitcasts and integer truncations.

This makes me wonder whether it wouldn't be better to change the used ABI here, at least for non-power-of-two types and element counts.

@nikic
Copy link
Contributor

nikic commented Jul 4, 2023

I ended up going with the second option.

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

@peterwillcn
Copy link

Any news? Old embedded devices take up a lot of space, such as home routers.

@nikic
Copy link
Contributor

nikic commented Aug 9, 2024

Any news? Old embedded devices take up a lot of space, such as home routers.

This issue has been fixed a year ago. If you still see a related problem, please file a new issue.

@slanterns

This comment was marked as off-topic.

veselypeta pushed a commit to veselypeta/cherillvm that referenced this issue Sep 7, 2024
The Mips MSA ABI requires that legal vector types are passed in
scalar registers in packed representation. E.g. a type like v16i8
would be passed as two i64 registers.

The implementation attempts to do the same for illegal vectors with
non-power-of-two element counts or non-power-of-two element types.
However, the SDAG argument lowering code doesn't support this, and
it is not easy to extend it to support this (we would have to deal
with situations like passing v7i18 as two i64 values).

This patch instead opts to restrict the special argument lowering
to only vectors with power-of-two elements and round element types.
Everything else is lowered naively, that is by passing each element
in promoted registers.

Fixes llvm/llvm-project#63608.

Differential Revision: https://reviews.llvm.org/D154445
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:MIPS crash Prefer [crash-on-valid] or [crash-on-invalid]
Projects
None yet
Development

No branches or pull requests