diff --git a/clang/lib/CodeGen/CGLoopInfo.h b/clang/lib/CodeGen/CGLoopInfo.h --- a/clang/lib/CodeGen/CGLoopInfo.h +++ b/clang/lib/CodeGen/CGLoopInfo.h @@ -75,6 +75,9 @@ /// 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 @@ void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx, const clang::CodeGenOptions &CGOpts, llvm::ArrayRef 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 @@ 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/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp --- a/clang/lib/CodeGen/CGLoopInfo.cpp +++ b/clang/lib/CodeGen/CGLoopInfo.cpp @@ -411,10 +411,14 @@ 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 @@ 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 @@ DistributeEnable = LoopAttributes::Unspecified; PipelineDisabled = false; PipelineInitiationInterval = 0; + MustProgress = false; } LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs, @@ -469,7 +474,7 @@ 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 @@ const clang::CodeGenOptions &CGOpts, ArrayRef 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(Attr); @@ -748,6 +752,8 @@ } } + 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/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -765,11 +765,6 @@ 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 @@ // 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(BoolCondVal)) - if (C->isOne()) + bool LoopMustProgress = false; + if (llvm::ConstantInt *C = dyn_cast(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 @@ 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 @@ // "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(BoolCondVal)) + bool LoopMustProgress = false; + if (llvm::ConstantInt *C = dyn_cast(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 @@ 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 @@ llvm::Value *BoolCondVal = EvaluateExprAsBool(S.getCond()); llvm::MDNode *Weights = createProfileOrBranchWeightsForLoop( S.getCond(), getProfileCount(S.getBody()), S.getBody()); + + if (llvm::ConstantInt *C = dyn_cast(BoolCondVal)) + if (C->isOne()) + FnIsMustProgress = false; + Builder.CreateCondBr(BoolCondVal, ForBody, ExitBlock, Weights); if (ExitBlock != LoopExit.getBlock()) { diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -502,6 +502,26 @@ /// 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/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1159,10 +1159,18 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { incrementProfileCounter(Body); + if (CPlusPlusWithProgress()) + FnIsMustProgress = true; + if (const CompoundStmt *S = dyn_cast(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/test/CodeGen/address-safety-attr-flavors.cpp b/clang/test/CodeGen/address-safety-attr-flavors.cpp --- 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 --- a/clang/test/CodeGen/address-safety-attr.cpp +++ b/clang/test/CodeGen/address-safety-attr.cpp @@ -35,8 +35,7 @@ // 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 @@ // 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 @@ // 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 --- /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 --- /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 --- /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 --- /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 --- 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 --- a/clang/test/CodeGen/no-builtin.cpp +++ b/clang/test/CodeGen/no-builtin.cpp @@ -43,7 +43,7 @@ // 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 @@ 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 @@ // 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 --- 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 --- a/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp +++ b/clang/test/CodeGenCXX/attr-likelihood-iteration-stmt.cpp @@ -9,7 +9,7 @@ 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 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 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 --- 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 --- a/clang/test/CodeGenCXX/debug-info-line-if.cpp +++ b/clang/test/CodeGenCXX/debug-info-line-if.cpp @@ -57,11 +57,11 @@ // 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 --- a/clang/test/CodeGenCXX/debug-info-loops.cpp +++ b/clang/test/CodeGenCXX/debug-info-loops.cpp @@ -35,7 +35,7 @@ // 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 @@ // 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 --- 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 @@ 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 @@ 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 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 --- a/clang/test/CodeGenCXX/pragma-followup_inner.cpp +++ b/clang/test/CodeGenCXX/pragma-followup_inner.cpp @@ -28,9 +28,9 @@ // 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 --- a/clang/test/CodeGenCXX/pragma-followup_outer.cpp +++ b/clang/test/CodeGenCXX/pragma-followup_outer.cpp @@ -17,25 +17,25 @@ // 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 --- a/clang/test/CodeGenCXX/pragma-loop-distribute.cpp +++ b/clang/test/CodeGenCXX/pragma-loop-distribute.cpp @@ -13,11 +13,12 @@ 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 --- a/clang/test/CodeGenCXX/pragma-loop-pr27643.cpp +++ b/clang/test/CodeGenCXX/pragma-loop-pr27643.cpp @@ -40,13 +40,13 @@ 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 --- a/clang/test/CodeGenCXX/pragma-loop-predicate.cpp +++ b/clang/test/CodeGenCXX/pragma-loop-predicate.cpp @@ -58,19 +58,19 @@ 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 --- a/clang/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp +++ b/clang/test/CodeGenCXX/pragma-loop-safety-imperfectly_nested.cpp @@ -26,7 +26,8 @@ // 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 --- a/clang/test/CodeGenCXX/pragma-loop-safety-nested.cpp +++ b/clang/test/CodeGenCXX/pragma-loop-safety-nested.cpp @@ -21,7 +21,7 @@ // 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 --- a/clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp +++ b/clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp @@ -18,5 +18,5 @@ // 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 --- a/clang/test/CodeGenCXX/pragma-loop-safety.cpp +++ b/clang/test/CodeGenCXX/pragma-loop-safety.cpp @@ -47,12 +47,12 @@ } // 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 --- a/clang/test/CodeGenCXX/pragma-loop.cpp +++ b/clang/test/CodeGenCXX/pragma-loop.cpp @@ -158,10 +158,10 @@ for_template_constant_expression_test(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 @@ // 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 @@ // 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 @@ // 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 --- a/clang/test/CodeGenCXX/pragma-pipeline.cpp +++ b/clang/test/CodeGenCXX/pragma-pipeline.cpp @@ -36,12 +36,12 @@ } } -// 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 --- a/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp +++ b/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp @@ -6,6 +6,7 @@ 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 @@ #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 @@ #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 @@ 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 --- a/clang/test/CodeGenCXX/pragma-unroll.cpp +++ b/clang/test/CodeGenCXX/pragma-unroll.cpp @@ -96,11 +96,11 @@ for_template_define_test(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 --- a/clang/test/CodeGenCXX/thunks-ehspec.cpp +++ b/clang/test/CodeGenCXX/thunks-ehspec.cpp @@ -17,13 +17,13 @@ }; 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 --- a/clang/test/CodeGenCXX/thunks.cpp +++ b/clang/test/CodeGenCXX/thunks.cpp @@ -529,7 +529,7 @@ // 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 --- a/clang/test/OpenMP/simd_metadata.c +++ b/clang/test/OpenMP/simd_metadata.c @@ -110,7 +110,8 @@ } // 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 --- a/clang/test/Profile/c-unprofiled-blocks.c +++ b/clang/test/Profile/c-unprofiled-blocks.c @@ -16,7 +16,7 @@ // 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 @@ // 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 --- 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 @@ // 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 @@ // 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 --- 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 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 --- 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 @@ // 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 @@ // 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 --- 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 @@ // 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 @@ // 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 //