Skip to content

Commit 595c615

Browse files
committed
[IR] Adds mustprogress as a LLVM IR attribute
This adds the LLVM IR attribute `mustprogress` as defined in LangRef through D86233. This attribute will be applied to functions with in languages like C++ where forward progress is guaranteed. Functions without this attribute are not required to make progress. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D85393
1 parent 08c8d5b commit 595c615

15 files changed

+54
-0
lines changed

llvm/include/llvm/Bitcode/LLVMBitCodes.h

+1
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,7 @@ enum AttributeKindCodes {
650650
ATTR_KIND_NULL_POINTER_IS_VALID = 67,
651651
ATTR_KIND_NOUNDEF = 68,
652652
ATTR_KIND_BYREF = 69,
653+
ATTR_KIND_MUSTPROGRESS = 70,
653654
};
654655

655656
enum ComdatSelectionKindCodes {

llvm/include/llvm/IR/Attributes.td

+3
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,9 @@ def WriteOnly : EnumAttr<"writeonly">;
235235
/// Zero extended before/after call.
236236
def ZExt : EnumAttr<"zeroext">;
237237

238+
/// Function is required to make Forward Progress.
239+
def MustProgress : TypeAttr<"mustprogress">;
240+
238241
/// Target-independent string attributes.
239242
def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
240243
def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;

llvm/include/llvm/IR/Function.h

+7
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,13 @@ class Function : public GlobalObject, public ilist_node<Function> {
622622
addFnAttr(Attribute::NoRecurse);
623623
}
624624

625+
/// Determine if the function is required to make forward progress.
626+
bool mustProgress() const {
627+
return hasFnAttribute(Attribute::MustProgress) ||
628+
hasFnAttribute(Attribute::WillReturn);
629+
}
630+
void setMustProgress() { addFnAttr(Attribute::MustProgress); }
631+
625632
/// True if the ABI mandates (or the user requested) that this
626633
/// function be in a unwind table.
627634
bool hasUWTable() const {

llvm/lib/AsmParser/LLLexer.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,7 @@ lltok::Kind LLLexer::LexIdentifier() {
698698
KEYWORD(zeroext);
699699
KEYWORD(immarg);
700700
KEYWORD(byref);
701+
KEYWORD(mustprogress);
701702

702703
KEYWORD(type);
703704
KEYWORD(opaque);

llvm/lib/AsmParser/LLParser.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,9 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B,
13091309
case lltok::kw_inlinehint: B.addAttribute(Attribute::InlineHint); break;
13101310
case lltok::kw_jumptable: B.addAttribute(Attribute::JumpTable); break;
13111311
case lltok::kw_minsize: B.addAttribute(Attribute::MinSize); break;
1312+
case lltok::kw_mustprogress:
1313+
B.addAttribute(Attribute::MustProgress);
1314+
break;
13121315
case lltok::kw_naked: B.addAttribute(Attribute::Naked); break;
13131316
case lltok::kw_nobuiltin: B.addAttribute(Attribute::NoBuiltin); break;
13141317
case lltok::kw_noduplicate: B.addAttribute(Attribute::NoDuplicate); break;
@@ -1724,6 +1727,7 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) {
17241727
case lltok::kw_inlinehint:
17251728
case lltok::kw_jumptable:
17261729
case lltok::kw_minsize:
1730+
case lltok::kw_mustprogress:
17271731
case lltok::kw_naked:
17281732
case lltok::kw_nobuiltin:
17291733
case lltok::kw_noduplicate:
@@ -1828,6 +1832,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
18281832
case lltok::kw_inlinehint:
18291833
case lltok::kw_jumptable:
18301834
case lltok::kw_minsize:
1835+
case lltok::kw_mustprogress:
18311836
case lltok::kw_naked:
18321837
case lltok::kw_nobuiltin:
18331838
case lltok::kw_noduplicate:

llvm/lib/AsmParser/LLToken.h

+1
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ enum Kind {
241241
kw_zeroext,
242242
kw_immarg,
243243
kw_byref,
244+
kw_mustprogress,
244245

245246
kw_type,
246247
kw_opaque,

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -1535,6 +1535,8 @@ static Attribute::AttrKind getAttrFromCode(uint64_t Code) {
15351535
return Attribute::NoUndef;
15361536
case bitc::ATTR_KIND_BYREF:
15371537
return Attribute::ByRef;
1538+
case bitc::ATTR_KIND_MUSTPROGRESS:
1539+
return Attribute::MustProgress;
15381540
}
15391541
}
15401542

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,8 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {
743743
return bitc::ATTR_KIND_NOUNDEF;
744744
case Attribute::ByRef:
745745
return bitc::ATTR_KIND_BYREF;
746+
case Attribute::MustProgress:
747+
return bitc::ATTR_KIND_MUSTPROGRESS;
746748
case Attribute::EndAttrKinds:
747749
llvm_unreachable("Can not encode end-attribute kinds marker.");
748750
case Attribute::None:

llvm/lib/IR/Attributes.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
451451
return "immarg";
452452
if (hasAttribute(Attribute::NoUndef))
453453
return "noundef";
454+
if (hasAttribute(Attribute::MustProgress))
455+
return "mustprogress";
454456

455457
const bool IsByVal = hasAttribute(Attribute::ByVal);
456458
if (IsByVal || hasAttribute(Attribute::StructRet)) {

llvm/lib/IR/Verifier.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -1613,6 +1613,7 @@ static bool isFuncOnlyAttr(Attribute::AttrKind Kind) {
16131613
case Attribute::Speculatable:
16141614
case Attribute::StrictFP:
16151615
case Attribute::NullPointerIsValid:
1616+
case Attribute::MustProgress:
16161617
return true;
16171618
default:
16181619
break;

llvm/lib/Transforms/Utils/CodeExtractor.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,7 @@ Function *CodeExtractor::constructFunction(const ValueSet &inputs,
931931
case Attribute::StrictFP:
932932
case Attribute::UWTable:
933933
case Attribute::NoCfCheck:
934+
case Attribute::MustProgress:
934935
break;
935936
}
936937

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
; RUN: not llvm-as < %s 2>&1 | FileCheck %s
2+
3+
; CHECK: [[@LINE+1]]:35: error: invalid use of function-only attribute
4+
define void @test_mustprogress(i8 mustprogress %a) {
5+
ret void
6+
}
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
; RUN: not llvm-as < %s 2>&1 | FileCheck %s
2+
3+
; CHECK: [[@LINE+1]]:8: error: invalid use of function-only attribute
4+
define mustprogress void @test_mustprogress(i8 %a) {
5+
ret void
6+
}
7+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
; RUN: not llvm-as < %s 2>&1 | FileCheck %s
2+
3+
; CHECK: [[@LINE+1]]:52: error: expected '{' in function body
4+
define i32* @test_mustprogress(i8 %a) mustprogress 8 {
5+
ret void
6+
}
7+

llvm/test/Bitcode/attributes.ll

+7
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,12 @@ define void @f67(i32* byref(i32) %a)
398398
ret void
399399
}
400400

401+
; CHECK: define void @f68() #41
402+
define void @f68() mustprogress
403+
{
404+
ret void
405+
}
406+
401407
; CHECK: attributes #0 = { noreturn }
402408
; CHECK: attributes #1 = { nounwind }
403409
; CHECK: attributes #2 = { readnone }
@@ -439,4 +445,5 @@ define void @f67(i32* byref(i32) %a)
439445
; CHECK: attributes #38 = { nosync }
440446
; CHECK: attributes #39 = { sanitize_memtag }
441447
; CHECK: attributes #40 = { null_pointer_is_valid }
448+
; CHECK: attributes #41 = { mustprogress }
442449
; CHECK: attributes #[[NOBUILTIN]] = { nobuiltin }

0 commit comments

Comments
 (0)