diff --git a/llvm/include/llvm/IR/Attributes.td b/llvm/include/llvm/IR/Attributes.td --- a/llvm/include/llvm/IR/Attributes.td +++ b/llvm/include/llvm/IR/Attributes.td @@ -236,7 +236,7 @@ def ZExt : EnumAttr<"zeroext">; /// Function is permitted to not make Forward Progress. -def MayNotProgress : TypeAttr<"maynotprogress">; +def MustProgress : TypeAttr<"mustprogress">; /// Target-independent string attributes. def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">; @@ -291,3 +291,4 @@ def : MergeRule<"adjustCallerStackProbeSize">; def : MergeRule<"adjustMinLegalVectorWidth">; def : MergeRule<"adjustNullPointerValidAttr">; +def : MergeRule<"setOR">; diff --git a/llvm/test/Transforms/Inline/mustprogress.ll b/llvm/test/Transforms/Inline/mustprogress.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/Inline/mustprogress.ll @@ -0,0 +1,42 @@ +; RUN: opt -inline -S < %s | FileCheck %s + +;; Original C Code: +;; void callee(int a, int b) { +;; for (;a < b;) ; +;; while(1) ; +;; } +;; void caller() { +;; callee(0, 5); +;; } + +define void @callee(i32 %a, i32 %b) #0 { +entry: + br label %for.cond +for.cond: + %cmp = icmp slt i32 %a, %b + br i1 %cmp, label %for.body, label %for.end +for.body: + br label %for.cond +for.end: + br label %while.body +while.body: + br label %while.body +} + +; CHECK: define void @caller() [[ATTR0:#.*]] { +; CHECK: entry: +; CHECK: br label %[[FOR_COND:.*]] +; CHECK: [[FOR_COND]]: +; CHECK: br label %[[FOR_COND]] +; CHECK: ret void +; CHECK: } + +define void @caller() { +entry: + call void @callee(i32 0, i32 5) + ret void +} + +; CHECK: attributes [[ATTR0]] = { mustprogress } + +attributes #0 = { mustprogress }