summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/docs/LangRef.rst4
-rw-r--r--llvm/include/llvm/Bitcode/LLVMBitCodes.h3
-rw-r--r--llvm/include/llvm/IR/Attributes.h1
-rw-r--r--llvm/include/llvm/IR/Function.h9
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp1
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp1
-rw-r--r--llvm/lib/AsmParser/LLToken.h1
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp2
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp2
-rw-r--r--llvm/lib/IR/Attributes.cpp3
-rw-r--r--llvm/lib/IR/Verifier.cpp3
-rw-r--r--llvm/test/Bindings/llvm-c/Inputs/invalid.ll.bcbin332 -> 624 bytes
-rw-r--r--llvm/test/Bindings/llvm-c/invalid-bitcode.test2
-rw-r--r--llvm/test/Bitcode/attributes.ll10
-rw-r--r--llvm/test/Bitcode/compatibility.ll17
-rw-r--r--llvm/test/Bitcode/invalid.ll2
-rw-r--r--llvm/test/Bitcode/invalid.ll.bcbin332 -> 624 bytes
-rw-r--r--llvm/test/LTO/X86/Inputs/invalid.ll.bcbin332 -> 624 bytes
-rw-r--r--llvm/test/LTO/X86/invalid.ll2
19 files changed, 49 insertions, 14 deletions
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 507c3bfd334..d2bba5c8a74 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -1277,6 +1277,10 @@ example:
This function attribute indicates that the function never returns
normally. This produces undefined behavior at runtime if the
function ever does dynamically return.
+``norecurse``
+ This function attribute indicates that the function does not call itself
+ either directly or indirectly down any possible call path. This produces
+ undefined behavior at runtime if the function ever does recurse.
``nounwind``
This function attribute indicates that the function never raises an
exception. If the function does raise an exception, its runtime
diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
index 08d88a20454..b79c2785a61 100644
--- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h
+++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h
@@ -466,7 +466,8 @@ enum { BITCODE_CURRENT_EPOCH = 0 };
ATTR_KIND_SAFESTACK = 44,
ATTR_KIND_ARGMEMONLY = 45,
ATTR_KIND_SWIFT_SELF = 46,
- ATTR_KIND_SWIFT_ERROR = 47
+ ATTR_KIND_SWIFT_ERROR = 47,
+ ATTR_KIND_NO_RECURSE = 48
};
enum ComdatSelectionKindCodes {
diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h
index 15f48fa38d9..b3984330b17 100644
--- a/llvm/include/llvm/IR/Attributes.h
+++ b/llvm/include/llvm/IR/Attributes.h
@@ -86,6 +86,7 @@ public:
NoDuplicate, ///< Call cannot be duplicated
NoImplicitFloat, ///< Disable implicit floating point insts
NoInline, ///< inline=never
+ NoRecurse, ///< The function does not recurse
NonLazyBind, ///< Function is called early and/or
///< often, so lazy binding isn't worthwhile
NonNull, ///< Pointer is known to be not null
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index b8e22af4bfe..71822a462da 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -329,6 +329,15 @@ public:
addFnAttr(Attribute::Convergent);
}
+ /// Determine if the function is known not to recurse, directly or
+ /// indirectly.
+ bool doesNotRecurse() const {
+ return AttributeSets.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::NoRecurse);
+ }
+ void setDoesNotRecurse() {
+ addFnAttr(Attribute::NoRecurse);
+ }
/// @brief True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 2eb5f0bf45d..82d6eb7788c 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -616,6 +616,7 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(noduplicate);
KEYWORD(noimplicitfloat);
KEYWORD(noinline);
+ KEYWORD(norecurse);
KEYWORD(nonlazybind);
KEYWORD(nonnull);
KEYWORD(noredzone);
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 1c219ad6cd8..7feb99d555c 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -998,6 +998,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
case lltok::kw_nonlazybind: B.addAttribute(Attribute::NonLazyBind); break;
case lltok::kw_noredzone: B.addAttribute(Attribute::NoRedZone); break;
case lltok::kw_noreturn: B.addAttribute(Attribute::NoReturn); break;
+ case lltok::kw_norecurse: B.addAttribute(Attribute::NoRecurse); break;
case lltok::kw_nounwind: B.addAttribute(Attribute::NoUnwind); break;
case lltok::kw_optnone: B.addAttribute(Attribute::OptimizeNone); break;
case lltok::kw_optsize: B.addAttribute(Attribute::OptimizeForSize); break;
diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h
index 06b5f9b0800..ecd6481e6fa 100644
--- a/llvm/lib/AsmParser/LLToken.h
+++ b/llvm/lib/AsmParser/LLToken.h
@@ -123,6 +123,7 @@ namespace lltok {
kw_noduplicate,
kw_noimplicitfloat,
kw_noinline,
+ kw_norecurse,
kw_nonlazybind,
kw_nonnull,
kw_noredzone,
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 7c1b208c626..bc846192fcf 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -1305,6 +1305,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
return Attribute::NoImplicitFloat;
case bitc::ATTR_KIND_NO_INLINE:
return Attribute::NoInline;
+ case bitc::ATTR_KIND_NO_RECURSE:
+ return Attribute::NoRecurse;
case bitc::ATTR_KIND_NON_LAZY_BIND:
return Attribute::NonLazyBind;
case bitc::ATTR_KIND_NON_NULL:
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index c73b099e27f..941e54765f5 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -202,6 +202,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
return bitc::ATTR_KIND_NO_IMPLICIT_FLOAT;
case Attribute::NoInline:
return bitc::ATTR_KIND_NO_INLINE;
+ case Attribute::NoRecurse:
+ return bitc::ATTR_KIND_NO_RECURSE;
case Attribute::NonLazyBind:
return bitc::ATTR_KIND_NON_LAZY_BIND;
case Attribute::NonNull:
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 2586cb54c3e..bdefe5917fe 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -232,6 +232,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return "noredzone";
if (hasAttribute(Attribute::NoReturn))
return "noreturn";
+ if (hasAttribute(Attribute::NoRecurse))
+ return "norecurse";
if (hasAttribute(Attribute::NoUnwind))
return "nounwind";
if (hasAttribute(Attribute::OptimizeNone))
@@ -442,6 +444,7 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
case Attribute::JumpTable: return 1ULL << 45;
case Attribute::Convergent: return 1ULL << 46;
case Attribute::SafeStack: return 1ULL << 47;
+ case Attribute::NoRecurse: return 1ULL << 48;
case Attribute::Dereferenceable:
llvm_unreachable("dereferenceable attribute not supported in raw format");
break;
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 813f9ca6744..0fce50e8440 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -1233,7 +1233,8 @@ void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
I->getKindAsEnum() == Attribute::OptimizeNone ||
I->getKindAsEnum() == Attribute::JumpTable ||
I->getKindAsEnum() == Attribute::Convergent ||
- I->getKindAsEnum() == Attribute::ArgMemOnly) {
+ I->getKindAsEnum() == Attribute::ArgMemOnly ||
+ I->getKindAsEnum() == Attribute::NoRecurse) {
if (!isFunction) {
CheckFailed("Attribute '" + I->getAsString() +
"' only applies to functions!", V);
diff --git a/llvm/test/Bindings/llvm-c/Inputs/invalid.ll.bc b/llvm/test/Bindings/llvm-c/Inputs/invalid.ll.bc
index a85c3644b3a..8f7474b9e46 100644
--- a/llvm/test/Bindings/llvm-c/Inputs/invalid.ll.bc
+++ b/llvm/test/Bindings/llvm-c/Inputs/invalid.ll.bc
Binary files differ
diff --git a/llvm/test/Bindings/llvm-c/invalid-bitcode.test b/llvm/test/Bindings/llvm-c/invalid-bitcode.test
index 6318a9bf13d..9219f36eb24 100644
--- a/llvm/test/Bindings/llvm-c/invalid-bitcode.test
+++ b/llvm/test/Bindings/llvm-c/invalid-bitcode.test
@@ -1,3 +1,3 @@
; RUN: not llvm-c-test --module-dump < %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
-CHECK: Error parsing bitcode: Unknown attribute kind (48)
+CHECK: Error parsing bitcode: Unknown attribute kind (50)
diff --git a/llvm/test/Bitcode/attributes.ll b/llvm/test/Bitcode/attributes.ll
index 0cf0745175e..e3eda4887b3 100644
--- a/llvm/test/Bitcode/attributes.ll
+++ b/llvm/test/Bitcode/attributes.ll
@@ -204,7 +204,7 @@ define void @f34()
; CHECK: define void @f34()
{
call void @nobuiltin() nobuiltin
-; CHECK: call void @nobuiltin() #27
+; CHECK: call void @nobuiltin() #28
ret void;
}
@@ -272,6 +272,11 @@ define "string_attribute_with_value"="value" void @f46(i32 "string_attribute_wit
ret void
}
+; CHECK: define void @f47() #27
+define void @f47() norecurse {
+ ret void
+}
+
; CHECK: attributes #0 = { noreturn }
; CHECK: attributes #1 = { nounwind }
; CHECK: attributes #2 = { readnone }
@@ -299,4 +304,5 @@ define "string_attribute_with_value"="value" void @f46(i32 "string_attribute_wit
; CHECK: attributes #24 = { jumptable }
; CHECK: attributes #25 = { convergent }
; CHECK: attributes #26 = { argmemonly }
-; CHECK: attributes #27 = { nobuiltin }
+; CHECK: attributes #27 = { norecurse }
+; CHECK: attributes #28 = { nobuiltin }
diff --git a/llvm/test/Bitcode/compatibility.ll b/llvm/test/Bitcode/compatibility.ll
index 4c6349c803c..73c24f0370a 100644
--- a/llvm/test/Bitcode/compatibility.ll
+++ b/llvm/test/Bitcode/compatibility.ll
@@ -501,6 +501,8 @@ declare void @f.uwtable() uwtable
; CHECK: declare void @f.uwtable() #30
declare void @f.kvpair() "cpu"="cortex-a8"
; CHECK:declare void @f.kvpair() #31
+declare void @f.norecurse() norecurse
+; CHECK: declare void @f.norecurse() #32
; Functions -- section
declare void @f.section() section "80"
@@ -559,7 +561,7 @@ declare void @f.prologuearray() prologue [4 x i32] [i32 0, i32 1, i32 2, i32 3]
; Functions -- Personality constant
declare void @llvm.donothing() nounwind readnone
-; CHECK: declare void @llvm.donothing() #32
+; CHECK: declare void @llvm.donothing() #33
define void @f.no_personality() personality i8 3 {
; CHECK: define void @f.no_personality() personality i8 3
invoke void @llvm.donothing() to label %normal unwind label %exception
@@ -1125,7 +1127,7 @@ exit:
; CHECK: select <2 x i1> <i1 true, i1 false>, <2 x i8> <i8 2, i8 3>, <2 x i8> <i8 3, i8 2>
call void @f.nobuiltin() builtin
- ; CHECK: call void @f.nobuiltin() #36
+ ; CHECK: call void @f.nobuiltin() #37
call fastcc noalias i32* @f.noalias() noinline
; CHECK: call fastcc noalias i32* @f.noalias() #12
@@ -1497,11 +1499,12 @@ normal:
; CHECK: attributes #29 = { "thunk" }
; CHECK: attributes #30 = { uwtable }
; CHECK: attributes #31 = { "cpu"="cortex-a8" }
-; CHECK: attributes #32 = { nounwind readnone }
-; CHECK: attributes #33 = { nounwind readonly argmemonly }
-; CHECK: attributes #34 = { nounwind argmemonly }
-; CHECK: attributes #35 = { nounwind readonly }
-; CHECK: attributes #36 = { builtin }
+; CHECK: attributes #32 = { norecurse }
+; CHECK: attributes #33 = { nounwind readnone }
+; CHECK: attributes #34 = { nounwind readonly argmemonly }
+; CHECK: attributes #35 = { nounwind argmemonly }
+; CHECK: attributes #36 = { nounwind readonly }
+; CHECK: attributes #37 = { builtin }
;; Metadata
diff --git a/llvm/test/Bitcode/invalid.ll b/llvm/test/Bitcode/invalid.ll
index df9fec8772d..2f2eca94321 100644
--- a/llvm/test/Bitcode/invalid.ll
+++ b/llvm/test/Bitcode/invalid.ll
@@ -1,6 +1,6 @@
; RUN: not llvm-dis < %s.bc 2>&1 | FileCheck %s
-; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (48)
+; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Unknown attribute kind (50)
; invalid.ll.bc has an invalid attribute number.
; The test checks that LLVM reports the error and doesn't access freed memory
diff --git a/llvm/test/Bitcode/invalid.ll.bc b/llvm/test/Bitcode/invalid.ll.bc
index a85c3644b3a..8f7474b9e46 100644
--- a/llvm/test/Bitcode/invalid.ll.bc
+++ b/llvm/test/Bitcode/invalid.ll.bc
Binary files differ
diff --git a/llvm/test/LTO/X86/Inputs/invalid.ll.bc b/llvm/test/LTO/X86/Inputs/invalid.ll.bc
index a85c3644b3a..8f7474b9e46 100644
--- a/llvm/test/LTO/X86/Inputs/invalid.ll.bc
+++ b/llvm/test/LTO/X86/Inputs/invalid.ll.bc
Binary files differ
diff --git a/llvm/test/LTO/X86/invalid.ll b/llvm/test/LTO/X86/invalid.ll
index 5b6996d4ad3..3de11112c71 100644
--- a/llvm/test/LTO/X86/invalid.ll
+++ b/llvm/test/LTO/X86/invalid.ll
@@ -1,4 +1,4 @@
; RUN: not llvm-lto %S/Inputs/invalid.ll.bc 2>&1 | FileCheck %s
-; CHECK: llvm-lto{{.*}}: error loading file '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (48)
+; CHECK: llvm-lto{{.*}}: error loading file '{{.*}}/Inputs/invalid.ll.bc': Unknown attribute kind (50)
OpenPOWER on IntegriCloud