From: Chris Lattner Date: Sun, 27 May 2012 23:20:41 +0000 (+0000) Subject: rdar://11542750 - llvm.trap should be marked no return. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=86208903cb3b693b26e144b8c5c7a0ab6a9a45c6;p=oota-llvm.git rdar://11542750 - llvm.trap should be marked no return. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157551 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/LangRef.html b/docs/LangRef.html index a781992f898..ab0f9e1dcaa 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -8386,7 +8386,7 @@ LLVM.

Syntax:
-  declare void @llvm.trap()
+  declare void @llvm.trap() noreturn nounwind
 
Overview:
@@ -8411,7 +8411,7 @@ LLVM.

Syntax:
-  declare void @llvm.debugtrap()
+  declare void @llvm.debugtrap() nounwind
 
Overview:
diff --git a/include/llvm/Intrinsics.td b/include/llvm/Intrinsics.td index 794848c19cf..1ebf13b1d81 100644 --- a/include/llvm/Intrinsics.td +++ b/include/llvm/Intrinsics.td @@ -55,6 +55,8 @@ class NoCapture : 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">; diff --git a/test/Feature/intrinsics.ll b/test/Feature/intrinsics.ll index c4e3db6174a..9e7dc6d4102 100644 --- a/test/Feature/intrinsics.ll +++ b/test/Feature/intrinsics.ll @@ -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 +} diff --git a/utils/TableGen/CodeGenIntrinsics.h b/utils/TableGen/CodeGenIntrinsics.h index 3f6ba61172c..6efe952ea2b 100644 --- a/utils/TableGen/CodeGenIntrinsics.h +++ b/utils/TableGen/CodeGenIntrinsics.h @@ -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 }; diff --git a/utils/TableGen/CodeGenTarget.cpp b/utils/TableGen/CodeGenTarget.cpp index cf6793570a2..dfa9526cc91 100644 --- a/utils/TableGen/CodeGenTarget.cpp +++ b/utils/TableGen/CodeGenTarget.cpp @@ -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)); diff --git a/utils/TableGen/IntrinsicEmitter.cpp b/utils/TableGen/IntrinsicEmitter.cpp index 941c0537d62..9e2bb9d87f2 100644 --- a/utils/TableGen/IntrinsicEmitter.cpp +++ b/utils/TableGen/IntrinsicEmitter.cpp @@ -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 &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"; }