rdar://11542750 - llvm.trap should be marked no return.
authorChris Lattner <sabre@nondot.org>
Sun, 27 May 2012 23:20:41 +0000 (23:20 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 27 May 2012 23:20:41 +0000 (23:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157551 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LangRef.html
include/llvm/Intrinsics.td
test/Feature/intrinsics.ll
utils/TableGen/CodeGenIntrinsics.h
utils/TableGen/CodeGenTarget.cpp
utils/TableGen/IntrinsicEmitter.cpp

index a781992f89826c027120e325a3d3ad6ac8e9a799..ab0f9e1dcaa7860b282c4390b7b3eb688cf7014b 100644 (file)
@@ -8386,7 +8386,7 @@ LLVM</a>.</p>
 
 <h5>Syntax:</h5>
 <pre>
-  declare void @llvm.trap()
+  declare void @llvm.trap() noreturn nounwind
 </pre>
 
 <h5>Overview:</h5>
@@ -8411,7 +8411,7 @@ LLVM</a>.</p>
 
 <h5>Syntax:</h5>
 <pre>
-  declare void @llvm.debugtrap()
+  declare void @llvm.debugtrap() nounwind
 </pre>
 
 <h5>Overview:</h5>
index 794848c19cfa226bea78251e46b8a7f7232de3f1..1ebf13b1d81bc28fce6e75077ee2e03f45ebe1e5 100644 (file)
@@ -55,6 +55,8 @@ class NoCapture<int argNo> : IntrinsicProperty {
   int ArgNo = argNo;
 }
 
+def IntrNoReturn : IntrinsicProperty;
+
 //===----------------------------------------------------------------------===//
 // Types used by intrinsics.
 //===----------------------------------------------------------------------===//
@@ -400,7 +402,7 @@ def int_invariant_end   : Intrinsic<[],
 //
 def int_flt_rounds : Intrinsic<[llvm_i32_ty]>,
                      GCCBuiltin<"__builtin_flt_rounds">;
-def int_trap : Intrinsic<[]>,
+def int_trap : Intrinsic<[], [], [IntrNoReturn]>,
                GCCBuiltin<"__builtin_trap">;
 def int_debugtrap : Intrinsic<[]>,
                     GCCBuiltin<"__builtin_debugtrap">;
index c4e3db6174a6716a1f994a8c18d6c5b0225c5218..9e7dc6d4102e4bec718de256c88682eb3ea4ceb6 100644 (file)
@@ -1,6 +1,7 @@
 ; RUN: llvm-as < %s | llvm-dis > %t1.ll
 ; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll
 ; RUN: diff %t1.ll %t2.ll
+; RUN: FileCheck %s < %t1.ll
 
 declare i1 @llvm.isunordered.f32(float, float)
 
@@ -58,3 +59,12 @@ define void @libm() {
 }
 
 ; FIXME: test ALL the intrinsics in this file.
+
+; rdar://11542750
+; CHECK: declare void @llvm.trap() noreturn nounwind
+declare void @llvm.trap()
+
+define void @trap() {
+  call void @llvm.trap()
+  ret void
+}
index 3f6ba61172c9dfc745d8ce1a2140e05115da784d..6efe952ea2bbd8305ffa5723c081975fb7ce260d 100644 (file)
@@ -72,7 +72,10 @@ namespace llvm {
 
     /// canThrow - True if the intrinsic can throw.
     bool canThrow;
-    
+
+    /// isNoReturn - True if the intrinsic is no-return.
+    bool isNoReturn;
+
     enum ArgAttribute {
       NoCapture
     };
index cf6793570a2633529a072fe29c4fd19ce28cb996..dfa9526cc918559b66fd6c55c1a8a84fdf4be613 100644 (file)
@@ -387,6 +387,7 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
   isOverloaded = false;
   isCommutative = false;
   canThrow = false;
+  isNoReturn = false;
 
   if (DefName.size() <= 4 ||
       std::string(DefName.begin(), DefName.begin() + 4) != "int_")
@@ -511,6 +512,8 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
       isCommutative = true;
     else if (Property->getName() == "Throws")
       canThrow = true;
+    else if (Property->getName() == "IntrNoReturn")
+      isNoReturn = true;
     else if (Property->isSubClassOf("NoCapture")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
       ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
index 941c0537d620e9a2125b26e8af75bcdd480a6b26..9e2bb9d87f2402982b658c05edd70520fd6f2dbf 100644 (file)
@@ -451,6 +451,9 @@ namespace {
       if (L->canThrow != R->canThrow)
         return R->canThrow;
 
+      if (L->isNoReturn != R->isNoReturn)
+        return R->isNoReturn;
+
       // Try to order by readonly/readnone attribute.
       ModRefKind LK = getModRefKind(*L);
       ModRefKind RK = getModRefKind(*R);
@@ -549,16 +552,30 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
 
     ModRefKind modRef = getModRefKind(intrinsic);
 
-    if (!intrinsic.canThrow || modRef) {
+    if (!intrinsic.canThrow || modRef || intrinsic.isNoReturn) {
       OS << "      AWI[" << numAttrs++ << "] = AttributeWithIndex::get(~0, ";
+      bool Emitted = false;
       if (!intrinsic.canThrow) {
         OS << "Attribute::NoUnwind";
-        if (modRef) OS << '|';
+        Emitted = true;
+      }
+      
+      if (intrinsic.isNoReturn) {
+        if (Emitted) OS << '|';
+        OS << "Attribute::NoReturn";
+        Emitted = true;
       }
+
       switch (modRef) {
       case MRK_none: break;
-      case MRK_readonly: OS << "Attribute::ReadOnly"; break;
-      case MRK_readnone: OS << "Attribute::ReadNone"; break;
+      case MRK_readonly:
+        if (Emitted) OS << '|';
+        OS << "Attribute::ReadOnly";
+        break;
+      case MRK_readnone:
+        if (Emitted) OS << '|';
+        OS << "Attribute::ReadNone"; 
+        break;
       }
       OS << ");\n";
     }