From ff9e08baf983da23bfd34da7d5260697de963f48 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 27 May 2012 23:20:41 +0000 Subject: [PATCH] rdar://11542750 - llvm.trap should be marked no return. llvm-svn: 157551 --- llvm/docs/LangRef.html | 4 ++-- llvm/include/llvm/Intrinsics.td | 4 +++- llvm/test/Feature/intrinsics.ll | 10 ++++++++++ llvm/utils/TableGen/CodeGenIntrinsics.h | 5 ++++- llvm/utils/TableGen/CodeGenTarget.cpp | 3 +++ llvm/utils/TableGen/IntrinsicEmitter.cpp | 25 +++++++++++++++++++++---- 6 files changed, 43 insertions(+), 8 deletions(-) diff --git a/llvm/docs/LangRef.html b/llvm/docs/LangRef.html index a781992..ab0f9e1 100644 --- a/llvm/docs/LangRef.html +++ b/llvm/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/llvm/include/llvm/Intrinsics.td b/llvm/include/llvm/Intrinsics.td index 794848c..1ebf13b 100644 --- a/llvm/include/llvm/Intrinsics.td +++ b/llvm/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/llvm/test/Feature/intrinsics.ll b/llvm/test/Feature/intrinsics.ll index c4e3db6..9e7dc6d 100644 --- a/llvm/test/Feature/intrinsics.ll +++ b/llvm/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/llvm/utils/TableGen/CodeGenIntrinsics.h b/llvm/utils/TableGen/CodeGenIntrinsics.h index 3f6ba61..6efe952 100644 --- a/llvm/utils/TableGen/CodeGenIntrinsics.h +++ b/llvm/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/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp index cf67935..dfa9526 100644 --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/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/llvm/utils/TableGen/IntrinsicEmitter.cpp b/llvm/utils/TableGen/IntrinsicEmitter.cpp index 941c053..9e2bb9d 100644 --- a/llvm/utils/TableGen/IntrinsicEmitter.cpp +++ b/llvm/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"; } -- 2.7.4