[llvm] fa023e0 - [NVPTX] Emit .noreturn directive
Andrew Savonichev via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 28 10:46:22 PST 2022
Author: Pavel Kopyl
Date: 2022-12-28T21:45:51+03:00
New Revision: fa023e0fe81697c4b263b6ee751b345d0fd60b6a
URL: https://github.com/llvm/llvm-project/commit/fa023e0fe81697c4b263b6ee751b345d0fd60b6a
DIFF: https://github.com/llvm/llvm-project/commit/fa023e0fe81697c4b263b6ee751b345d0fd60b6a.diff
LOG: [NVPTX] Emit .noreturn directive
Differential Revision: https://reviews.llvm.org/D140238
Added:
llvm/test/CodeGen/NVPTX/noreturn.ll
Modified:
llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
llvm/lib/Target/NVPTX/NVPTXSubtarget.h
llvm/lib/Target/NVPTX/NVPTXUtilities.cpp
llvm/lib/Target/NVPTX/NVPTXUtilities.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
index 076f3949e531a..7d8d37a0f97e2 100644
--- a/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXAsmPrinter.cpp
@@ -472,6 +472,9 @@ void NVPTXAsmPrinter::emitFunctionEntryLabel() {
if (isKernelFunction(*F))
emitKernelFunctionDirectives(*F, O);
+ if (shouldEmitPTXNoReturn(F, TM))
+ O << ".noreturn";
+
OutStreamer->emitRawText(O.str());
VRegMapping.clear();
@@ -615,6 +618,8 @@ void NVPTXAsmPrinter::emitDeclaration(const Function *F, raw_ostream &O) {
getSymbol(F)->print(O, MAI);
O << "\n";
emitFunctionParamList(F, O);
+ if (shouldEmitPTXNoReturn(F, TM))
+ O << ".noreturn";
O << ";\n";
}
diff --git a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
index c7ed3797b0ea1..8b571811cdac9 100644
--- a/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXISelLowering.cpp
@@ -1430,7 +1430,10 @@ std::string NVPTXTargetLowering::getPrototype(
if (VAInfo)
O << (first ? "" : ",") << " .param .align " << VAInfo->second
<< " .b8 _[]\n";
- O << ");";
+ O << ")";
+ if (shouldEmitPTXNoReturn(&CB, *nvTM))
+ O << " .noreturn";
+ O << ";";
return Prototype;
}
diff --git a/llvm/lib/Target/NVPTX/NVPTXSubtarget.h b/llvm/lib/Target/NVPTX/NVPTXSubtarget.h
index 73866ff3027d5..920f5bb94689d 100644
--- a/llvm/lib/Target/NVPTX/NVPTXSubtarget.h
+++ b/llvm/lib/Target/NVPTX/NVPTXSubtarget.h
@@ -78,6 +78,7 @@ class NVPTXSubtarget : public NVPTXGenSubtargetInfo {
bool hasFP16Math() const { return SmVersion >= 53; }
bool allowFP16Math() const;
bool hasMaskOperator() const { return PTXVersion >= 71; }
+ bool hasNoReturn() const { return SmVersion >= 30 && PTXVersion >= 64; }
unsigned int getSmVersion() const { return SmVersion; }
std::string getTargetName() const { return TargetName; }
diff --git a/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp b/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp
index 90d4d35cded04..988910810da65 100644
--- a/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp
+++ b/llvm/lib/Target/NVPTX/NVPTXUtilities.cpp
@@ -12,6 +12,7 @@
#include "NVPTXUtilities.h"
#include "NVPTX.h"
+#include "NVPTXTargetMachine.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
@@ -328,4 +329,23 @@ Function *getMaybeBitcastedCallee(const CallBase *CB) {
return dyn_cast<Function>(CB->getCalledOperand()->stripPointerCasts());
}
+bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM) {
+ const auto &ST =
+ *static_cast<const NVPTXTargetMachine &>(TM).getSubtargetImpl();
+ if (!ST.hasNoReturn())
+ return false;
+
+ assert((isa<Function>(V) || isa<CallInst>(V)) &&
+ "Expect either a call instruction or a function");
+
+ if (const CallInst *CallI = dyn_cast<CallInst>(V))
+ return CallI->doesNotReturn() &&
+ CallI->getFunctionType()->getReturnType()->isVoidTy();
+
+ const Function *F = cast<Function>(V);
+ return F->doesNotReturn() &&
+ F->getFunctionType()->getReturnType()->isVoidTy() &&
+ !isKernelFunction(*F);
+}
+
} // namespace llvm
diff --git a/llvm/lib/Target/NVPTX/NVPTXUtilities.h b/llvm/lib/Target/NVPTX/NVPTXUtilities.h
index 6e6b355f74bee..f980ea3dec0b8 100644
--- a/llvm/lib/Target/NVPTX/NVPTXUtilities.h
+++ b/llvm/lib/Target/NVPTX/NVPTXUtilities.h
@@ -24,6 +24,8 @@
namespace llvm {
+class TargetMachine;
+
void clearAnnotationCache(const Module *);
bool findOneNVVMAnnotation(const GlobalValue *, const std::string &,
@@ -70,6 +72,8 @@ inline unsigned promoteScalarArgumentSize(unsigned size) {
else
return size;
}
+
+bool shouldEmitPTXNoReturn(const Value *V, const TargetMachine &TM);
}
#endif
diff --git a/llvm/test/CodeGen/NVPTX/noreturn.ll b/llvm/test/CodeGen/NVPTX/noreturn.ll
new file mode 100644
index 0000000000000..86cec0a37d9bf
--- /dev/null
+++ b/llvm/test/CodeGen/NVPTX/noreturn.ll
@@ -0,0 +1,51 @@
+; RUN: llc < %s -march=nvptx64 -mattr=+ptx64 -mcpu=sm_30 | FileCheck %s
+; RUN: %if ptxas %{llc < %s -march=nvptx64 -mattr=+ptx60 -mcpu=sm_30 | %ptxas-verify %}
+
+ at function_pointer = addrspace(1) global void (i32)* null
+
+; CHECK: .func trap_wrapper
+; CHECK-NEXT: ()
+; CHECK-NEXT: .noreturn;
+
+declare void @trap_wrapper() #0
+
+; CHECK: .func {{.*}} non_void_noreturn()
+; CHECK-NOT: .noreturn
+
+define i32 @non_void_noreturn() #0 {
+ ret i32 54
+}
+
+; CHECK: .func true_noreturn0()
+; CHECK-NEXT: .noreturn
+
+define void @true_noreturn0() #0 {
+ call void @trap_wrapper()
+ ret void
+}
+
+; CHECK: .entry ignore_kernel_noreturn()
+; CHECK-NOT: .noreturn
+
+define void @ignore_kernel_noreturn() #0 {
+ unreachable
+}
+
+; CHECK-LABEL: .entry callprototype_noreturn(
+; CHECK: prototype_{{[0-9]+}} : .callprototype ()_ (.param .b32 _) .noreturn;
+; CHECK: prototype_{{[0-9]+}} : .callprototype (.param .b32 _) _ (.param .b32 _);
+
+define void @callprototype_noreturn(i32) {
+ %fn = load void (i32)*, void (i32)* addrspace(1)* @function_pointer
+ call void %fn(i32 %0) #0
+ %non_void = bitcast void (i32)* %fn to i32 (i32)*
+ %2 = call i32 %non_void(i32 %0) #0
+ ret void
+}
+
+attributes #0 = { noreturn }
+
+!nvvm.annotations = !{!0, !1}
+
+!0 = !{void ()* @ignore_kernel_noreturn, !"kernel", i32 1}
+!1 = !{void (i32)* @callprototype_noreturn, !"kernel", i32 1}
More information about the llvm-commits
mailing list