[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