diff options
-rw-r--r-- | llvm/docs/LangRef.rst | 4 | ||||
-rw-r--r-- | llvm/include/llvm/Bitcode/LLVMBitCodes.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Attributes.h | 1 | ||||
-rw-r--r-- | llvm/include/llvm/IR/Function.h | 9 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Attributes.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 3 | ||||
-rw-r--r-- | llvm/test/Bindings/llvm-c/Inputs/invalid.ll.bc | bin | 332 -> 624 bytes | |||
-rw-r--r-- | llvm/test/Bindings/llvm-c/invalid-bitcode.test | 2 | ||||
-rw-r--r-- | llvm/test/Bitcode/attributes.ll | 10 | ||||
-rw-r--r-- | llvm/test/Bitcode/compatibility.ll | 17 | ||||
-rw-r--r-- | llvm/test/Bitcode/invalid.ll | 2 | ||||
-rw-r--r-- | llvm/test/Bitcode/invalid.ll.bc | bin | 332 -> 624 bytes | |||
-rw-r--r-- | llvm/test/LTO/X86/Inputs/invalid.ll.bc | bin | 332 -> 624 bytes | |||
-rw-r--r-- | llvm/test/LTO/X86/invalid.ll | 2 |
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 Binary files differindex a85c3644b3a..8f7474b9e46 100644 --- a/llvm/test/Bindings/llvm-c/Inputs/invalid.ll.bc +++ b/llvm/test/Bindings/llvm-c/Inputs/invalid.ll.bc 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 Binary files differindex a85c3644b3a..8f7474b9e46 100644 --- a/llvm/test/Bitcode/invalid.ll.bc +++ b/llvm/test/Bitcode/invalid.ll.bc diff --git a/llvm/test/LTO/X86/Inputs/invalid.ll.bc b/llvm/test/LTO/X86/Inputs/invalid.ll.bc Binary files differindex a85c3644b3a..8f7474b9e46 100644 --- a/llvm/test/LTO/X86/Inputs/invalid.ll.bc +++ b/llvm/test/LTO/X86/Inputs/invalid.ll.bc 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) |