Skip to content

Commit 3da5e82

Browse files
authored
[NVPTX] Fix NVPTXLowerUnreachable::isLoweredToTrap logic (#109730)
Previously, this pass would not generate traps if `NoTrapAfterNoreturn` was set and would generate traps even if the instruction directly before the `UnreachableInst` was `llvm.trap()`. Fix both of these problems and add some tests.
1 parent 642bfd8 commit 3da5e82

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

llvm/lib/Target/NVPTX/NVPTXLowerUnreachable.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,17 +110,24 @@ StringRef NVPTXLowerUnreachable::getPassName() const {
110110
}
111111

112112
// =============================================================================
113-
// Returns whether a `trap` intrinsic should be emitted before I.
113+
// Returns whether a `trap` intrinsic would be emitted before I.
114114
//
115115
// This is a copy of the logic in SelectionDAGBuilder::visitUnreachable().
116116
// =============================================================================
117117
bool NVPTXLowerUnreachable::isLoweredToTrap(const UnreachableInst &I) const {
118-
if (!TrapUnreachable)
119-
return false;
120-
if (!NoTrapAfterNoreturn)
121-
return true;
122-
const CallInst *Call = dyn_cast_or_null<CallInst>(I.getPrevNode());
123-
return Call && Call->doesNotReturn();
118+
if (const auto *Call = dyn_cast_or_null<CallInst>(I.getPrevNode())) {
119+
// We've already emitted a non-continuable trap.
120+
if (Call->isNonContinuableTrap())
121+
return true;
122+
123+
// No traps are emitted for calls that do not return
124+
// when this option is enabled.
125+
if (NoTrapAfterNoreturn && Call->doesNotReturn())
126+
return false;
127+
}
128+
129+
// In all other cases, we will generate a trap if TrapUnreachable is set.
130+
return TrapUnreachable;
124131
}
125132

126133
// =============================================================================

llvm/test/CodeGen/NVPTX/unreachable.ll

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
1-
; RUN: llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs \
1+
; RUN: llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs -trap-unreachable=false \
22
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOTRAP
3-
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs \
3+
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs -trap-unreachable=false \
44
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOTRAP
5-
; RUN: llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs -trap-unreachable \
5+
; RUN: llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs -trap-unreachable -no-trap-after-noreturn \
6+
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOTRAP
7+
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs -trap-unreachable -no-trap-after-noreturn \
8+
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOTRAP
9+
; RUN: llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs -trap-unreachable -no-trap-after-noreturn=false \
610
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-TRAP
7-
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs -trap-unreachable \
11+
; RUN: llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs -trap-unreachable -no-trap-after-noreturn=false \
812
; RUN: | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-TRAP
913
; RUN: %if ptxas && !ptxas-12.0 %{ llc < %s -march=nvptx -mcpu=sm_20 -verify-machineinstrs | %ptxas-verify %}
1014
; RUN: %if ptxas %{ llc < %s -march=nvptx64 -mcpu=sm_20 -verify-machineinstrs | %ptxas-verify %}
1115

1216
; CHECK: .extern .func throw
1317
declare void @throw() #0
18+
declare void @llvm.trap() #0
1419

15-
; CHECK: .entry kernel_func
20+
; CHECK-LABEL: .entry kernel_func
1621
define void @kernel_func() {
1722
; CHECK: call.uni
1823
; CHECK: throw,
@@ -24,6 +29,17 @@ define void @kernel_func() {
2429
unreachable
2530
}
2631

32+
; CHECK-LABEL: kernel_func_2
33+
define void @kernel_func_2() {
34+
; CHECK: trap; exit;
35+
call void @llvm.trap()
36+
37+
;; Make sure we avoid emitting two trap instructions.
38+
; CHECK-NOT: trap;
39+
; CHECK-NOT: exit;
40+
unreachable
41+
}
42+
2743
attributes #0 = { noreturn }
2844

2945

0 commit comments

Comments
 (0)