From ac73b73c16526c9e51943759ea6cab285a57e33f Mon Sep 17 00:00:00 2001 From: Atmn Patel Date: Mon, 2 Nov 2020 16:03:21 -0500 Subject: [PATCH] [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 --- clang/lib/CodeGen/CGLoopInfo.cpp | 16 +- clang/lib/CodeGen/CGLoopInfo.h | 8 +- clang/lib/CodeGen/CGStmt.cpp | 54 +++-- clang/lib/CodeGen/CodeGenFunction.cpp | 8 + clang/lib/CodeGen/CodeGenFunction.h | 20 ++ clang/test/CodeGen/address-safety-attr-flavors.cpp | 60 ++--- clang/test/CodeGen/address-safety-attr.cpp | 13 +- clang/test/CodeGen/attr-mustprogress-0.c | 184 +++++++++++++++ clang/test/CodeGen/attr-mustprogress-0.cpp | 183 +++++++++++++++ clang/test/CodeGen/attr-mustprogress-1.c | 186 +++++++++++++++ clang/test/CodeGen/attr-mustprogress-1.cpp | 261 +++++++++++++++++++++ clang/test/CodeGen/memtag-attr.cpp | 6 +- clang/test/CodeGen/no-builtin.cpp | 8 +- clang/test/CodeGen/pragma-do-while.cpp | 5 +- .../CodeGenCXX/attr-likelihood-iteration-stmt.cpp | 8 +- .../cxx11-trivial-initializer-struct.cpp | 10 +- clang/test/CodeGenCXX/debug-info-line-if.cpp | 4 +- clang/test/CodeGenCXX/debug-info-loops.cpp | 4 +- .../test/CodeGenCXX/fno-unroll-loops-metadata.cpp | 17 +- clang/test/CodeGenCXX/pragma-followup_inner.cpp | 4 +- clang/test/CodeGenCXX/pragma-followup_outer.cpp | 10 +- clang/test/CodeGenCXX/pragma-loop-distribute.cpp | 5 +- clang/test/CodeGenCXX/pragma-loop-pr27643.cpp | 8 +- clang/test/CodeGenCXX/pragma-loop-predicate.cpp | 22 +- .../pragma-loop-safety-imperfectly_nested.cpp | 5 +- .../test/CodeGenCXX/pragma-loop-safety-nested.cpp | 4 +- clang/test/CodeGenCXX/pragma-loop-safety-outer.cpp | 2 +- clang/test/CodeGenCXX/pragma-loop-safety.cpp | 4 +- clang/test/CodeGenCXX/pragma-loop.cpp | 10 +- clang/test/CodeGenCXX/pragma-pipeline.cpp | 6 +- clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp | 16 +- clang/test/CodeGenCXX/pragma-unroll.cpp | 4 +- clang/test/CodeGenCXX/thunks-ehspec.cpp | 6 +- clang/test/CodeGenCXX/thunks.cpp | 2 +- clang/test/OpenMP/simd_metadata.c | 3 +- clang/test/Profile/c-unprofiled-blocks.c | 4 +- .../Inputs/basic-cplusplus.cpp.expected | 4 +- .../Inputs/check-attributes.cpp.funcattrs.expected | 2 +- .../Inputs/generated-funcs.c.generated.expected | 4 +- .../Inputs/generated-funcs.c.no-generated.expected | 4 +- 40 files changed, 1038 insertions(+), 146 deletions(-) create mode 100644 clang/test/CodeGen/attr-mustprogress-0.c create mode 100644 clang/test/CodeGen/attr-mustprogress-0.cpp create mode 100644 clang/test/CodeGen/attr-mustprogress-1.c create mode 100644 clang/test/CodeGen/attr-mustprogress-1.cpp diff --git a/clang/lib/CodeGen/CGLoopInfo.cpp b/clang/lib/CodeGen/CGLoopInfo.cpp index a02d832..be4993e 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 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 @@ 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 e379c64..2c13e02 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 @@ public: 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 @@ public: 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 38e5ce1..972da3d 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(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 @@ 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(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 @@ 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(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 f1fe8f9..ea33ea0 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(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 346253a..8cde860 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -502,6 +502,26 @@ public: /// 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 815cbae..ac575ed 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 9862240..90e60f7 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 0000000..2af24e8 --- /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 0000000..3a180cc --- /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 0000000..a5a8595 --- /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 0000000..6d53d2d --- /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 f0b0785..33c22a2 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 24df100..bf0e4a3 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 ecab7fc..ecf8322 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 1c87ee4..ec2ee37 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 cded6da..cdac253 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 3b54b5c..442d705 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 69948ea..b46acb2 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 e5f9a1a..77ab97e 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 62e9f07..0098f8c 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 a71056e..49198c4 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 a692559..98aef21 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 87a2250..75c2668 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 ec2161d..ec8f82e 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 1aed1e6..49ca93c 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 d3bdb88..35fd213 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 670cb29..25c08be 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 86e7632..588e262 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 d730f30..a348170 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(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 6846f15..b7d2136 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 524b60a..11cda78 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 54a691b..02d9bad 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(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 3027694..c0d8f3e 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 0f21a24..612acfb 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 18133e3..7c39587 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 a547400..834a307 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 8095b10..edf99e2 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 4862de9..319f120 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 d41971b3a..cbdfff4 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 8aa1cb5..7bb4014 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 // -- 2.7.4