Index: lib/CodeGen/CGLoopInfo.h =================================================================== --- lib/CodeGen/CGLoopInfo.h +++ lib/CodeGen/CGLoopInfo.h @@ -18,6 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/IR/DebugLoc.h" #include "llvm/IR/Value.h" #include "llvm/Support/Compiler.h" @@ -63,7 +64,8 @@ class LoopInfo { public: /// \brief Construct a new LoopInfo for the loop with entry Header. - LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs); + LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs, + llvm::DebugLoc Location); /// \brief Get the loop id metadata for this loop. llvm::MDNode *getLoopID() const { return LoopID; } @@ -95,12 +97,14 @@ /// \brief Begin a new structured loop. The set of staged attributes will be /// applied to the loop and then cleared. - void push(llvm::BasicBlock *Header); + void push(llvm::BasicBlock *Header, + llvm::DebugLoc Location = llvm::DebugLoc()); /// \brief Begin a new structured loop. Stage attributes from the Attrs list. /// The staged attributes are applied to the loop and then cleared. void push(llvm::BasicBlock *Header, clang::ASTContext &Ctx, - llvm::ArrayRef Attrs); + llvm::ArrayRef Attrs, + llvm::DebugLoc Location = llvm::DebugLoc()); /// \brief End the current loop. void pop(); Index: lib/CodeGen/CGLoopInfo.cpp =================================================================== --- lib/CodeGen/CGLoopInfo.cpp +++ lib/CodeGen/CGLoopInfo.cpp @@ -19,12 +19,14 @@ using namespace clang::CodeGen; using namespace llvm; -static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs) { +static MDNode *createMetadata(LLVMContext &Ctx, const LoopAttributes &Attrs, + llvm::DebugLoc Location) { if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 && Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 && Attrs.VectorizeEnable == LoopAttributes::Unspecified && - Attrs.UnrollEnable == LoopAttributes::Unspecified) + Attrs.UnrollEnable == LoopAttributes::Unspecified && + !Location) return nullptr; SmallVector Args; @@ -32,6 +34,10 @@ auto TempNode = MDNode::getTemporary(Ctx, None); Args.push_back(TempNode.get()); + // If we have a valid debug location for the loop, add it. + if (Location) + Args.push_back(Location.getAsMDNode()); + // Setting vectorize.width if (Attrs.VectorizeWidth > 0) { Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.vectorize.width"), @@ -98,19 +104,21 @@ UnrollEnable = LoopAttributes::Unspecified; } -LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs) +LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs, + llvm::DebugLoc Location) : LoopID(nullptr), Header(Header), Attrs(Attrs) { - LoopID = createMetadata(Header->getContext(), Attrs); + LoopID = createMetadata(Header->getContext(), Attrs, Location); } -void LoopInfoStack::push(BasicBlock *Header) { - Active.push_back(LoopInfo(Header, StagedAttrs)); +void LoopInfoStack::push(BasicBlock *Header, llvm::DebugLoc Location) { + Active.push_back(LoopInfo(Header, StagedAttrs, Location)); // Clear the attributes so nested loops do not inherit them. StagedAttrs.clear(); } void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx, - ArrayRef Attrs) { + ArrayRef Attrs, + llvm::DebugLoc Location) { // Identify loop hint attributes from Attrs. for (const auto *Attr : Attrs) { @@ -239,7 +247,7 @@ } /// Stage the attributes. - push(Header); + push(Header, Location); } void LoopInfoStack::pop() { Index: lib/CodeGen/CGStmt.cpp =================================================================== --- lib/CodeGen/CGStmt.cpp +++ lib/CodeGen/CGStmt.cpp @@ -629,7 +629,8 @@ JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond"); EmitBlock(LoopHeader.getBlock()); - LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), WhileAttrs); + LoopStack.push(LoopHeader.getBlock(), CGM.getContext(), WhileAttrs, + Builder.getCurrentDebugLocation()); // Create an exit block for when the condition fails, which will // also become the break target. @@ -720,7 +721,8 @@ // Emit the body of the loop. llvm::BasicBlock *LoopBody = createBasicBlock("do.body"); - LoopStack.push(LoopBody, CGM.getContext(), DoAttrs); + LoopStack.push(LoopBody, CGM.getContext(), DoAttrs, + Builder.getCurrentDebugLocation()); EmitBlockWithFallThrough(LoopBody, &S); { @@ -772,6 +774,8 @@ LexicalScope ForScope(*this, S.getSourceRange()); + llvm::DebugLoc DL = Builder.getCurrentDebugLocation(); + // Evaluate the first part before the loop. if (S.getInit()) EmitStmt(S.getInit()); @@ -783,7 +787,7 @@ llvm::BasicBlock *CondBlock = Continue.getBlock(); EmitBlock(CondBlock); - LoopStack.push(CondBlock, CGM.getContext(), ForAttrs); + LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, DL); // 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 @@ -868,6 +872,8 @@ LexicalScope ForScope(*this, S.getSourceRange()); + llvm::DebugLoc DL = Builder.getCurrentDebugLocation(); + // Evaluate the first pieces before the loop. EmitStmt(S.getRangeStmt()); EmitStmt(S.getBeginStmt()); @@ -879,7 +885,7 @@ llvm::BasicBlock *CondBlock = createBasicBlock("for.cond"); EmitBlock(CondBlock); - LoopStack.push(CondBlock, CGM.getContext(), ForAttrs); + LoopStack.push(CondBlock, CGM.getContext(), ForAttrs, DL); // If there are any cleanups between here and the loop-exit scope, // create a block to stage a loop exit along. Index: lib/CodeGen/CGStmtOpenMP.cpp =================================================================== --- lib/CodeGen/CGStmtOpenMP.cpp +++ lib/CodeGen/CGStmtOpenMP.cpp @@ -1218,7 +1218,7 @@ // Start the loop with a block that tests the condition. auto CondBlock = createBasicBlock("omp.inner.for.cond"); EmitBlock(CondBlock); - LoopStack.push(CondBlock); + LoopStack.push(CondBlock, Builder.getCurrentDebugLocation()); // If there are any cleanups between here and the loop-exit scope, // create a block to stage a loop exit along. @@ -1619,7 +1619,7 @@ // Start the loop with a block that tests the condition. auto CondBlock = createBasicBlock("omp.dispatch.cond"); EmitBlock(CondBlock); - LoopStack.push(CondBlock); + LoopStack.push(CondBlock, Builder.getCurrentDebugLocation()); llvm::Value *BoolCondVal = nullptr; if (!DynamicOrOrdered) { Index: test/CodeGenCXX/debug-info-line-if.cpp =================================================================== --- test/CodeGenCXX/debug-info-line-if.cpp +++ test/CodeGenCXX/debug-info-line-if.cpp @@ -15,7 +15,7 @@ // CHECK: br label // CHECK: br label - // CHECK: br label {{.*}}, !dbg [[DBG1:!.*]] + // CHECK: br label {{.*}}, !dbg [[DBG1:![0-9]*]], !llvm.loop [[L1:![0-9]*]] #line 200 while (a) @@ -25,7 +25,7 @@ ++a; // CHECK: add nsw{{.*}}, 1 // CHECK: br label - // CHECK: br label {{.*}}, !dbg [[DBG2:!.*]] + // CHECK: br label {{.*}}, !dbg [[DBG2:![0-9]*]], !llvm.loop [[L2:![0-9]*]] #line 300 for (; a; ) @@ -35,7 +35,7 @@ ++a; // CHECK: add nsw{{.*}}, 1 // CHECK: br label - // CHECK: br label {{.*}}, !dbg [[DBG3:!.*]] + // CHECK: br label {{.*}}, !dbg [[DBG3:![0-9]*]], !llvm.loop [[L3:![0-9]*]] #line 400 int x[] = {1, 2}; @@ -46,10 +46,22 @@ ++a; // CHECK: add nsw{{.*}}, 1 // CHECK: br label - // CHECK: br label {{.*}}, !dbg [[DBG4:!.*]] + // CHECK: br label {{.*}}, !dbg [[DBG4:![0-9]*]], !llvm.loop [[L4:![0-9]*]] - // CHECK: [[DBG1]] = !DILocation(line: 100, scope: !{{.*}}) - // CHECK: [[DBG2]] = !DILocation(line: 200, scope: !{{.*}}) - // CHECK: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}}) - // CHECK: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}}) + // CHECK-DAG: [[DBG1]] = !DILocation(line: 100, scope: !{{.*}}) + // CHECK-DAG: [[DBG2]] = !DILocation(line: 200, scope: !{{.*}}) + // CHECK-DAG: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}}) + // CHECK-DAG: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}}) + + // CHECK-DAG: [[L1]] = distinct !{[[L1]], [[LDBG1:![0-9]*]]} + // CHECK-DAG: [[LDBG1]] = !DILocation(line: 100, scope: !{{.*}}) + + // CHECK-DAG: [[L2]] = distinct !{[[L2]], [[LDBG2:![0-9]*]]} + // CHECK-DAG: [[LDBG2]] = !DILocation(line: 200, scope: !{{.*}}) + + // CHECK-DAG: [[L3]] = distinct !{[[L3]], [[LDBG3:![0-9]*]]} + // CHECK-DAG: [[LDBG3]] = !DILocation(line: 300, scope: !{{.*}}) + + // CHECK-DAG: [[L4]] = distinct !{[[L4]], [[LDBG4:![0-9]*]]} + // CHECK-DAG: [[LDBG4]] = !DILocation(line: 401, scope: !{{.*}}) } Index: test/Frontend/optimization-remark-options.c =================================================================== --- test/Frontend/optimization-remark-options.c +++ test/Frontend/optimization-remark-options.c @@ -11,7 +11,7 @@ return v; } -// CHECK: {{.*}}:18:13: remark: loop not vectorized: cannot prove it is safe to reorder memory operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop. If the arrays will always be independent specify '#pragma clang loop vectorize(assume_safety)' before the loop or provide the '__restrict__' qualifier with the independent array arguments. Erroneous results will occur if these options are incorrectly applied! +// CHECK: {{.*}}:17:3: remark: loop not vectorized: cannot prove it is safe to reorder memory operations; allow reordering by specifying '#pragma clang loop vectorize(enable)' before the loop. If the arrays will always be independent specify '#pragma clang loop vectorize(assume_safety)' before the loop or provide the '__restrict__' qualifier with the independent array arguments. Erroneous results will occur if these options are incorrectly applied! void foo2(int *dw, int *uw, int *A, int *B, int *C, int *D, int N) { for (int i = 0; i < N; i++) { Index: test/Misc/backend-optimization-failure.cpp =================================================================== --- test/Misc/backend-optimization-failure.cpp +++ test/Misc/backend-optimization-failure.cpp @@ -7,7 +7,7 @@ void test_switch(int *A, int *B, int Length) { #pragma clang loop vectorize(enable) unroll(disable) for (int i = 0; i < Length; i++) { -/* expected-warning {{loop not vectorized: failed explicitly specified loop vectorization}} */ switch (A[i]) { +/* expected-warning@-1 {{loop not vectorized: failed explicitly specified loop vectorization}} */ switch (A[i]) { case 0: B[i] = 1; break;