Skip to content

[NVPTX] Fix NVPTXLowerUnreachable::isLoweredToTrap logic #109730

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

Merged
merged 1 commit into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions llvm/lib/Target/NVPTX/NVPTXLowerUnreachable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,17 +110,24 @@ StringRef NVPTXLowerUnreachable::getPassName() const {
}

// =============================================================================
// Returns whether a `trap` intrinsic should be emitted before I.
// Returns whether a `trap` intrinsic would be emitted before I.
//
// This is a copy of the logic in SelectionDAGBuilder::visitUnreachable().
// =============================================================================
bool NVPTXLowerUnreachable::isLoweredToTrap(const UnreachableInst &I) const {
if (!TrapUnreachable)
return false;
if (!NoTrapAfterNoreturn)
return true;
const CallInst *Call = dyn_cast_or_null<CallInst>(I.getPrevNode());
return Call && Call->doesNotReturn();
if (const auto *Call = dyn_cast_or_null<CallInst>(I.getPrevNode())) {
// We've already emitted a non-continuable trap.
if (Call->isNonContinuableTrap())
return true;

// No traps are emitted for calls that do not return
// when this option is enabled.
if (NoTrapAfterNoreturn && Call->doesNotReturn())
return false;
}

// In all other cases, we will generate a trap if TrapUnreachable is set.
return TrapUnreachable;
}

// =============================================================================
Expand Down
26 changes: 21 additions & 5 deletions llvm/test/CodeGen/NVPTX/unreachable.ll
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
; RUN: llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs \
; RUN: llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs -trap-unreachable=false \
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOTRAP
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs \
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs -trap-unreachable=false \
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOTRAP
; RUN: llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs -trap-unreachable \
; RUN: llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs -trap-unreachable -no-trap-after-noreturn \
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOTRAP
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs -trap-unreachable -no-trap-after-noreturn \
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOTRAP
; RUN: llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs -trap-unreachable -no-trap-after-noreturn=false \
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-TRAP
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs -trap-unreachable \
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs -trap-unreachable -no-trap-after-noreturn=false \
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-TRAP
; RUN: %if ptxas && !ptxas-12.0 %{ llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs | %ptxas-verify %}
; RUN: %if ptxas %{ llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs | %ptxas-verify %}

; CHECK: .extern .func throw
declare void @throw() #0
declare void @llvm.trap() #0

; CHECK: .entry kernel_func
; CHECK-LABEL: .entry kernel_func
define void @kernel_func() {
; CHECK: call.uni
; CHECK: throw,
Expand All @@ -24,6 +29,17 @@ define void @kernel_func() {
unreachable
}

; CHECK-LABEL: kernel_func_2
define void @kernel_func_2() {
; CHECK: trap; exit;
call void @llvm.trap()

;; Make sure we avoid emitting two trap instructions.
; CHECK-NOT: trap;
; CHECK-NOT: exit;
unreachable
}

attributes #0 = { noreturn }


Expand Down
Loading