[clang] ac73b73 - [clang] Add mustprogress and llvm.loop.mustprogress attribute deduction
Atmn Patel via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 4 19:03:39 PST 2020
Author: Atmn Patel
Date: 2020-11-04T22:03:14-05:00
New Revision: ac73b73c16526c9e51943759ea6cab285a57e33f
URL: https://github.com/llvm/llvm-project/commit/ac73b73c16526c9e51943759ea6cab285a57e33f
DIFF: https://github.com/llvm/llvm-project/commit/ac73b73c16526c9e51943759ea6cab285a57e33f.diff
LOG: [clang] Add mustprogress and llvm.loop.mustprogress attribute deduction
Since C++11, the C++ standard has a forward progress guarantee
[intro.progress], so all such functions must have the `mustprogress`
requirement. In addition, from C11 and onwards, loops without a non-zero
constant conditional or no conditional are also required to make
progress (C11 6.8.5p6). This patch implements these attribute deductions
so they can be used by the optimization passes.
Differential Revision: https://reviews.llvm.org/D86841
Added:
clang/test/CodeGen/attr-mustprogress-0.c
clang/test/CodeGen/attr-mustprogress-0.cpp
clang/test/CodeGen/attr-mustprogress-1.c
clang/test/CodeGen/attr-mustprogress-1.cpp
Modified:
clang/lib/CodeGen/CGLoopInfo.cpp
clang/lib/CodeGen/CGLoopInfo.h
clang/lib/CodeGen/CGStmt.cpp
clang/lib/CodeGen/CodeGenFunction.cpp
clang/lib/CodeGen/CodeGenFunction.h
clang/test/CodeGen/address-safety-attr-flavors.cpp
clang/test/CodeGen/address-safety-attr.cpp
clang/test/CodeGen/memtag-attr.cpp
clang/test/CodeGen/no-builtin.cpp
clang/test/CodeGen/pragma-do-while.cpp
clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp
clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp
clang/test/CodeGenCXX/debug-info-line-if.cpp
clang/test/CodeGenCXX/debug-info-loops.cpp
clang/test/CodeGenCXX/fno-unroll-loops-metadata.cpp
clang/test/CodeGenCXX/pragma-followup_inner.cpp
clang/test/CodeGenCXX/pragma-followup_outer.cpp
clang/test/CodeGenCXX/pragma-loop-distribute.cpp
clang/test/CodeGenCXX/pragma-loop-pr27643.cpp
clang/test/CodeGenCXX/pragma-loop-predicate.cpp
clang/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
clang/test/CodeGenCXX/pragma-loop-safety-nested.cpp
clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp
clang/test/CodeGenCXX/pragma-loop-safety.cpp
clang/test/CodeGenCXX/pragma-loop.cpp
clang/test/CodeGenCXX/pragma-pipeline.cpp
clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp
clang/test/CodeGenCXX/pragma-unroll.cpp
clang/test/CodeGenCXX/thunks-ehspec.cpp
clang/test/CodeGenCXX/thunks.cpp
clang/test/OpenMP/simd_metadata.c
clang/test/Profile/c-unprofiled-blocks.c
clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp
index a02d832b84b4..be4993e802f8 100644
--- a/clang/lib/CodeGen/CGLoopInfo.cpp
+++ b/clang/lib/CodeGen/CGLoopInfo.cpp
@@ -411,10 +411,14 @@ MDNode *LoopInfo::createMetadata(
LoopProperties.push_back(EndLoc.getAsMDNode());
}
+ LLVMContext &Ctx = Header->getContext();
+ if (Attrs.MustProgress)
+ LoopProperties.push_back(
+ MDNode::get(Ctx, MDString::get(Ctx, "llvm.loop.mustprogress")));
+
assert(!!AccGroup == Attrs.IsParallel &&
"There must be an access group iff the loop is parallel");
if (Attrs.IsParallel) {
- LLVMContext &Ctx = Header->getContext();
LoopProperties.push_back(MDNode::get(
Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
}
@@ -431,7 +435,7 @@ LoopAttributes::LoopAttributes(bool IsParallel)
VectorizePredicateEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0),
DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false),
- PipelineInitiationInterval(0) {}
+ PipelineInitiationInterval(0), MustProgress(false) {}
void LoopAttributes::clear() {
IsParallel = false;
@@ -446,6 +450,7 @@ void LoopAttributes::clear() {
DistributeEnable = LoopAttributes::Unspecified;
PipelineDisabled = false;
PipelineInitiationInterval = 0;
+ MustProgress = false;
}
LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
@@ -469,7 +474,7 @@ LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
Attrs.UnrollEnable == LoopAttributes::Unspecified &&
Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
Attrs.DistributeEnable == LoopAttributes::Unspecified && !StartLoc &&
- !EndLoc)
+ !EndLoc && !Attrs.MustProgress)
return;
TempLoopID = MDNode::getTemporary(Header->getContext(), None);
@@ -570,8 +575,7 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
const clang::CodeGenOptions &CGOpts,
ArrayRef<const clang::Attr *> Attrs,
const llvm::DebugLoc &StartLoc,
- const llvm::DebugLoc &EndLoc) {
-
+ const llvm::DebugLoc &EndLoc, bool MustProgress) {
// Identify loop hint attributes from Attrs.
for (const auto *Attr : Attrs) {
const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(Attr);
@@ -748,6 +752,8 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
}
}
+ setMustProgress(MustProgress);
+
if (CGOpts.OptimizationLevel > 0)
// Disable unrolling for the loop, if unrolling is disabled (via
// -fno-unroll-loops) and no pragmas override the decision.
diff --git a/clang/lib/CodeGen/CGLoopInfo.h b/clang/lib/CodeGen/CGLoopInfo.h
index e379c64c99a8..2c13e020c5df 100644
--- a/clang/lib/CodeGen/CGLoopInfo.h
+++ b/clang/lib/CodeGen/CGLoopInfo.h
@@ -75,6 +75,9 @@ struct LoopAttributes {
/// Value for llvm.loop.pipeline.iicount metadata.
unsigned PipelineInitiationInterval;
+
+ /// Value for whether the loop is required to make progress.
+ bool MustProgress;
};
/// Information used when generating a structured loop.
@@ -205,7 +208,7 @@ class LoopInfoStack {
void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx,
const clang::CodeGenOptions &CGOpts,
llvm::ArrayRef<const Attr *> Attrs, const llvm::DebugLoc &StartLoc,
- const llvm::DebugLoc &EndLoc);
+ const llvm::DebugLoc &EndLoc, bool MustProgress = false);
/// End the current loop.
void pop();
@@ -272,6 +275,9 @@ class LoopInfoStack {
StagedAttrs.PipelineInitiationInterval = C;
}
+ /// Set no progress for the next loop pushed.
+ void setMustProgress(bool P) { StagedAttrs.MustProgress = P; }
+
private:
/// Returns true if there is LoopInfo on the stack.
bool hasInfo() const { return !Active.empty(); }
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 38e5ce1ab11b..972da3d4ea2d 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -765,11 +765,6 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond");
EmitBlock(LoopHeader.getBlock());
- const SourceRange &R = S.getSourceRange();
- LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), CGM.getCodeGenOpts(),
- WhileAttrs, SourceLocToDebugLoc(R.getBegin()),
- SourceLocToDebugLoc(R.getEnd()));
-
// Create an exit block for when the condition fails, which will
// also become the break target.
JumpDest LoopExit = getJumpDestInCurrentScope("while.end");
@@ -797,9 +792,19 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
// while(1) is common, avoid extra exit blocks. Be sure
// to correctly handle break/continue though.
bool EmitBoolCondBranch = true;
- if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
- if (C->isOne())
+ bool LoopMustProgress = false;
+ if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) {
+ if (C->isOne()) {
EmitBoolCondBranch = false;
+ FnIsMustProgress = false;
+ }
+ } else if (LanguageRequiresProgress())
+ LoopMustProgress = true;
+
+ const SourceRange &R = S.getSourceRange();
+ LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), CGM.getCodeGenOpts(),
+ WhileAttrs, SourceLocToDebugLoc(R.getBegin()),
+ SourceLocToDebugLoc(R.getEnd()), LoopMustProgress);
// As long as the condition is true, go to the loop body.
llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
@@ -875,11 +880,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
EmitBlock(LoopCond.getBlock());
- const SourceRange &R = S.getSourceRange();
- LoopStack.push(LoopBody, CGM.getContext(), CGM.getCodeGenOpts(), DoAttrs,
- SourceLocToDebugLoc(R.getBegin()),
- SourceLocToDebugLoc(R.getEnd()));
-
// C99 6.8.5.2: "The evaluation of the controlling expression takes place
// after each execution of the loop body."
@@ -893,9 +893,19 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
// "do {} while (0)" is common in macros, avoid extra blocks. Be sure
// to correctly handle break/continue though.
bool EmitBoolCondBranch = true;
- if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
+ bool LoopMustProgress = false;
+ if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal)) {
if (C->isZero())
EmitBoolCondBranch = false;
+ else if (C->isOne())
+ FnIsMustProgress = false;
+ } else if (LanguageRequiresProgress())
+ LoopMustProgress = true;
+
+ const SourceRange &R = S.getSourceRange();
+ LoopStack.push(LoopBody, CGM.getContext(), CGM.getCodeGenOpts(), DoAttrs,
+ SourceLocToDebugLoc(R.getBegin()),
+ SourceLocToDebugLoc(R.getEnd()), LoopMustProgress);
// As long as the condition is true, iterate the loop.
if (EmitBoolCondBranch) {
@@ -933,10 +943,21 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
llvm::BasicBlock *CondBlock = Continue.getBlock();
EmitBlock(CondBlock);
+ bool LoopMustProgress = false;
+ Expr::EvalResult Result;
+ if (LanguageRequiresProgress()) {
+ if (!S.getCond()) {
+ LoopMustProgress = true;
+ FnIsMustProgress = false;
+ } else if (!S.getCond()->EvaluateAsInt(Result, getContext())) {
+ LoopMustProgress = true;
+ }
+ }
+
const SourceRange &R = S.getSourceRange();
LoopStack.push(CondBlock, CGM.getContext(), CGM.getCodeGenOpts(), ForAttrs,
SourceLocToDebugLoc(R.getBegin()),
- SourceLocToDebugLoc(R.getEnd()));
+ SourceLocToDebugLoc(R.getEnd()), LoopMustProgress);
// If the for loop doesn't have an increment we can just use the
// condition as the continue block. Otherwise we'll need to create
@@ -972,6 +993,11 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond());
llvm::MDNode *Weights = createProfileOrBranchWeightsForLoop(
S.getCond(), getProfileCount(S.getBody()), S.getBody());
+
+ if (llvm::ConstantInt *C = dyn_cast<llvm::ConstantInt>(BoolCondVal))
+ if (C->isOne())
+ FnIsMustProgress = false;
+
Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights);
if (ExitBlock != LoopExit.getBlock()) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index f1fe8f92c07c..ea33ea056a2d 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1159,10 +1159,18 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
void CodeGenFunction::EmitFunctionBody(const Stmt *Body) {
incrementProfileCounter(Body);
+ if (CPlusPlusWithProgress())
+ FnIsMustProgress = true;
+
if (const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
EmitCompoundStmtWithoutScope(*S);
else
EmitStmt(Body);
+
+ // This is checked after emitting the function body so we know if there
+ // are any permitted infinite loops.
+ if (FnIsMustProgress)
+ CurFn->addFnAttr(llvm::Attribute::MustProgress);
}
/// When instrumenting to collect profile data, the counts for some blocks
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 346253a68cbf..8cde8601022b 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -502,6 +502,26 @@ class CodeGenFunction : public CodeGenTypeCache {
/// True if the current statement has nomerge attribute.
bool InNoMergeAttributedStmt = false;
+ /// True if the current function should be marked mustprogress.
+ bool FnIsMustProgress = false;
+
+ /// True if the C++ Standard Requires Progress.
+ bool CPlusPlusWithProgress() {
+ return getLangOpts().CPlusPlus11 || getLangOpts().CPlusPlus14 ||
+ getLangOpts().CPlusPlus17 || getLangOpts().CPlusPlus20;
+ }
+
+ /// True if the C Standard Requires Progress.
+ bool CWithProgress() {
+ return getLangOpts().C11 || getLangOpts().C17 || getLangOpts().C2x;
+ }
+
+ /// True if the language standard requires progress in functions or
+ /// in infinite loops with non-constant conditionals.
+ bool LanguageRequiresProgress() {
+ return CWithProgress() || CPlusPlusWithProgress();
+ }
+
const CodeGen::CGBlockInfo *BlockInfo = nullptr;
llvm::Value *BlockPointer = nullptr;
diff --git a/clang/test/CodeGen/address-safety-attr-flavors.cpp b/clang/test/CodeGen/address-safety-attr-flavors.cpp
index 815cbae78a67..ac575ede0461 100644
--- a/clang/test/CodeGen/address-safety-attr-flavors.cpp
+++ b/clang/test/CodeGen/address-safety-attr-flavors.cpp
@@ -25,51 +25,51 @@
// RUN: FileCheck -check-prefix=CHECK-KHWASAN %s
int HasSanitizeAddress() { return 1; }
-// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-ASAN: Function Attrs: noinline nounwind sanitize_address
-// CHECK-KASAN: Function Attrs: noinline nounwind sanitize_address
-// CHECK-HWASAN: Function Attrs: noinline nounwind sanitize_hwaddress
-// CHECK-KHWASAN: Function Attrs: noinline nounwind sanitize_hwaddress
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-ASAN: Function Attrs: noinline nounwind sanitize_address mustprogress
+// CHECK-KASAN: Function Attrs: noinline nounwind sanitize_address mustprogress
+// CHECK-HWASAN: Function Attrs: noinline nounwind sanitize_hwaddress mustprogress
+// CHECK-KHWASAN: Function Attrs: noinline nounwind sanitize_hwaddress mustprogress
__attribute__((no_sanitize("address"))) int NoSanitizeQuoteAddress() {
return 0;
}
-// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-ASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-KASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
-// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
+// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
__attribute__((no_sanitize_address)) int NoSanitizeAddress() { return 0; }
-// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-ASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-KASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
-// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
+// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
__attribute__((no_sanitize("kernel-address"))) int NoSanitizeKernelAddress() {
return 0;
}
-// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-ASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-KASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
-// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress$}}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-HWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
+// CHECK-KHWASAN: {{Function Attrs: noinline nounwind sanitize_hwaddress mustprogress$}}
__attribute__((no_sanitize("hwaddress"))) int NoSanitizeHWAddress() {
return 0;
}
-// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
-// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
-// CHECK-HWASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-KHWASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address mustprogress$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address mustprogress$}}
+// CHECK-HWASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-KHWASAN: {{Function Attrs: noinline nounwind mustprogress$}}
__attribute__((no_sanitize("kernel-hwaddress"))) int NoSanitizeKernelHWAddress() {
return 0;
}
-// CHECK-NOASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
-// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address$}}
-// CHECK-HWASAN: {{Function Attrs: noinline nounwind$}}
-// CHECK-KHWASAN: {{Function Attrs: noinline nounwind$}}
+// CHECK-NOASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-ASAN: {{Function Attrs: noinline nounwind sanitize_address mustprogress$}}
+// CHECK-KASAN: {{Function Attrs: noinline nounwind sanitize_address mustprogress$}}
+// CHECK-HWASAN: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-KHWASAN: {{Function Attrs: noinline nounwind mustprogress$}}
diff --git a/clang/test/CodeGen/address-safety-attr.cpp b/clang/test/CodeGen/address-safety-attr.cpp
index 986224092922..90e60f7fb7fd 100644
--- a/clang/test/CodeGen/address-safety-attr.cpp
+++ b/clang/test/CodeGen/address-safety-attr.cpp
@@ -35,8 +35,7 @@ int DefinedInDifferentFile(int *a);
// ASAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
// ASAN: @__cxx_global_array_dtor{{.*}}[[WITH]]
-
-// WITHOUT: NoAddressSafety1{{.*}}) [[NOATTR]]
+// WITHOUT: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
// BLFILE: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
// BLFUNC: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
// ASAN: NoAddressSafety1{{.*}}) [[NOATTR:#[0-9]+]]
@@ -83,8 +82,8 @@ int NoAddressSafety6(int *a) { return *a; }
// WITHOUT: AddressSafetyOk{{.*}}) [[NOATTR]]
// BLFILE: AddressSafetyOk{{.*}}) [[NOATTR]]
-// BLFUNC: AddressSafetyOk{{.*}}) [[WITH]]
-// ASAN: AddressSafetyOk{{.*}}) [[WITH]]
+// BLFUNC: AddressSafetyOk{{.*}}) [[WITH:#[0-9]+]]
+// ASAN: AddressSafetyOk{{.*}}) [[WITH:#[0-9]+]]
int AddressSafetyOk(int *a) { return *a; }
// WITHOUT: BlacklistedFunction{{.*}}) [[NOATTR]]
@@ -138,10 +137,10 @@ int force_instance = TemplateAddressSafetyOk<42>()
// Check that __cxx_global_var_init* get the sanitize_address attribute.
int global1 = 0;
int global2 = *(int*)((char*)&global1+1);
-// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR]]
+// WITHOUT: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]]
// BLFILE: @__cxx_global_var_init{{.*}}[[NOATTR:#[0-9]+]]
-// BLFUNC: @__cxx_global_var_init{{.*}}[[WITH]]
-// ASAN: @__cxx_global_var_init{{.*}}[[WITH]]
+// BLFUNC: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
+// ASAN: @__cxx_global_var_init{{.*}}[[WITH:#[0-9]+]]
// WITHOUT: attributes [[NOATTR]] = { noinline nounwind{{.*}} }
diff --git a/clang/test/CodeGen/attr-mustprogress-0.c b/clang/test/CodeGen/attr-mustprogress-0.c
new file mode 100644
index 000000000000..2af24e88ceef
--- /dev/null
+++ b/clang/test/CodeGen/attr-mustprogress-0.c
@@ -0,0 +1,184 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes
+// RUN: %clang_cc1 -std=c89 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c99 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+
+int a = 0;
+int b = 0;
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @f1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]]
+// CHECK: for.end:
+// CHECK-NEXT: ret void
+//
+void f1() {
+ for (; 1;) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @f2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]]
+// CHECK: for.end:
+// CHECK-NEXT: ret void
+//
+void f2() {
+ for (; a == b;) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @F(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]]
+// CHECK: for.end:
+// CHECK-NEXT: br label [[FOR_COND1:%.*]]
+// CHECK: for.cond1:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
+// CHECK: for.body2:
+// CHECK-NEXT: br label [[FOR_COND1]]
+// CHECK: for.end3:
+// CHECK-NEXT: ret void
+//
+void F() {
+ for (; 1;) {
+ }
+ for (; a == b;) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @w1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_BODY]]
+//
+void w1() {
+ while (1) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @w2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_COND:%.*]]
+// CHECK: while.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_COND]]
+// CHECK: while.end:
+// CHECK-NEXT: ret void
+//
+void w2() {
+ while (a == b) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @W(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_COND:%.*]]
+// CHECK: while.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_COND]]
+// CHECK: while.end:
+// CHECK-NEXT: br label [[WHILE_BODY2:%.*]]
+// CHECK: while.body2:
+// CHECK-NEXT: br label [[WHILE_BODY2]]
+//
+void W() {
+ while (a == b) {
+ }
+ while (1) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @d1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
+// CHECK: do.end:
+// CHECK-NEXT: ret void
+//
+void d1() {
+ do {
+ } while (1);
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @d2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]]
+// CHECK: do.end:
+// CHECK-NEXT: ret void
+//
+void d2() {
+ do {
+ } while (a == b);
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @D(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
+// CHECK: do.end:
+// CHECK-NEXT: br label [[DO_BODY1:%.*]]
+// CHECK: do.body1:
+// CHECK-NEXT: br label [[DO_COND2:%.*]]
+// CHECK: do.cond2:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY1]], label [[DO_END3:%.*]]
+// CHECK: do.end3:
+// CHECK-NEXT: ret void
+//
+void D() {
+ do {
+ } while (1);
+ do {
+ } while (a == b);
+}
diff --git a/clang/test/CodeGen/attr-mustprogress-0.cpp b/clang/test/CodeGen/attr-mustprogress-0.cpp
new file mode 100644
index 000000000000..3a180cc6b5ad
--- /dev/null
+++ b/clang/test/CodeGen/attr-mustprogress-0.cpp
@@ -0,0 +1,183 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes
+// RUN: %clang_cc1 -std=c++98 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+
+int a = 0;
+int b = 0;
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2f1v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]]
+// CHECK: for.end:
+// CHECK-NEXT: ret void
+//
+void f1() {
+ for (; 1;) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2f2v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]]
+// CHECK: for.end:
+// CHECK-NEXT: ret void
+//
+void f2() {
+ for (; a == b;) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z1Fv(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]]
+// CHECK: for.end:
+// CHECK-NEXT: br label [[FOR_COND1:%.*]]
+// CHECK: for.cond1:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
+// CHECK: for.body2:
+// CHECK-NEXT: br label [[FOR_COND1]]
+// CHECK: for.end3:
+// CHECK-NEXT: ret void
+//
+void F() {
+ for (; 1;) {
+ }
+ for (; a == b;) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2w1v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_BODY]]
+//
+void w1() {
+ while (1) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2w2v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_COND:%.*]]
+// CHECK: while.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_COND]]
+// CHECK: while.end:
+// CHECK-NEXT: ret void
+//
+void w2() {
+ while (a == b) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z1Wv(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_COND:%.*]]
+// CHECK: while.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_COND]]
+// CHECK: while.end:
+// CHECK-NEXT: br label [[WHILE_BODY2:%.*]]
+// CHECK: while.body2:
+// CHECK-NEXT: br label [[WHILE_BODY2]]
+//
+void W() {
+ while (a == b) {
+ }
+ while (1) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2d1v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
+// CHECK: do.end:
+// CHECK-NEXT: ret void
+//
+void d1() {
+ do {
+ } while (1);
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2d2v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]]
+// CHECK: do.end:
+// CHECK-NEXT: ret void
+//
+void d2() {
+ do {
+ } while (a == b);
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z1Dv(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
+// CHECK: do.end:
+// CHECK-NEXT: br label [[DO_BODY1:%.*]]
+// CHECK: do.body1:
+// CHECK-NEXT: br label [[DO_COND2:%.*]]
+// CHECK: do.cond2:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY1]], label [[DO_END3:%.*]]
+// CHECK: do.end3:
+// CHECK-NEXT: ret void
+//
+void D() {
+ do {
+ } while (1);
+ do {
+ } while (a == b);
+}
diff --git a/clang/test/CodeGen/attr-mustprogress-1.c b/clang/test/CodeGen/attr-mustprogress-1.c
new file mode 100644
index 000000000000..a5a8595218a1
--- /dev/null
+++ b/clang/test/CodeGen/attr-mustprogress-1.c
@@ -0,0 +1,186 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes
+// RUN: %clang_cc1 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c11 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c18 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c2x -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+
+int a = 0;
+int b = 0;
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @f1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]]
+// CHECK: for.end:
+// CHECK-NEXT: ret void
+//
+void f1() {
+ for (; 1;) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @f2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
+// CHECK: for.end:
+// CHECK-NEXT: ret void
+//
+void f2() {
+ for (; a == b;) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @F(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]]
+// CHECK: for.end:
+// CHECK-NEXT: br label [[FOR_COND1:%.*]]
+// CHECK: for.cond1:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
+// CHECK: for.body2:
+// CHECK-NEXT: br label [[FOR_COND1]], [[LOOP4:!llvm.loop !.*]]
+// CHECK: for.end3:
+// CHECK-NEXT: ret void
+//
+void F() {
+ for (; 1;) {
+ }
+ for (; a == b;) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @w1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_BODY]]
+//
+void w1() {
+ while (1) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @w2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_COND:%.*]]
+// CHECK: while.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_COND]], [[LOOP5:!llvm.loop !.*]]
+// CHECK: while.end:
+// CHECK-NEXT: ret void
+//
+void w2() {
+ while (a == b) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @W(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_COND:%.*]]
+// CHECK: while.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_COND]], [[LOOP6:!llvm.loop !.*]]
+// CHECK: while.end:
+// CHECK-NEXT: br label [[WHILE_BODY2:%.*]]
+// CHECK: while.body2:
+// CHECK-NEXT: br label [[WHILE_BODY2]]
+//
+void W() {
+ while (a == b) {
+ }
+ while (1) {
+ }
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @d1(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
+// CHECK: do.end:
+// CHECK-NEXT: ret void
+//
+void d1() {
+ do {
+ } while (1);
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @d2(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP7:!llvm.loop !.*]]
+// CHECK: do.end:
+// CHECK-NEXT: ret void
+//
+void d2() {
+ do {
+ } while (a == b);
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @D(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
+// CHECK: do.end:
+// CHECK-NEXT: br label [[DO_BODY1:%.*]]
+// CHECK: do.body1:
+// CHECK-NEXT: br label [[DO_COND2:%.*]]
+// CHECK: do.cond2:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY1]], label [[DO_END3:%.*]], [[LOOP8:!llvm.loop !.*]]
+// CHECK: do.end3:
+// CHECK-NEXT: ret void
+//
+void D() {
+ do {
+ } while (1);
+ do {
+ } while (a == b);
+}
diff --git a/clang/test/CodeGen/attr-mustprogress-1.cpp b/clang/test/CodeGen/attr-mustprogress-1.cpp
new file mode 100644
index 000000000000..6d53d2d1148d
--- /dev/null
+++ b/clang/test/CodeGen/attr-mustprogress-1.cpp
@@ -0,0 +1,261 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes
+// RUN: %clang_cc1 -std=c++11 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++14 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++17 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++20 -triple=x86_64-unknown-linux-gnu -S -emit-llvm %s -o - | FileCheck %s
+
+int a = 0;
+int b = 0;
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2f1v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]]
+// CHECK: for.end:
+// CHECK-NEXT: ret void
+//
+void f1() {
+ for (; 1;)
+ ;
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone mustprogress
+// CHECK-LABEL: @_Z2f2v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
+// CHECK: for.end:
+// CHECK-NEXT: ret void
+//
+void f2() {
+ for (; a == b;)
+ ;
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z1Fv(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: br i1 true, label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]]
+// CHECK: for.end:
+// CHECK-NEXT: br label [[FOR_COND1:%.*]]
+// CHECK: for.cond1:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
+// CHECK: for.body2:
+// CHECK-NEXT: br label [[FOR_COND1]], [[LOOP4:!llvm.loop !.*]]
+// CHECK: for.end3:
+// CHECK-NEXT: ret void
+//
+void F() {
+ for (; 1;)
+ ;
+ for (; a == b;)
+ ;
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2F2v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[FOR_COND:%.*]]
+// CHECK: for.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+// CHECK: for.body:
+// CHECK-NEXT: br label [[FOR_COND]], [[LOOP5:!llvm.loop !.*]]
+// CHECK: for.end:
+// CHECK-NEXT: br label [[FOR_COND1:%.*]]
+// CHECK: for.cond1:
+// CHECK-NEXT: br i1 true, label [[FOR_BODY2:%.*]], label [[FOR_END3:%.*]]
+// CHECK: for.body2:
+// CHECK-NEXT: br label [[FOR_COND1]]
+// CHECK: for.end3:
+// CHECK-NEXT: ret void
+//
+void F2() {
+ for (; a == b;)
+ ;
+ for (; 1;)
+ ;
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2w1v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_BODY]]
+//
+void w1() {
+ while (1)
+ ;
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone mustprogress
+// CHECK-LABEL: @_Z2w2v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_COND:%.*]]
+// CHECK: while.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_COND]], [[LOOP6:!llvm.loop !.*]]
+// CHECK: while.end:
+// CHECK-NEXT: ret void
+//
+void w2() {
+ while (a == b)
+ ;
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z1Wv(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_COND:%.*]]
+// CHECK: while.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[WHILE_BODY:%.*]], label [[WHILE_END:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_COND]], [[LOOP7:!llvm.loop !.*]]
+// CHECK: while.end:
+// CHECK-NEXT: br label [[WHILE_BODY2:%.*]]
+// CHECK: while.body2:
+// CHECK-NEXT: br label [[WHILE_BODY2]]
+//
+void W() {
+ while (a == b)
+ ;
+ while (1)
+ ;
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2W2v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[WHILE_BODY:%.*]]
+// CHECK: while.body:
+// CHECK-NEXT: br label [[WHILE_BODY]]
+//
+void W2() {
+ while (1)
+ ;
+ while (a == b)
+ ;
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2d1v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
+// CHECK: do.end:
+// CHECK-NEXT: ret void
+//
+void d1() {
+ do
+ ;
+ while (1);
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone mustprogress
+// CHECK-LABEL: @_Z2d2v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP8:!llvm.loop !.*]]
+// CHECK: do.end:
+// CHECK-NEXT: ret void
+//
+void d2() {
+ do
+ ;
+ while (a == b);
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z1Dv(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: br i1 true, label [[DO_BODY]], label [[DO_END:%.*]]
+// CHECK: do.end:
+// CHECK-NEXT: br label [[DO_BODY1:%.*]]
+// CHECK: do.body1:
+// CHECK-NEXT: br label [[DO_COND2:%.*]]
+// CHECK: do.cond2:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY1]], label [[DO_END3:%.*]], [[LOOP9:!llvm.loop !.*]]
+// CHECK: do.end3:
+// CHECK-NEXT: ret void
+//
+void D() {
+ do
+ ;
+ while (1);
+ do
+ ;
+ while (a == b);
+}
+
+// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK-LABEL: @_Z2D2v(
+// CHECK-NEXT: entry:
+// CHECK-NEXT: br label [[DO_BODY:%.*]]
+// CHECK: do.body:
+// CHECK-NEXT: br label [[DO_COND:%.*]]
+// CHECK: do.cond:
+// CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @a, align 4
+// CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
+// CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+// CHECK-NEXT: br i1 [[CMP]], label [[DO_BODY]], label [[DO_END:%.*]], [[LOOP10:!llvm.loop !.*]]
+// CHECK: do.end:
+// CHECK-NEXT: br label [[DO_BODY1:%.*]]
+// CHECK: do.body1:
+// CHECK-NEXT: br label [[DO_COND2:%.*]]
+// CHECK: do.cond2:
+// CHECK-NEXT: br i1 true, label [[DO_BODY1]], label [[DO_END3:%.*]]
+// CHECK: do.end3:
+// CHECK-NEXT: ret void
+//
+void D2() {
+ do
+ ;
+ while (a == b);
+ do
+ ;
+ while (1);
+}
+
diff --git a/clang/test/CodeGen/memtag-attr.cpp b/clang/test/CodeGen/memtag-attr.cpp
index f0b0785367ba..33c22a2d9165 100644
--- a/clang/test/CodeGen/memtag-attr.cpp
+++ b/clang/test/CodeGen/memtag-attr.cpp
@@ -9,11 +9,11 @@
// RUN: FileCheck -check-prefix=CHECK-MEMTAG %s
int HasSanitizeMemTag() { return 1; }
-// CHECK-NO: {{Function Attrs: noinline nounwind$}}
+// CHECK-NO: {{Function Attrs: noinline nounwind mustprogress$}}
// CHECK-MEMTAG: Function Attrs: noinline nounwind sanitize_memtag
__attribute__((no_sanitize("memtag"))) int NoSanitizeQuoteAddress() {
return 0;
}
-// CHECK-NO: {{Function Attrs: noinline nounwind$}}
-// CHECK-MEMTAG: {{Function Attrs: noinline nounwind$}}
+// CHECK-NO: {{Function Attrs: noinline nounwind mustprogress$}}
+// CHECK-MEMTAG: {{Function Attrs: noinline nounwind mustprogress$}}
diff --git a/clang/test/CodeGen/no-builtin.cpp b/clang/test/CodeGen/no-builtin.cpp
index 24df100d8717..bf0e4a315f83 100644
--- a/clang/test/CodeGen/no-builtin.cpp
+++ b/clang/test/CodeGen/no-builtin.cpp
@@ -43,7 +43,7 @@ extern "C" void call_b_foo(B *b) {
// CHECK-LABEL: define void @call_foo_no_mempcy() #3
extern "C" void call_foo_no_mempcy() {
- // CHECK: call void @foo_no_mempcy() #6
+ // CHECK: call void @foo_no_mempcy() #7
foo_no_mempcy(); // call gets annotated with "no-builtin-memcpy"
}
@@ -51,7 +51,7 @@ A::~A() {} // Anchoring A so A::foo() gets generated
B::~B() {} // Anchoring B so B::foo() gets generated
// CHECK-LABEL: define linkonce_odr i32 @_ZNK1A3fooEv(%struct.A* %this) unnamed_addr #0 comdat align 2
-// CHECK-LABEL: define linkonce_odr i32 @_ZNK1B3fooEv(%struct.B* %this) unnamed_addr #5 comdat align 2
+// CHECK-LABEL: define linkonce_odr i32 @_ZNK1B3fooEv(%struct.B* %this) unnamed_addr #6 comdat align 2
// CHECK: attributes #0 = {{{.*}}"no-builtin-memcpy"{{.*}}}
// CHECK-NOT: attributes #0 = {{{.*}}"no-builtin-memmove"{{.*}}}
@@ -59,7 +59,7 @@ B::~B() {} // Anchoring B so B::foo() gets generated
// CHECK: attributes #1 = {{{.*}}"no-builtins"{{.*}}}
// CHECK: attributes #2 = {{{.*}}"no-builtin-memcpy"{{.*}}"no-builtin-memset"{{.*}}}
// CHECK-NOT: attributes #2 = {{{.*}}"no-builtin-memmove"{{.*}}}
-// CHECK: attributes #5 = {{{.*}}"no-builtin-memmove"{{.*}}}
+// CHECK: attributes #6 = {{{.*}}"no-builtin-memmove"{{.*}}}
// CHECK-NOT: attributes #5 = {{{.*}}"no-builtin-memcpy"{{.*}}}
// CHECK-NOT: attributes #5 = {{{.*}}"no-builtin-memset"{{.*}}}
-// CHECK: attributes #6 = { "no-builtin-memcpy" }
+// CHECK: attributes #7 = { "no-builtin-memcpy" }
diff --git a/clang/test/CodeGen/pragma-do-while.cpp b/clang/test/CodeGen/pragma-do-while.cpp
index ecab7fc029e2..ecf8322cadcf 100644
--- a/clang/test/CodeGen/pragma-do-while.cpp
+++ b/clang/test/CodeGen/pragma-do-while.cpp
@@ -17,8 +17,9 @@
// CHECK: br {{.*}}, label %do.body, label %do.end, !llvm.loop ![[LMD1:[0-9]+]]
// CHECK-LABEL: do.end:
// CHECK-NOT: llvm.loop
-// CHECK: ![[LMD1]] = distinct !{![[LMD1]], ![[LMD2:[0-9]+]]}
-// CHECK: ![[LMD2]] = !{!"llvm.loop.unroll.count", i32 4}
+// CHECK: ![[LMD1]] = distinct !{![[LMD1]], [[LMD2:![0-9]+]], ![[LMD3:[0-9]+]]}
+// CHECK: [[LMD2]] = !{!"llvm.loop.mustprogress"}
+// CHECK: ![[LMD3]] = !{!"llvm.loop.unroll.count", i32 4}
int test(int a[], int n) {
int i = 0;
diff --git a/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp
index 1c87ee411f50..ec2ee37f97c0 100644
--- a/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp
+++ b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp
@@ -9,7 +9,7 @@ void wl(int e){
void wu(int e){
// CHECK-LABEL: define{{.*}}wu
- // CHECK: br {{.*}} !prof !9
+ // CHECK: br {{.*}} !prof !10
while(e) [[unlikely]] ++e;
}
@@ -31,7 +31,7 @@ void fl(unsigned e)
void fu(int e)
{
// CHECK-LABEL: define{{.*}}fu
- // CHECK: br {{.*}} !prof !9
+ // CHECK: br {{.*}} !prof !10
for(int i = 0; i != e; ++e) [[unlikely]];
}
@@ -52,9 +52,9 @@ void frl(int (&&e) [4])
void fru(int (&&e) [4])
{
// CHECK-LABEL: define{{.*}}fru
- // CHECK: br {{.*}} !prof !9
+ // CHECK: br {{.*}} !prof !10
for(int i : e) [[unlikely]];
}
// CHECK: !6 = !{!"branch_weights", i32 2000, i32 1}
-// CHECK: !9 = !{!"branch_weights", i32 1, i32 2000}
+// CHECK: !10 = !{!"branch_weights", i32 1, i32 2000}
diff --git a/clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp b/clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp
index cded6da7be1e..cdac2535a3ef 100644
--- a/clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp
+++ b/clang/test/CodeGenCXX/cxx11-trivial-initializer-struct.cpp
@@ -1,7 +1,11 @@
-// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o %t-c++11.ll %s -triple x86_64-apple-darwin10
+// RUN: %clang_cc1 -std=c++11 -S -emit-llvm -o %t-c++11.ll %s -triple x86_64-apple-darwin10
// RUN: FileCheck %s < %t-c++11.ll
-// RUN: %clang_cc1 -std=c++98 -S -emit-llvm -o %t.ll %s -triple x86_64-apple-darwin10
-// RUN:
diff %t.ll %t-c++11.ll
+// RUN: %clang_cc1 -std=c++17 -S -emit-llvm -o %t-c++17.ll %s -triple x86_64-apple-darwin10
+// RUN: FileCheck %s < %t-c++17.ll
+// RUN: %clang_cc1 -std=c++98 -S -emit-llvm -o %t.ll %s -triple x86_64-apple-darwin10
+// RUN: %clang_cc1 -std=c++03 -S -emit-llvm -o %t-c++03.ll %s -triple x86_64-apple-darwin10
+// RUN:
diff %t-c++11.ll %t-c++17.ll
+// RUN:
diff %t.ll %t-c++03.ll
// rdar://12897704
diff --git a/clang/test/CodeGenCXX/debug-info-line-if.cpp b/clang/test/CodeGenCXX/debug-info-line-if.cpp
index 3b54b5c7c65d..442d705c3d7f 100644
--- a/clang/test/CodeGenCXX/debug-info-line-if.cpp
+++ b/clang/test/CodeGenCXX/debug-info-line-if.cpp
@@ -57,11 +57,11 @@ int main() {
// CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, scope: !{{.*}})
// CHECK-DAG: [[ELDBG1]] = !DILocation(line: 104, scope: !{{.*}})
- // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]}
+ // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]], [[MP:![0-9]+]]}
// CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, scope: !{{.*}})
// CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, scope: !{{.*}})
- // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]]}
+ // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[SLDBG3:![0-9]*]], [[ELDBG3:![0-9]*]], [[MP]]}
// CHECK-DAG: [[SLDBG3]] = !DILocation(line: 300, scope: !{{.*}})
// CHECK-DAG: [[ELDBG3]] = !DILocation(line: 304, scope: !{{.*}})
diff --git a/clang/test/CodeGenCXX/debug-info-loops.cpp b/clang/test/CodeGenCXX/debug-info-loops.cpp
index 69948ea0f880..b46acb248143 100644
--- a/clang/test/CodeGenCXX/debug-info-loops.cpp
+++ b/clang/test/CodeGenCXX/debug-info-loops.cpp
@@ -35,7 +35,7 @@ int main() {
// CHECK-DAG: [[SLDBG1]] = !DILocation(line: 100, column: 3, scope: !{{.*}})
// CHECK-DAG: [[ELDBG1]] = !DILocation(line: 105, column: 3, scope: !{{.*}})
- // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]]}
+ // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[SLDBG2:![0-9]*]], [[ELDBG2:![0-9]*]], [[MP:![0-9]+]]}
// CHECK-DAG: [[SLDBG2]] = !DILocation(line: 200, column: 3, scope: !{{.*}})
// CHECK-DAG: [[ELDBG2]] = !DILocation(line: 204, column: 9, scope: !{{.*}})
@@ -43,7 +43,7 @@ int main() {
// CHECK-DAG: [[SLDBG3]] = !DILocation(line: 302, column: 5, scope: !{{.*}})
// CHECK-DAG: [[ELDBG3]] = !DILocation(line: 303, column: 9, scope: !{{.*}})
//
- // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]]}
+ // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[SLDBG4:![0-9]*]], [[ELDBG4:![0-9]*]], [[MP]]}
// CHECK-DAG: [[SLDBG4]] = !DILocation(line: 300, column: 3, scope: !{{.*}})
// CHECK-DAG: [[ELDBG4]] = !DILocation(line: 304, column: 3, scope: !{{.*}})
}
diff --git a/clang/test/CodeGenCXX/fno-unroll-loops-metadata.cpp b/clang/test/CodeGenCXX/fno-unroll-loops-metadata.cpp
index e5f9a1a50411..77ab97ea8260 100644
--- a/clang/test/CodeGenCXX/fno-unroll-loops-metadata.cpp
+++ b/clang/test/CodeGenCXX/fno-unroll-loops-metadata.cpp
@@ -4,7 +4,7 @@
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s -O3 -disable-llvm-optzns -fno-unroll-loops | FileCheck --check-prefix=UNROLL_DISABLED_MD %s
// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s -O3 -disable-llvm-optzns | FileCheck --check-prefix=NO_UNROLL_MD %s
-// NO_UNROLL_MD-NOT: llvm.loop
+// NO_UNROLL_MD-NOT: llvm.loop.unroll.disable
// Verify unroll.disable metadata is added to while loop with -fno-unroll-loops
// and optlevel > 0.
@@ -13,7 +13,7 @@ void while_test(int *List, int Length) {
int i = 0;
while (i < Length) {
- // UNROLL_DISABLED_MD: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ // UNROLL_DISABLED_MD: br label {{.*}}, !llvm.loop [[LOOP_1:![0-9]+]]
List[i] = i * 2;
i++;
}
@@ -26,7 +26,7 @@ void do_test(int *List, int Length) {
int i = 0;
do {
- // UNROLL_DISABLED_MD: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
+ // UNROLL_DISABLED_MD: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop [[LOOP_2:![0-9]+]]
List[i] = i * 2;
i++;
} while (i < Length);
@@ -37,12 +37,13 @@ void do_test(int *List, int Length) {
void for_test(int *List, int Length) {
// UNROLL_DISABLED_MD: define {{.*}} @_Z8for_test
for (int i = 0; i < Length; i++) {
- // UNROLL_DISABLED_MD: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ // UNROLL_DISABLED_MD: br label {{.*}}, !llvm.loop [[LOOP_3:![0-9]+]]
List[i] = i * 2;
}
}
-// UNROLL_DISABLED_MD: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_DISABLE:.*]]}
-// UNROLL_DISABLED_MD: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
-// UNROLL_DISABLED_MD: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[UNROLL_DISABLE:.*]]}
-// UNROLL_DISABLED_MD: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNROLL_DISABLE:.*]]}
+// UNROLL_DISABLED_MD: [[LOOP_1]] = distinct !{[[LOOP_1]], [[MP:![0-9]+]], [[UNROLL_DISABLE:![0-9]+]]}
+// UNROLL_DISABLED_MD: [[MP]] = !{!"llvm.loop.mustprogress"}
+// UNROLL_DISABLED_MD: [[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
+// UNROLL_DISABLED_MD: [[LOOP_2]] = distinct !{[[LOOP_2]], [[MP]], [[UNROLL_DISABLE]]}
+// UNROLL_DISABLED_MD: [[LOOP_3]] = distinct !{[[LOOP_3]], [[MP]], [[UNROLL_DISABLE]]}
diff --git a/clang/test/CodeGenCXX/pragma-followup_inner.cpp b/clang/test/CodeGenCXX/pragma-followup_inner.cpp
index 62e9f07f019a..0098f8c62cb8 100644
--- a/clang/test/CodeGenCXX/pragma-followup_inner.cpp
+++ b/clang/test/CodeGenCXX/pragma-followup_inner.cpp
@@ -28,9 +28,9 @@ extern "C" void followup_inner(int n, int *x) {
// CHECK-DAG: ![[LOOP_7:[0-9]+]] = distinct !{![[LOOP_7:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[VECTORIZE_8:[0-9]+]]}
// CHECK-DAG: ![[VECTORIZE_8:[0-9]+]] = !{!"llvm.loop.vectorize.enable", i1 true}
-// CHECK-DAG: ![[OUTERLOOP_9:[0-9]+]] = distinct !{![[OUTERLOOP_9:[0-9]+]], ![[UNROLLANDJAM_COUNT_10:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]]}
+// CHECK-DAG: ![[OUTERLOOP_9:[0-9]+]] = distinct !{![[OUTERLOOP_9:[0-9]+]], [[MP:![0-9]+]], ![[UNROLLANDJAM_COUNT_10:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]]}
// CHECK-DAG: ![[UNROLLANDJAM_COUNT_10:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
-// CHECK-DAG: ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.followup_inner", !12}
+// CHECK-DAG: ![[UNROLLANDJAM_FOLLOWUPINNER_11:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.followup_inner", !13}
// CHECK-DAG: ![[LOOP_12:[0-9]+]] = distinct !{![[LOOP_12:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_13:[0-9]+]], ![[UNROLL_COUNT_13:[0-9]+]], ![[UNROLL_FOLLOWUP_14:[0-9]+]]}
// CHECK-DAG: ![[ISVECTORIZED_13:[0-9]+]] = !{!"llvm.loop.isvectorized"}
diff --git a/clang/test/CodeGenCXX/pragma-followup_outer.cpp b/clang/test/CodeGenCXX/pragma-followup_outer.cpp
index a71056eb3ae2..49198c48c5bc 100644
--- a/clang/test/CodeGenCXX/pragma-followup_outer.cpp
+++ b/clang/test/CodeGenCXX/pragma-followup_outer.cpp
@@ -17,25 +17,25 @@ extern "C" void followup_outer(int n, int *x) {
// CHECK-DAG: ![[ACCESSGROUP_2:[0-9]+]] = distinct !{}
-// CHECK-DAG: ![[LOOP_3:[0-9]+]] = distinct !{![[LOOP_3:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[DISTRIBUTE_5:[0-9]+]], ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]]}
+// CHECK-DAG: ![[LOOP_3:[0-9]+]] = distinct !{![[LOOP_3:[0-9]+]], [[MP:![0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[DISTRIBUTE_5:[0-9]+]], ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]]}
// CHECK-DAG: ![[PARALLEL_ACCESSES_4:[0-9]+]] = !{!"llvm.loop.parallel_accesses", ![[ACCESSGROUP_2]]}
// CHECK-DAG: ![[DISTRIBUTE_5:[0-9]+]] = !{!"llvm.loop.distribute.enable", i1 true}
// CHECK-DAG: ![[DISTRIBUTE_FOLLOWUP_6:[0-9]+]] = !{!"llvm.loop.distribute.followup_all", ![[LOOP_7:[0-9]+]]}
-// CHECK-DAG: ![[LOOP_7:[0-9]+]] = distinct !{![[LOOP_7:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[VECTORIZE_8:[0-9]+]], ![[VECTORIZE_FOLLOWUP_9:[0-9]+]]}
+// CHECK-DAG: ![[LOOP_7:[0-9]+]] = distinct !{![[LOOP_7:[0-9]+]], [[MP]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[VECTORIZE_8:[0-9]+]], ![[VECTORIZE_FOLLOWUP_9:[0-9]+]]}
// CHECK-DAG: ![[VECTORIZE_8:[0-9]+]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK-DAG: ![[VECTORIZE_FOLLOWUP_9:[0-9]+]] = !{!"llvm.loop.vectorize.followup_all", ![[LOOP_10:[0-9]+]]}
-// CHECK-DAG: ![[LOOP_10:[0-9]+]] = distinct !{![[LOOP_10:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_12:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPOUTER_13:[0-9]+]]}
+// CHECK-DAG: ![[LOOP_10:[0-9]+]] = distinct !{![[LOOP_10:[0-9]+]], [[MP]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_12:[0-9]+]], ![[UNROLLANDJAM_FOLLOWUPOUTER_13:[0-9]+]]}
// CHECK-DAG: ![[ISVECTORIZED_11:[0-9]+]] = !{!"llvm.loop.isvectorized"}
// CHECK-DAG: ![[UNROLLANDJAM_12:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.enable"}
// CHECK-DAG: ![[UNROLLANDJAM_FOLLOWUPOUTER_13:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.followup_outer", ![[LOOP_14:[0-9]+]]}
-// CHECK-DAG: ![[LOOP_14:[0-9]+]] = distinct !{![[LOOP_14:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_COUNT_16:[0-9]+]], ![[UNROLL_FOLLOWUP_17:[0-9]+]]}
+// CHECK-DAG: ![[LOOP_14:[0-9]+]] = distinct !{![[LOOP_14:[0-9]+]], [[MP]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_COUNT_16:[0-9]+]], ![[UNROLL_FOLLOWUP_17:[0-9]+]]}
// CHECK-DAG: ![[UNROLLANDJAM_DISABLE_15:[0-9]+]] = !{!"llvm.loop.unroll_and_jam.disable"}
// CHECK-DAG: ![[UNROLL_COUNT_16:[0-9]+]] = !{!"llvm.loop.unroll.count", i32 4}
// CHECK-DAG: ![[UNROLL_FOLLOWUP_17:[0-9]+]] = !{!"llvm.loop.unroll.followup_all", ![[LOOP_18:[0-9]+]]}
-// CHECK-DAG: ![[LOOP_18:[0-9]+]] = distinct !{![[LOOP_18:[0-9]+]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_DISABLE_19:[0-9]+]], ![[INITIATIONINTERVAL_20:[0-9]+]]}
+// CHECK-DAG: ![[LOOP_18:[0-9]+]] = distinct !{![[LOOP_18:[0-9]+]], [[MP]], ![[PARALLEL_ACCESSES_4:[0-9]+]], ![[ISVECTORIZED_11:[0-9]+]], ![[UNROLLANDJAM_DISABLE_15:[0-9]+]], ![[UNROLL_DISABLE_19:[0-9]+]], ![[INITIATIONINTERVAL_20:[0-9]+]]}
// CHECK-DAG: ![[UNROLL_DISABLE_19:[0-9]+]] = !{!"llvm.loop.unroll.disable"}
// CHECK-DAG: ![[INITIATIONINTERVAL_20:[0-9]+]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
diff --git a/clang/test/CodeGenCXX/pragma-loop-distribute.cpp b/clang/test/CodeGenCXX/pragma-loop-distribute.cpp
index a6925593b818..98aef21da2ac 100644
--- a/clang/test/CodeGenCXX/pragma-loop-distribute.cpp
+++ b/clang/test/CodeGenCXX/pragma-loop-distribute.cpp
@@ -13,11 +13,12 @@ void while_test(int *List, int Length, int *List2, int Length2) {
i = 0;
while (i < Length2) {
- // CHECK-NOT: br label {{.*}}, !llvm.loop
+ // CHECK: br label {{.*}}, !llvm.loop [[LOOP_2:![0-9]+]]
List2[i] = i * 2;
i++;
}
}
-// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[DISTRIBUTE_ENABLE:.*]]}
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], [[MP:![0-9]+]], ![[DISTRIBUTE_ENABLE:.*]]}
// CHECK: ![[DISTRIBUTE_ENABLE]] = !{!"llvm.loop.distribute.enable", i1 true}
+// CHECK: [[LOOP_2]] = distinct !{[[LOOP_2]], [[MP]]}
diff --git a/clang/test/CodeGenCXX/pragma-loop-pr27643.cpp b/clang/test/CodeGenCXX/pragma-loop-pr27643.cpp
index 87a225081faa..75c2668962d4 100644
--- a/clang/test/CodeGenCXX/pragma-loop-pr27643.cpp
+++ b/clang/test/CodeGenCXX/pragma-loop-pr27643.cpp
@@ -40,13 +40,13 @@ void loop4(int *List, int Length) {
List[i] = i * 2;
}
-// CHECK: ![[LOOP1]] = distinct !{![[LOOP1]], ![[VEC_WIDTH_1:.*]], ![[VEC_ENABLE:.*]]}
+// CHECK: ![[LOOP1]] = distinct !{![[LOOP1]], [[MP:![0-9]+]], ![[VEC_WIDTH_1:.*]], ![[VEC_ENABLE:.*]]}
// CHECK: ![[VEC_WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
// CHECK: ![[VEC_ENABLE]] = !{!"llvm.loop.vectorize.enable", i1 true}
-// CHECK: ![[LOOP2]] = distinct !{![[LOOP2]], ![[VEC_WIDTH_2:.*]], ![[VEC_ENABLE]]}
+// CHECK: ![[LOOP2]] = distinct !{![[LOOP2]], [[MP]], ![[VEC_WIDTH_2:.*]], ![[VEC_ENABLE]]}
// CHECK: ![[VEC_WIDTH_2]] = !{!"llvm.loop.vectorize.width", i32 2}
-// CHECK: ![[LOOP3]] = distinct !{![[LOOP3]], ![[VEC_WIDTH_1]]}
+// CHECK: ![[LOOP3]] = distinct !{![[LOOP3]], [[MP]], ![[VEC_WIDTH_1]]}
-// CHECK: ![[LOOP4]] = distinct !{![[LOOP4]], ![[VEC_WIDTH_2]], ![[VEC_ENABLE]]}
+// CHECK: ![[LOOP4]] = distinct !{![[LOOP4]], [[MP]], ![[VEC_WIDTH_2]], ![[VEC_ENABLE]]}
diff --git a/clang/test/CodeGenCXX/pragma-loop-predicate.cpp b/clang/test/CodeGenCXX/pragma-loop-predicate.cpp
index ec2161d1772e..ec8f82ef9b9e 100644
--- a/clang/test/CodeGenCXX/pragma-loop-predicate.cpp
+++ b/clang/test/CodeGenCXX/pragma-loop-predicate.cpp
@@ -58,19 +58,19 @@ void test5(int *List, int Length) {
List[i] = i * 2;
}
+// CHECK: ![[LOOP0]] = distinct !{![[LOOP0]], [[MP:![0-9]+]], [[GEN3:![0-9]+]]}
+// CHECK: [[MP]] = !{!"llvm.loop.mustprogress"}
+// CHECK-NEXT: [[GEN3]] = !{!"llvm.loop.vectorize.enable", i1 true}
-// CHECK: ![[LOOP0]] = distinct !{![[LOOP0]], !3}
-// CHECK-NEXT: !3 = !{!"llvm.loop.vectorize.enable", i1 true}
+// CHECK-NEXT: ![[LOOP1]] = distinct !{![[LOOP1]], [[MP]], [[GEN6:![0-9]+]], [[GEN3]]}
+// CHECK-NEXT: [[GEN6]] = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
-// CHECK-NEXT: ![[LOOP1]] = distinct !{![[LOOP1]], !5, !3}
-// CHECK-NEXT: !5 = !{!"llvm.loop.vectorize.predicate.enable", i1 true}
+// CHECK-NEXT: ![[LOOP2]] = distinct !{![[LOOP2]], [[MP]], [[GEN8:![0-9]+]], [[GEN3]]}
+// CHECK-NEXT: [[GEN8]] = !{!"llvm.loop.vectorize.predicate.enable", i1 false}
-// CHECK-NEXT: ![[LOOP2]] = distinct !{![[LOOP2]], !7, !3}
-// CHECK-NEXT: !7 = !{!"llvm.loop.vectorize.predicate.enable", i1 false}
+// CHECK-NEXT: ![[LOOP3]] = distinct !{![[LOOP3]], [[MP]], [[GEN6]], [[GEN3]]}
-// CHECK-NEXT: ![[LOOP3]] = distinct !{![[LOOP3]], !5, !3}
+// CHECK-NEXT: ![[LOOP4]] = distinct !{![[LOOP4]], [[MP]], [[GEN10:![0-9]+]]}
+// CHECK-NEXT: [[GEN10]] = !{!"llvm.loop.vectorize.width", i32 1}
-// CHECK-NEXT: ![[LOOP4]] = distinct !{![[LOOP4]], !10}
-// CHECK-NEXT: !10 = !{!"llvm.loop.vectorize.width", i32 1}
-
-// CHECK-NEXT: ![[LOOP5]] = distinct !{![[LOOP5]], !10}
+// CHECK-NEXT: ![[LOOP5]] = distinct !{![[LOOP5]], [[MP]], [[GEN10]]}
diff --git a/clang/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp b/clang/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
index 1aed1e6df857..49ca93c5ec78 100644
--- a/clang/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
+++ b/clang/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp
@@ -26,7 +26,8 @@ void vectorize_imperfectly_nested_test(int *List, int Length) {
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
// CHECK: ![[ACCESS_GROUP_LIST_3:[0-9]+]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
-// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], [[MP:![0-9]+]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
+// CHECK: [[MP]] = !{!"llvm.loop.mustprogress"}
// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], [[MP]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/clang/test/CodeGenCXX/pragma-loop-safety-nested.cpp b/clang/test/CodeGenCXX/pragma-loop-safety-nested.cpp
index d3bdb880e172..35fd21395763 100644
--- a/clang/test/CodeGenCXX/pragma-loop-safety-nested.cpp
+++ b/clang/test/CodeGenCXX/pragma-loop-safety-nested.cpp
@@ -21,7 +21,7 @@ void vectorize_nested_test(int *List, int Length) {
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
// CHECK: ![[ACCESS_GROUP_LIST_3]] = !{![[ACCESS_GROUP_2]], ![[ACCESS_GROUP_4:[0-9]+]]}
// CHECK: ![[ACCESS_GROUP_4]] = distinct !{}
-// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
+// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]], [[MP:![0-9]+]], ![[PARALLEL_ACCESSES_8:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_8]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_4]]}
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], [[MP]], ![[PARALLEL_ACCESSES_10:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_10]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp b/clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp
index 670cb29edd42..25c08be65924 100644
--- a/clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp
+++ b/clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp
@@ -18,5 +18,5 @@ void vectorize_outer_test(int *List, int Length) {
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
// CHECK: ![[INNER_LOOPID]] = distinct !{![[INNER_LOOPID]],
-// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], ![[PARALLEL_ACCESSES_9:[0-9]+]]
+// CHECK: ![[OUTER_LOOPID]] = distinct !{![[OUTER_LOOPID]], [[MP:![0-9]+]], ![[PARALLEL_ACCESSES_9:[0-9]+]]
// CHECK: ![[PARALLEL_ACCESSES_9]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
diff --git a/clang/test/CodeGenCXX/pragma-loop-safety.cpp b/clang/test/CodeGenCXX/pragma-loop-safety.cpp
index 86e7632a4416..588e262f1780 100644
--- a/clang/test/CodeGenCXX/pragma-loop-safety.cpp
+++ b/clang/test/CodeGenCXX/pragma-loop-safety.cpp
@@ -47,12 +47,12 @@ void interleave_test(int *List, int Length) {
}
// CHECK: ![[ACCESS_GROUP_2]] = distinct !{}
-// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], ![[PARALLEL_ACCESSES_7:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]]}
+// CHECK: ![[LOOP1_HINTS]] = distinct !{![[LOOP1_HINTS]], [[MP:![0-9]+]], ![[PARALLEL_ACCESSES_7:[0-9]+]], ![[UNROLL_DISABLE:[0-9]+]], ![[INTERLEAVE_1:[0-9]+]], ![[INTENABLE_1:[0-9]+]]}
// CHECK: ![[PARALLEL_ACCESSES_7]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_2]]}
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
// CHECK: ![[INTERLEAVE_1]] = !{!"llvm.loop.interleave.count", i32 1}
// CHECK: ![[INTENABLE_1]] = !{!"llvm.loop.vectorize.enable", i1 true}
// CHECK: ![[ACCESS_GROUP_8]] = distinct !{}
-// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], ![[PARALLEL_ACCESSES_11:[0-9]+]], ![[UNROLL_DISABLE]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]]}
+// CHECK: ![[LOOP2_HINTS]] = distinct !{![[LOOP2_HINTS]], [[MP]], ![[PARALLEL_ACCESSES_11:[0-9]+]], ![[UNROLL_DISABLE]], ![[WIDTH_1:[0-9]+]], ![[INTENABLE_1]]}
// CHECK: ![[PARALLEL_ACCESSES_11]] = !{!"llvm.loop.parallel_accesses", ![[ACCESS_GROUP_8]]}
// CHECK: ![[WIDTH_1]] = !{!"llvm.loop.vectorize.width", i32 1}
diff --git a/clang/test/CodeGenCXX/pragma-loop.cpp b/clang/test/CodeGenCXX/pragma-loop.cpp
index d730f30621a4..a34817082281 100644
--- a/clang/test/CodeGenCXX/pragma-loop.cpp
+++ b/clang/test/CodeGenCXX/pragma-loop.cpp
@@ -158,10 +158,10 @@ void template_test(double *List, int Length) {
for_template_constant_expression_test<double, 2, 4, 8>(List, Length);
}
-// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_FULL:.*]]}
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], [[MP:![0-9]+]], ![[UNROLL_FULL:.*]]}
// CHECK: ![[UNROLL_FULL]] = !{!"llvm.loop.unroll.full"}
-// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]], ![[VECTORIZE_ENABLE:.*]]}
+// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], [[MP]], ![[UNROLL_DISABLE:.*]], ![[DISTRIBUTE_DISABLE:.*]], ![[WIDTH_8:.*]], ![[INTERLEAVE_4:.*]], ![[VECTORIZE_ENABLE:.*]]}
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
// CHECK: ![[DISTRIBUTE_DISABLE]] = !{!"llvm.loop.distribute.enable", i1 false}
// CHECK: ![[WIDTH_8]] = !{!"llvm.loop.vectorize.width", i32 8}
@@ -170,7 +170,7 @@ void template_test(double *List, int Length) {
// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[INTERLEAVE_4:.*]], ![[VECTORIZE_ENABLE]], ![[FOLLOWUP_VECTOR_3:.*]]}
// CHECK: ![[FOLLOWUP_VECTOR_3]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_3:.*]]}
-// CHECK: ![[AFTER_VECTOR_3]] = distinct !{![[AFTER_VECTOR_3]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
+// CHECK: ![[AFTER_VECTOR_3]] = distinct !{![[AFTER_VECTOR_3]], [[MP]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
// CHECK: ![[ISVECTORIZED]] = !{!"llvm.loop.isvectorized"}
// CHECK: ![[UNROLL_8]] = !{!"llvm.loop.unroll.count", i32 8}
@@ -185,7 +185,7 @@ void template_test(double *List, int Length) {
// CHECK: ![[FOLLOWUP_VECTOR_6]] = !{!"llvm.loop.vectorize.followup_all", ![[AFTER_VECTOR_6:.*]]}
// CHECK: ![[AFTER_VECTOR_6]] = distinct !{![[AFTER_VECTOR_6]], ![[ISVECTORIZED:.*]], ![[UNROLL_8:.*]]}
-// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[WIDTH_5:.*]], ![[VECTORIZE_ENABLE]]}
+// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], [[MP]], ![[WIDTH_5:.*]], ![[VECTORIZE_ENABLE]]}
// CHECK: ![[WIDTH_5]] = !{!"llvm.loop.vectorize.width", i32 5}
// CHECK: ![[LOOP_8]] = distinct !{![[LOOP_8]], ![[WIDTH_5:.*]]}
@@ -213,5 +213,5 @@ void template_test(double *List, int Length) {
// CHECK: ![[AFTER_VECTOR_13]] = distinct !{![[AFTER_VECTOR_13]], ![[ISVECTORIZED:.*]], ![[UNROLL_32:.*]]}
// CHECK: ![[UNROLL_32]] = !{!"llvm.loop.unroll.count", i32 32}
-// CHECK: ![[LOOP_14]] = distinct !{![[LOOP_14]], ![[WIDTH_10:.*]], ![[VECTORIZE_ENABLE]]}
+// CHECK: ![[LOOP_14]] = distinct !{![[LOOP_14]], [[MP]], ![[WIDTH_10:.*]], ![[VECTORIZE_ENABLE]]}
// CHECK: ![[WIDTH_10]] = !{!"llvm.loop.vectorize.width", i32 10}
diff --git a/clang/test/CodeGenCXX/pragma-pipeline.cpp b/clang/test/CodeGenCXX/pragma-pipeline.cpp
index 6846f1544365..b7d2136745c7 100644
--- a/clang/test/CodeGenCXX/pragma-pipeline.cpp
+++ b/clang/test/CodeGenCXX/pragma-pipeline.cpp
@@ -36,12 +36,12 @@ void pipeline_disabled_on_nested_loop(int *List, int Length, int Value) {
}
}
-// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[PIPELINE_DISABLE:.*]]}
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], [[MP:![0-9]+]], ![[PIPELINE_DISABLE:.*]]}
// CHECK: ![[PIPELINE_DISABLE]] = !{!"llvm.loop.pipeline.disable", i1 true}
// CHECK-NOT:llvm.loop.pipeline
-// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[PIPELINE_II_10:.*]]}
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], [[MP]], ![[PIPELINE_II_10:.*]]}
// CHECK: ![[PIPELINE_II_10]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
-// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[PIPELINE_DISABLE]]}
+// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], [[MP]], ![[PIPELINE_DISABLE]]}
diff --git a/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp b/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp
index 524b60ab6956..11cda785781e 100644
--- a/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp
+++ b/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp
@@ -6,6 +6,7 @@ void unroll_and_jam(int *List, int Length, int Value) {
for (int i = 0; i < Length; i++) {
for (int j = 0; j < Length; j++) {
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
List[i * Length + j] = Value;
}
}
@@ -16,7 +17,8 @@ void unroll_and_jam_count(int *List, int Length, int Value) {
#pragma unroll_and_jam(4)
for (int i = 0; i < Length; i++) {
for (int j = 0; j < Length; j++) {
- // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
List[i * Length + j] = Value;
}
}
@@ -27,7 +29,8 @@ void nounroll_and_jam(int *List, int Length, int Value) {
#pragma nounroll_and_jam
for (int i = 0; i < Length; i++) {
for (int j = 0; j < Length; j++) {
- // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_6:.*]]
List[i * Length + j] = Value;
}
}
@@ -40,16 +43,17 @@ void clang_unroll_plus_nounroll_and_jam(int *List, int Length, int Value) {
for (int i = 0; i < Length; i++) {
for (int j = 0; j < Length; j++) {
// CHECK: br label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_8:.*]]
List[i * Length + j] = Value;
}
}
}
-// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNJ_ENABLE:.*]]}
+// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], [[MP:![0-9]+]], ![[UNJ_ENABLE:.*]]}
// CHECK: ![[UNJ_ENABLE]] = !{!"llvm.loop.unroll_and_jam.enable"}
-// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNJ_4:.*]]}
+// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], [[MP]], ![[UNJ_4:.*]]}
// CHECK: ![[UNJ_4]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
-// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNJ_DISABLE:.*]]}
+// CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], [[MP]], ![[UNJ_DISABLE:.*]]}
// CHECK: ![[UNJ_DISABLE]] = !{!"llvm.loop.unroll_and_jam.disable"}
-// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNJ_DISABLE:.*]], ![[UNROLL_4:.*]]}
+// CHECK: ![[LOOP_8]] = distinct !{![[LOOP_8]], [[MP]], ![[UNJ_DISABLE:.*]], ![[UNROLL_4:.*]]}
// CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
diff --git a/clang/test/CodeGenCXX/pragma-unroll.cpp b/clang/test/CodeGenCXX/pragma-unroll.cpp
index 54a691b5c89b..02d9bad7148d 100644
--- a/clang/test/CodeGenCXX/pragma-unroll.cpp
+++ b/clang/test/CodeGenCXX/pragma-unroll.cpp
@@ -96,11 +96,11 @@ void template_test(double *List, int Length) {
for_template_define_test<double>(List, Length, Value);
}
-// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_ENABLE:.*]]}
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], [[MP:![0-9]+]], ![[UNROLL_ENABLE:.*]]}
// CHECK: ![[UNROLL_ENABLE]] = !{!"llvm.loop.unroll.enable"}
// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[UNROLL_DISABLE:.*]]}
// CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
-// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNROLL_8:.*]]}
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], [[MP]], ![[UNROLL_8:.*]]}
// CHECK: ![[UNROLL_8]] = !{!"llvm.loop.unroll.count", i32 8}
// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[UNROLL_4:.*]]}
// CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
diff --git a/clang/test/CodeGenCXX/thunks-ehspec.cpp b/clang/test/CodeGenCXX/thunks-ehspec.cpp
index 30276948d3fc..c0d8f3eec78e 100644
--- a/clang/test/CodeGenCXX/thunks-ehspec.cpp
+++ b/clang/test/CodeGenCXX/thunks-ehspec.cpp
@@ -17,13 +17,13 @@ class C : A, B {
};
void C::primary_key() {}
-// CHECK-LABEL: define available_externally void @_ZThn8_N1C9secondaryEv(%class.C* %this)
+// CHECK-LABEL: define available_externally void @_ZThn8_N1C9secondaryEv(%class.C* %this) {{.*}} #2
// CHECK-NOT: invoke
// CHECK: tail call void @_ZN1C9secondaryEv(%class.C* %{{.*}})
// CHECK-NOT: invoke
// CHECK: ret void
-// CHECK-LABEL: define available_externally void @_ZThn8_N1C16secondary_varargEiz(%class.C* %this, i32 %0, ...)
+// CHECK-LABEL: define available_externally void @_ZThn8_N1C16secondary_varargEiz(%class.C* %this, i32 %0, ...) {{.*}} #2
// CHECK-NOT: invoke
-// CHECK: musttail call void (%class.C*, i32, ...) @_ZN1C16secondary_varargEiz(%class.C* %{{.*}}, i32 %{{.*}}, ...) #2
+// CHECK: musttail call void (%class.C*, i32, ...) @_ZN1C16secondary_varargEiz(%class.C* %{{.*}}, i32 %{{.*}}, ...) #3
// CHECK-NEXT: ret void
diff --git a/clang/test/CodeGenCXX/thunks.cpp b/clang/test/CodeGenCXX/thunks.cpp
index 0f21a24b4410..612acfb535e7 100644
--- a/clang/test/CodeGenCXX/thunks.cpp
+++ b/clang/test/CodeGenCXX/thunks.cpp
@@ -529,7 +529,7 @@ C c;
// CHECK-NONOPT-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv
// Checking with opt
-// CHECK-OPT-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous namespace)::C"* %this) unnamed_addr #0 align 2
+// CHECK-OPT-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv(%"struct.Test4B::(anonymous namespace)::C"* %this) unnamed_addr #1 align 2
// This is from Test5:
// CHECK-OPT-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
diff --git a/clang/test/OpenMP/simd_metadata.c b/clang/test/OpenMP/simd_metadata.c
index 18133e3b6c2e..7c39587f9019 100644
--- a/clang/test/OpenMP/simd_metadata.c
+++ b/clang/test/OpenMP/simd_metadata.c
@@ -110,7 +110,8 @@ void h3(float *c, float *a, float *b, int size)
}
// CHECK: store float {{.+}}, float* {{.+}}, align {{.+}}, !llvm.access.group ![[ACCESS_GROUP_13:[0-9]+]]
}
-// CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
+ // CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER_INNER:![0-9]+]]
+ // CHECK: br label %{{.+}}, !llvm.loop [[LOOP_H3_HEADER:![0-9]+]]
}
// Metadata for h1:
diff --git a/clang/test/Profile/c-unprofiled-blocks.c b/clang/test/Profile/c-unprofiled-blocks.c
index a5474001315b..834a307ed770 100644
--- a/clang/test/Profile/c-unprofiled-blocks.c
+++ b/clang/test/Profile/c-unprofiled-blocks.c
@@ -16,7 +16,7 @@ int never_called(int i) {
// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
while (--i) {}
- // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+ // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}, !llvm.loop [[LOOP1:!.*]]
do {} while (i++ < 75);
// PGOUSE: switch {{.*}} [
@@ -46,7 +46,7 @@ int dead_code(int i) {
// PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
while (--i) {}
- // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}{{$}}
+ // PGOUSE: br i1 %{{[^,]*}}, label %{{[^,]*}}, label %{{[^,]*}}, !llvm.loop [[LOOP2:!.*]]
do {} while (i++ < 75);
// PGOUSE: switch {{.*}} [
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected b/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
index 8095b10d7877..edf99e2c7673 100644
--- a/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
+++ b/clang/test/utils/update_cc_test_checks/Inputs/basic-cplusplus.cpp.expected
@@ -44,7 +44,7 @@ Foo::Foo(int x) : x(x) {}
// CHECK-NEXT: [[THIS_ADDR:%.*]] = alloca %class.Foo*, align 8
// CHECK-NEXT: store %class.Foo* [[THIS:%.*]], %class.Foo** [[THIS_ADDR]], align 8
// CHECK-NEXT: [[THIS1:%.*]] = load %class.Foo*, %class.Foo** [[THIS_ADDR]], align 8
-// CHECK-NEXT: call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR2:#.*]]
+// CHECK-NEXT: call void @_ZN3FooD2Ev(%class.Foo* [[THIS1]]) [[ATTR3:#.*]]
// CHECK-NEXT: ret void
//
Foo::~Foo() {}
@@ -70,7 +70,7 @@ int Foo::function_defined_out_of_line(int arg) const { return x - arg; }
// CHECK-NEXT: call void @_ZN3FooC1Ei(%class.Foo* [[F]], i32 1)
// CHECK-NEXT: [[CALL:%.*]] = call i32 @_ZNK3Foo23function_defined_inlineEi(%class.Foo* [[F]], i32 2)
// CHECK-NEXT: [[CALL1:%.*]] = call i32 @_ZNK3Foo28function_defined_out_of_lineEi(%class.Foo* [[F]], i32 3)
-// CHECK-NEXT: call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR2]]
+// CHECK-NEXT: call void @_ZN3FooD1Ev(%class.Foo* [[F]]) [[ATTR3]]
// CHECK-NEXT: ret i32 0
//
int main() {
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected b/clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
index 4862de910a95..319f1201e8eb 100644
--- a/clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
+++ b/clang/test/utils/update_cc_test_checks/Inputs/check-attributes.cpp.funcattrs.expected
@@ -11,7 +11,7 @@ struct ST {
struct RT Z;
};
-// CHECK: Function Attrs: noinline nounwind optnone
+// CHECK: Function Attrs: noinline nounwind optnone mustprogress
// CHECK-LABEL: @_Z3fooP2ST(
// CHECK-NEXT: entry:
// CHECK-NEXT: [[S_ADDR:%.*]] = alloca %struct.ST*, align 8
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
index d41971b3a027..cbdfff47675c 100644
--- a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
+++ b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.generated.expected
@@ -197,7 +197,7 @@ void foo(void) {
// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
-// NOOMP-NEXT: br label [[FOR_COND]]
+// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
// NOOMP: for.end:
// NOOMP-NEXT: call void @foo()
// NOOMP-NEXT: ret i32 0
@@ -223,7 +223,7 @@ void foo(void) {
// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
-// NOOMP-NEXT: br label [[FOR_COND]]
+// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP4:!llvm.loop !.*]]
// NOOMP: for.end:
// NOOMP-NEXT: ret void
//
diff --git a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
index 8aa1cb591e09..7bb40144b0b1 100644
--- a/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
+++ b/clang/test/utils/update_cc_test_checks/Inputs/generated-funcs.c.no-generated.expected
@@ -41,7 +41,7 @@ void foo(void);
// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
-// NOOMP-NEXT: br label [[FOR_COND]]
+// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP2:!llvm.loop !.*]]
// NOOMP: for.end:
// NOOMP-NEXT: call void @foo()
// NOOMP-NEXT: ret i32 0
@@ -86,7 +86,7 @@ int main() {
// NOOMP-NEXT: [[TMP2:%.*]] = load i32, i32* [[I]], align 4
// NOOMP-NEXT: [[INC:%.*]] = add nsw i32 [[TMP2]], 1
// NOOMP-NEXT: store i32 [[INC]], i32* [[I]], align 4
-// NOOMP-NEXT: br label [[FOR_COND]]
+// NOOMP-NEXT: br label [[FOR_COND]], [[LOOP4:!llvm.loop !.*]]
// NOOMP: for.end:
// NOOMP-NEXT: ret void
//
More information about the cfe-commits
mailing list