diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 3d4c3e0..dca1a33 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -966,3 +966,7 @@ def VirtualInheritance : InheritableAttr {
 def Unaligned : IgnoredAttr {
   let Spellings = [Keyword<"__unaligned">];
 }
+
+def IVDep : InheritableAttr {
+  let Spellings = [];
+}
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 7dccb73..399a2f8 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -79,6 +79,9 @@ def note_decl_hiding_tag_type : Note<
   "%1 %0 is hidden by a non-type declaration of %0 here">;
 def err_attribute_not_type_attr : Error<
   "%0 attribute cannot be applied to types">;
+// #pragma ivdep
+def warn_pragma_ivdep_expected_loop : Warning<
+  "expected loop statement following '#pragma ivdep' - ignored">;
 
 // Sema && Lex
 def ext_c99_longlong : Extension<
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 6850bd5..e3a193a 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -646,6 +646,11 @@ ANNOTATION(pragma_fp_contract)
 // handles them.
 ANNOTATION(pragma_opencl_extension)
 
+// Annotation for #pragma ivdep
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_ivdep)
+
 #undef ANNOTATION
 #undef TESTING_KEYWORD
 #undef OBJC2_AT_KEYWORD
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 8e69b64..3db20a6 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -146,6 +146,7 @@ class Parser : public CodeCompletionHandler {
   OwningPtr<PragmaHandler> RedefineExtnameHandler;
   OwningPtr<PragmaHandler> FPContractHandler;
   OwningPtr<PragmaHandler> OpenCLExtensionHandler;
+  OwningPtr<PragmaHandler> IVDepHandler;
   OwningPtr<CommentHandler> CommentSemaHandler;
 
   /// Whether the '>' token acts as an operator or not. This will be
@@ -424,6 +425,13 @@ private:
   /// #pragma OPENCL EXTENSION...
   void HandlePragmaOpenCLExtension();
 
+  /// \brief Handle the annotation token produced for
+  /// #pragma ivdep
+  void HandlePragmaIVDep();
+  /// \brief Handle the annotation token produced for
+  /// #pragma ivdep
+  StmtResult HandlePragmaIVDepStatementOrDeclaration();
+
   /// GetLookAheadToken - This peeks ahead N tokens and returns that token
   /// without consuming any tokens.  LookAhead(0) returns 'Tok', LookAhead(1)
   /// returns the token after Tok, etc.
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 397bd14..d3bb24f 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -6515,6 +6515,9 @@ public:
   /// \#pragma {STDC,OPENCL} FP_CONTRACT
   void ActOnPragmaFPContract(tok::OnOffSwitch OOS);
 
+  /// ActOnPragmaIVDep - Called on well formed \#pragma ivdep
+  StmtResult ActOnPragmaIVDep(SourceLocation PragmaLoc, Stmt *S);
+
   /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
   /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'.
   void AddAlignmentAttributesForRecord(RecordDecl *RD);
diff --git a/lib/CodeGen/CGBuilder.h b/lib/CodeGen/CGBuilder.h
index fd21e7e..6dc416c 100644
--- a/lib/CodeGen/CGBuilder.h
+++ b/lib/CodeGen/CGBuilder.h
@@ -10,16 +10,40 @@
 #ifndef CLANG_CODEGEN_CGBUILDER_H
 #define CLANG_CODEGEN_CGBUILDER_H
 
+#include "CGLoopMetadata.h"
 #include "llvm/IR/IRBuilder.h"
 
 namespace clang {
 namespace CodeGen {
 
+/// Custom IRBuilder inserter which can annotate instructions with metadata.
+template<bool PreserveNames>
+class CGBuilderInserter
+  : protected llvm::IRBuilderDefaultInserter<PreserveNames> {
+public:
+  CGBuilderInserter() : LMS(0) {}
+  CGBuilderInserter(const LoopMetadataStack *LMS) : LMS(LMS) {}
+protected:
+  void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name,
+                    llvm::BasicBlock *BB,
+                    llvm::BasicBlock::iterator InsertPt) const {
+    llvm::IRBuilderDefaultInserter<PreserveNames>::InsertHelper(I, Name, BB,
+                                                                InsertPt);
+    if (LMS) LMS->AnnotateInstruction(I);
+  }
+private:
+  const LoopMetadataStack *LMS;
+};
+
 // Don't preserve names on values in an optimized build.
 #ifdef NDEBUG
-typedef llvm::IRBuilder<false> CGBuilderTy;
+typedef CGBuilderInserter<false> CGBuilderInserterTy;
+typedef llvm::IRBuilder<false, llvm::ConstantFolder, CGBuilderInserterTy>
+  CGBuilderTy;
 #else
-typedef llvm::IRBuilder<> CGBuilderTy;
+typedef CGBuilderInserter<true> CGBuilderInserterTy;
+typedef llvm::IRBuilder<true, llvm::ConstantFolder, CGBuilderInserterTy>
+  CGBuilderTy;
 #endif
 
 }  // end namespace CodeGen
diff --git a/lib/CodeGen/CGLoopMetadata.cpp b/lib/CodeGen/CGLoopMetadata.cpp
new file mode 100644
index 0000000..b57ebcf
--- /dev/null
+++ b/lib/CodeGen/CGLoopMetadata.cpp
@@ -0,0 +1,76 @@
+#include "CGLoopMetadata.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/IR/Instructions.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+static llvm::Value *TracePointer(llvm::Value *V) {
+  assert(V->getType()->isPointerTy());
+  V = V->stripPointerCasts();
+  if (llvm::GetElementPtrInst *GI = dyn_cast<llvm::GetElementPtrInst>(V))
+    return TracePointer(GI->getPointerOperand());
+  return V;
+}
+
+/// Assuming I is in a parallel loop, return true if I needs
+/// llvm.mem.parallel_loop_access metadata.
+static bool AnnotateParallelLoopAccess(llvm::Instruction *I) {
+  if (!I->mayReadOrWriteMemory())
+    return false;
+  llvm::Value *Ptr = 0;
+  if (llvm::StoreInst *SI = dyn_cast<llvm::StoreInst>(I))
+    Ptr = TracePointer(SI->getPointerOperand());
+  if (llvm::LoadInst *LI = dyn_cast<llvm::LoadInst>(I))
+    Ptr = TracePointer(LI->getPointerOperand());
+  if (dyn_cast_or_null<llvm::AllocaInst>(Ptr))
+      return false;
+  return true;
+}
+
+LoopAttributes::LoopAttributes() : IVDep(0) {
+}
+
+void LoopAttributes::Clear() {
+  IVDep = 0;
+}
+
+LoopInfo::LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs)
+  : LoopID(0), Header(Header), Attrs(Attrs) {
+}
+
+llvm::MDNode *LoopInfo::GetLoopID() const {
+  if (LoopID) return LoopID;
+  // Create a loop id metadata of the form '!n = metadata !{metadata !n}'
+  llvm::Value* Args[] = { 0 };
+  LoopID = llvm::MDNode::get(Header->getContext(), Args);
+  LoopID->replaceOperandWith(0, LoopID);
+  return LoopID;
+}
+
+void LoopMetadataStack::Begin(llvm::BasicBlock *Header) {
+  Active.push_back(LoopInfo(Header, Attrs));
+  // Clear the attributes so nested loops do not inherit them.
+  Attrs.Clear();
+}
+
+void LoopMetadataStack::End() {
+  assert(!Active.empty());
+  Active.pop_back();
+}
+
+void LoopMetadataStack::AnnotateInstruction(llvm::Instruction *I) const {
+  if (Active.empty()) return;
+  const LoopInfo& L = Active.back();
+  if (L.GetAttributes().IVDep) {
+    if (llvm::TerminatorInst *TI = dyn_cast<llvm::TerminatorInst>(I)) {
+      for (unsigned i = 0, ie = TI->getNumSuccessors(); i != ie; ++i)
+        if (TI->getSuccessor(i) == L.GetHeader()) {
+          TI->setMetadata("llvm.loop.parallel", L.GetLoopID());
+          break;
+        }
+    } else if (AnnotateParallelLoopAccess(I))
+      I->setMetadata("llvm.mem.parallel_loop_access", L.GetLoopID());
+  }
+}
diff --git a/lib/CodeGen/CGLoopMetadata.h b/lib/CodeGen/CGLoopMetadata.h
new file mode 100644
index 0000000..ad8e25b
--- /dev/null
+++ b/lib/CodeGen/CGLoopMetadata.h
@@ -0,0 +1,93 @@
+//===---- CGLoopMetadata.h - LLVM CodeGen for loop metadata -*- C++ -*-----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This is the internal state used for llvm translation for loop statement
+// metadata.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CLANG_CODEGEN_CGLOOPMETADATA_H
+#define CLANG_CODEGEN_CGLOOPMETADATA_H
+
+#include "clang/AST/Attr.h"
+#include "llvm/IR/Metadata.h"
+
+namespace llvm {
+class Instruction;
+class LLVMContext;
+class MDNode;
+class TerminatorInst;
+} // end namespace llvm
+
+namespace clang {
+class IVDepAttr;
+
+namespace CodeGen {
+
+/// LoopAttributes - Set of attributes that can be applied to a loop.
+class LoopAttributes {
+public:
+  LoopAttributes();
+  void Clear();
+  /// #pragma ivdep attribute.
+  const IVDepAttr *IVDep;
+};
+
+/// LoopInfo - Information used when generating a structured loop.
+class LoopInfo {
+public:
+  /// Construct a new LoopInfo with the attributes specified in Attrs.
+  LoopInfo(llvm::BasicBlock *Header, const LoopAttributes &Attrs);
+
+  /// Get the loop id metadata for this loop.
+  llvm::MDNode *GetLoopID() const;
+  /// Get the header block of this loop.
+  llvm::BasicBlock *GetHeader() const { return Header; }
+  /// Get the set of attributes active for this loop.
+  const LoopAttributes &GetAttributes() const { return Attrs; }
+
+private:
+  /// Loop ID metadata.
+  mutable llvm::MDNode *LoopID;
+  /// Header block of this loop.
+  llvm::BasicBlock *Header;
+  /// Attributes active for this loop.
+  LoopAttributes Attrs;
+};
+
+/// LoopMetadataStack - A stack of loop information corresponding to loop 
+/// nesting levels. This stack can be used to prepare attributes which are
+/// applied when a loop is emitted.
+class LoopMetadataStack {
+public:
+
+  /// Begin a new structured loop. The set of applied attributes will be applied
+  /// to the loop and the attributes will be cleared.
+  void Begin(llvm::BasicBlock *Header);
+  /// End the current loop.
+  void End();
+
+  /// Add annotations to an instruction using metadata. It is assumed that
+  /// I is an instruction being emitted in the current loop.
+  void AnnotateInstruction(llvm::Instruction *I) const;
+
+  /// The set of attributes that will be applied to the next loop created with
+  /// Begin(). These attributes are cleared whenever a new loop is created with
+  /// Begin() -- the attributes are currently not inherited by nested loops.
+  LoopAttributes &GetStagedAttributes() { return Attrs; }
+
+private:
+  LoopAttributes Attrs;
+  llvm::SmallVector<LoopInfo, 4> Active;
+};
+
+} // end namespace CodeGen
+} // end namespace clang
+
+#endif // CLANG_CODEGEN_CGLOOPMETADATA_H
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 842eaf1..51eae09 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -347,6 +347,17 @@ void CodeGenFunction::EmitLabelStmt(const LabelStmt &S) {
 }
 
 void CodeGenFunction::EmitAttributedStmt(const AttributedStmt &S) {
+  typedef ArrayRef<const Attr*> AttrList;
+  AttrList Attrs = S.getAttrs();
+  for (AttrList::iterator I = Attrs.begin(), IE = Attrs.end(); I != IE; ++I) {
+    if (isa<IVDepAttr>(*I)) {
+      assert((isa<ForStmt>(S.getSubStmt()) ||
+             isa<WhileStmt>(S.getSubStmt()) ||
+             isa<DoStmt>(S.getSubStmt())) &&
+             "Not a valid loop statement for ivdep");
+      Loop.GetStagedAttributes().IVDep = cast<IVDepAttr>(*I);
+    }
+  }
   EmitStmt(S.getSubStmt());
 }
 
@@ -453,6 +464,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
   // the continue target.
   JumpDest LoopHeader = getJumpDestInCurrentScope("while.cond");
   EmitBlock(LoopHeader.getBlock());
+  Loop.Begin(LoopHeader.getBlock());
 
   // Create an exit block for when the condition fails, which will
   // also become the break target.
@@ -516,6 +528,8 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S) {
   // Branch to the loop header again.
   EmitBranch(LoopHeader.getBlock());
 
+  Loop.End();
+
   // Emit the exit block.
   EmitBlock(LoopExit.getBlock(), true);
 
@@ -534,6 +548,8 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
 
   // Emit the body of the loop.
   llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
+  Loop.Begin(LoopBody);
+
   EmitBlock(LoopBody);
   {
     RunCleanupsScope BodyScope(*this);
@@ -563,6 +579,8 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S) {
   if (EmitBoolCondBranch)
     Builder.CreateCondBr(BoolCondVal, LoopBody, LoopExit.getBlock());
 
+  Loop.End();
+
   // Emit the exit block.
   EmitBlock(LoopExit.getBlock());
 
@@ -591,6 +609,7 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {
   JumpDest Continue = getJumpDestInCurrentScope("for.cond");
   llvm::BasicBlock *CondBlock = Continue.getBlock();
   EmitBlock(CondBlock);
+  Loop.Begin(CondBlock);
 
   // Create a cleanup scope for the condition variable cleanups.
   RunCleanupsScope ConditionScope(*this);
@@ -661,6 +680,8 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S) {
   if (DI)
     DI->EmitLexicalBlockEnd(Builder, S.getSourceRange().getEnd());
 
+  Loop.End();
+
   // Emit the fall-through block.
   EmitBlock(LoopExit.getBlock(), true);
 }
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 76be85f..1d8becf 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -29,6 +29,7 @@ add_clang_library(clangCodeGen
   CGExprConstant.cpp
   CGExprCXX.cpp
   CGExprScalar.cpp
+  CGLoopMetadata.cpp
   CGObjC.cpp
   CGObjCGNU.cpp
   CGObjCMac.cpp
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 973ee88..0b83668 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -32,7 +32,8 @@ using namespace CodeGen;
 CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
   : CodeGenTypeCache(cgm), CGM(cgm),
     Target(CGM.getContext().getTargetInfo()),
-    Builder(cgm.getModule().getContext()),
+    Builder(cgm.getModule().getContext(), llvm::ConstantFolder(),
+            CGBuilderInserterTy(&Loop)),
     SanitizePerformTypeCheck(CGM.getSanOpts().Null |
                              CGM.getSanOpts().Alignment |
                              CGM.getSanOpts().ObjectSize |
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index cd738f0..3334cf2 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -16,6 +16,7 @@
 
 #include "CGBuilder.h"
 #include "CGDebugInfo.h"
+#include "CGLoopMetadata.h"
 #include "CGValue.h"
 #include "CodeGenModule.h"
 #include "clang/AST/CharUnits.h"
@@ -561,6 +562,7 @@ public:
   const TargetInfo &Target;
 
   typedef std::pair<llvm::Value *, llvm::Value *> ComplexPairTy;
+  LoopMetadataStack Loop;
   CGBuilderTy Builder;
 
   /// CurFuncDecl - Holds the Decl for the current function or ObjC method.
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 641654b..f6701e3 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -151,6 +151,31 @@ void Parser::HandlePragmaOpenCLExtension() {
   }
 }
 
+void Parser::HandlePragmaIVDep() {
+  assert(Tok.is(tok::annot_pragma_ivdep));
+  SourceLocation Loc = Tok.getLocation();
+  ConsumeToken();
+  PP.Diag(Loc, diag::warn_pragma_ivdep_expected_loop);
+}
+
+StmtResult Parser::HandlePragmaIVDepStatementOrDeclaration() {
+  assert(Tok.is(tok::annot_pragma_ivdep));
+  SourceLocation Loc = Tok.getLocation();
+  ConsumeToken();
+
+  if (Tok.is(tok::r_brace)) {
+    PP.Diag(Loc, diag::warn_pragma_ivdep_expected_loop);
+    return StmtEmpty();
+  }
+
+  StmtVector Stmts;
+  StmtResult R(ParseStatementOrDeclaration(Stmts, false));
+  if (R.isInvalid())
+    return R;
+
+  return Actions.ActOnPragmaIVDep(Loc, R.get());
+}
+
 // #pragma GCC visibility comes in two variants:
 //   'push' '(' [visibility] ')'
 //   'pop'
@@ -718,3 +743,24 @@ PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
                       /*OwnsTokens=*/false);
 }
 
+void PragmaIVDepHandler::HandlePragma(Preprocessor &PP,
+                                      PragmaIntroducerKind Introducer,
+                                      Token &Tok) {
+  SourceLocation Loc = Tok.getLocation();
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::eod)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+      << "ivdep";
+    return;
+  }
+
+  Token *Toks =
+    (Token*) PP.getPreprocessorAllocator().Allocate(
+      sizeof(Token) * 1, llvm::alignOf<Token>());
+  new (Toks) Token();
+  Toks[0].startToken();
+  Toks[0].setKind(tok::annot_pragma_ivdep);
+  Toks[0].setLocation(Loc);
+  PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
+                      /*OwnsTokens=*/false);
+}
diff --git a/lib/Parse/ParsePragma.h b/lib/Parse/ParsePragma.h
index b9a2a25..4c6722e 100644
--- a/lib/Parse/ParsePragma.h
+++ b/lib/Parse/ParsePragma.h
@@ -98,7 +98,15 @@ public:
   virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
                             Token &FirstToken);
 };
-  
+
+class PragmaIVDepHandler : public PragmaHandler {
+public:
+  explicit PragmaIVDepHandler() : PragmaHandler("ivdep") {}
+
+  virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                            Token &FirstToken);
+};
+
 
 }  // end namespace clang
 
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 71a7b2c..dc93319 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -288,6 +288,10 @@ Retry:
     ProhibitAttributes(Attrs);
     HandlePragmaOpenCLExtension();
     return StmtEmpty();
+
+  case tok::annot_pragma_ivdep:
+    ProhibitAttributes(Attrs);
+    return HandlePragmaIVDepStatementOrDeclaration();
   }
 
   // If we reached this code, the statement must end in a semicolon.
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 24849ed..b1ee525 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -97,6 +97,9 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
     PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
   }
 
+  IVDepHandler.reset(new PragmaIVDepHandler());
+  PP.AddPragmaHandler(IVDepHandler.get());
+
   CommentSemaHandler.reset(new ActionCommentHandler(actions));
   PP.addCommentHandler(CommentSemaHandler.get());
 
@@ -429,6 +432,9 @@ Parser::~Parser() {
     PP.RemovePragmaHandler("OPENCL", FPContractHandler.get());
   }
 
+  PP.RemovePragmaHandler(IVDepHandler.get());
+  IVDepHandler.reset();
+
   PP.RemovePragmaHandler("STDC", FPContractHandler.get());
   FPContractHandler.reset();
 
@@ -624,6 +630,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
   case tok::annot_pragma_opencl_extension:
     HandlePragmaOpenCLExtension();
     return DeclGroupPtrTy();
+  case tok::annot_pragma_ivdep:
+    HandlePragmaIVDep();
+    return DeclGroupPtrTy();
   case tok::semi:
     // Either a C++11 empty-declaration or attribute-declaration.
     SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(),
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index b5b35fc..046fa1e 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -2863,3 +2863,15 @@ StmtResult Sema::ActOnMSDependentExistsStmt(SourceLocation KeywordLoc,
                                     GetNameFromUnqualifiedId(Name),
                                     Nested);
 }
+
+StmtResult Sema::ActOnPragmaIVDep(SourceLocation PragmaLoc,
+                                  Stmt *SubStmt) {
+  if (isa<ForStmt>(SubStmt) ||
+      isa<WhileStmt>(SubStmt) ||
+      isa<DoStmt>(SubStmt)) {
+    const Attr* Attrs[] = { ::new (Context) IVDepAttr(PragmaLoc, Context) };
+    return ActOnAttributedStmt(PragmaLoc, Attrs, SubStmt);
+  }
+  Diag(PragmaLoc, diag::warn_pragma_ivdep_expected_loop);
+  return SubStmt;
+}
diff --git a/test/CodeGen/pragma-ivdep.c b/test/CodeGen/pragma-ivdep.c
new file mode 100644
index 0000000..f1013e7
--- /dev/null
+++ b/test/CodeGen/pragma-ivdep.c
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+// CHECK: void @for_loop
+// CHECK: for.inc:
+// CHECK: br label %for.cond, !llvm.loop.parallel !0
+void for_loop(int n) {
+  #pragma ivdep
+  for (int i = 0; i < n; ++i)
+    ;
+}
+
+// CHECK: void @for_loop_nested
+// CHECK: for.inc:
+// CHECK: br label %for.cond1, !llvm.loop.parallel !2
+// CHECK: for.inc4:
+// CHECK: br label %for.cond, !llvm.loop.parallel !1
+void for_loop_nested(int n) {
+  #pragma ivdep
+  for (int i = 0; i < n; ++i)
+    #pragma ivdep
+    for (int j = 0; j < n; ++j)
+      ;
+}
+
+// CHECK: void @while_loop
+// CHECK: while.cond:
+// CHECK: while.body:
+// CHECK: br label %while.cond, !llvm.loop.parallel !3
+void while_loop(int n) {
+  int i = 0;
+  #pragma ivdep
+  while (i < n) ++i;
+}
+
+// CHECK: void @while_loop_continue
+// CHECK: while.cond:
+// CHECK: while.body:
+// CHECK: if.then:
+// CHECK: br label %while.cond, !llvm.loop.parallel !4
+// CHECK: if.end:
+// CHECK: br label %while.cond, !llvm.loop.parallel !4
+void while_loop_continue(int n) {
+  int i = 0;
+  #pragma ivdep
+  while (i < n)
+    if (++i % 2) continue;
+}
+
+// CHECK: void @do_loop
+// CHECK: do.body:
+// CHECK: do.cond:
+// CHECK: %cmp, label %do.body, label %do.end, !llvm.loop.parallel !5
+void do_loop(int n) {
+  int i = 0;
+  #pragma ivdep
+  do ++i; while (i < n);
+}
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index 931de83..7682774 100644
--- a/test/Misc/warning-flags.c
+++ b/test/Misc/warning-flags.c
@@ -18,7 +18,7 @@ This test serves two purposes:
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 
-CHECK: Warnings without flags (144):
+CHECK: Warnings without flags (145):
 CHECK-NEXT:   ext_delete_void_ptr_operand
 CHECK-NEXT:   ext_enum_friend
 CHECK-NEXT:   ext_expected_semi_decl_list
@@ -121,6 +121,7 @@ CHECK-NEXT:   warn_pragma_expected_identifier
 CHECK-NEXT:   warn_pragma_expected_lparen
 CHECK-NEXT:   warn_pragma_expected_rparen
 CHECK-NEXT:   warn_pragma_extra_tokens_at_eol
+CHECK-NEXT:   warn_pragma_ivdep_expected_loop
 CHECK-NEXT:   warn_pragma_ms_struct
 CHECK-NEXT:   warn_pragma_options_align_reset_failed
 CHECK-NEXT:   warn_pragma_options_expected_align
diff --git a/test/Parser/pragma-ivdep.c b/test/Parser/pragma-ivdep.c
new file mode 100644
index 0000000..df4ae32
--- /dev/null
+++ b/test/Parser/pragma-ivdep.c
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+/* expected-warning@+1 {{extra tokens at end of '#pragma ivdep'}} */
+#pragma ivdep foo
+
+/* expected-warning@+1 {{expected loop statement following '#pragma ivdep' - ignored}} */
+#pragma ivdep
+
+void f0() {
+  /* expected-warning@+1 {{expected loop statement following '#pragma ivdep' - ignored}} */
+  #pragma ivdep
+  int i;
+  for (i = 0; i < 10; ++i)
+    ;
+}
+
+void f1()
+{
+  /* expected-warning@+1 {{expected loop statement following '#pragma ivdep' - ignored}} */
+  #pragma ivdep
+}
+
+void f2() {
+  int i;
+
+  /* expected-warning@+1 {{expected loop statement following '#pragma ivdep' - ignored}} */
+  #pragma ivdep
+  if (1 != 0) {}
+
+  /* expected-warning@+1 {{extra tokens at end of '#pragma ivdep'}} */
+  #pragma ivdep foo
+  for (i = 0; i < 10; ++i)
+    ;
+
+  /* expected-warning@+1 {{expected loop statement following '#pragma ivdep' - ignored}} */
+  #pragma ivdep
+  #pragma ivdep
+  for (i = 0; i < 10; ++i)
+    ;
+
+  #pragma ivdep
+  #pragma unroll
+  for (i = 0; i < 10; ++i)
+    ;
+
+  #pragma ivdep
+  for (i = 0; i < 10; ++i)
+    ;
+
+  i = 0;
+  #pragma ivdep
+  while (i < 10)
+    ++i;
+
+  i = 0;
+  #pragma ivdep
+  do 
+    ++i;
+  while (i < 10);
+
+  /* expected-warning@+1 {{expected loop statement following '#pragma ivdep' - ignored}} */
+  #pragma ivdep
+  return;
+}
