<div dir="ltr">I seem to be getting this build failure after this commit with -Werror enabled<br><br>







<p class="">lib/Sema/SemaStmtAttr.cpp:132:59: <span class="">error: </span>missing field 'EnabledIsSet' initializer [-Werror,-Wmissing-field-initializers]</p>
<p class="">    {LoopHintAttr::Vectorize, LoopHintAttr::VectorizeWidth},</p>
<p class="">                                                          ^</p>
<p class="">lib/Sema/SemaStmtAttr.cpp:133:61: <span class="">error: </span>missing field 'EnabledIsSet' initializer [-Werror,-Wmissing-field-initializers]</p>
<p class="">    {LoopHintAttr::Interleave, LoopHintAttr::InterleaveCount},</p>
<p class="">                                                            ^</p>
<p class="">lib/Sema/SemaStmtAttr.cpp:134:53: <span class="">error: </span>missing field 'EnabledIsSet' initializer [-Werror,-Wmissing-field-initializers]</p>
<p class="">    {LoopHintAttr::Unroll, LoopHintAttr::UnrollCount}</p></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jun 11, 2014 at 10:56 AM, Eli Bendersky <span dir="ltr"><<a href="mailto:eliben@google.com" target="_blank">eliben@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: eliben<br>
Date: Wed Jun 11 12:56:26 2014<br>
New Revision: 210667<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=210667&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=210667&view=rev</a><br>
Log:<br>
Add loop unroll pragma support<br>
<br>
<a href="http://reviews.llvm.org/D4089" target="_blank">http://reviews.llvm.org/D4089</a><br>
<br>
Patch by Mark Heffernan.<br>
<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/Attr.td<br>
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br>
    cfe/trunk/lib/CodeGen/CGStmt.cpp<br>
    cfe/trunk/lib/Parse/ParsePragma.cpp<br>
    cfe/trunk/lib/Sema/SemaStmtAttr.cpp<br>
    cfe/trunk/test/CodeGen/pragma-loop.cpp<br>
    cfe/trunk/test/PCH/pragma-loop.cpp<br>
    cfe/trunk/test/Parser/pragma-loop.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Basic/Attr.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=210667&r1=210666&r2=210667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=210667&r1=210666&r2=210667&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/Attr.td (original)<br>
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Jun 11 12:56:26 2014<br>
@@ -1766,6 +1766,8 @@ def LoopHint : Attr {<br>
   /// vectorize_width: vectorize loop operations with width 'value'.<br>
   /// interleave: interleave multiple loop iterations if 'value != 0'.<br>
   /// interleave_count: interleaves 'value' loop interations.<br>
+  /// unroll: unroll loop if 'value != 0'.<br>
+  /// unroll_count: unrolls loop 'value' times.<br>
<br>
   /// FIXME: Add Pragma spelling to tablegen and<br>
   /// use it here.<br>
@@ -1773,8 +1775,10 @@ def LoopHint : Attr {<br>
<br>
   /// State of the loop optimization specified by the spelling.<br>
   let Args = [EnumArgument<"Option", "OptionType",<br>
-                          ["vectorize", "vectorize_width", "interleave", "interleave_count"],<br>
-                          ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount"]>,<br>
+                          ["vectorize", "vectorize_width", "interleave", "interleave_count",<br>
+                           "unroll", "unroll_count"],<br>
+                          ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",<br>
+                           "Unroll", "UnrollCount"]>,<br>
               DefaultIntArgument<"Value", 1>];<br>
<br>
   let AdditionalMembers = [{<br>
@@ -1784,6 +1788,8 @@ def LoopHint : Attr {<br>
     case VectorizeWidth: return "vectorize_width";<br>
     case Interleave: return "interleave";<br>
     case InterleaveCount: return "interleave_count";<br>
+    case Unroll: return "unroll";<br>
+    case UnrollCount: return "unroll_count";<br>
     }<br>
     llvm_unreachable("Unhandled LoopHint option.");<br>
   }<br>
@@ -1797,7 +1803,8 @@ def LoopHint : Attr {<br>
   // FIXME: Modify pretty printer to print this pragma.<br>
   void print(raw_ostream &OS, const PrintingPolicy &Policy) const {<br>
     OS << "#pragma clang loop " << getOptionName(option) << "(";<br>
-    if (option == VectorizeWidth || option == InterleaveCount)<br>
+    if (option == VectorizeWidth || option == InterleaveCount ||<br>
+        option == UnrollCount)<br>
       OS << value;<br>
     else<br>
       OS << getValueName(value);<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=210667&r1=210666&r2=210667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=210667&r1=210666&r2=210667&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Wed Jun 11 12:56:26 2014<br>
@@ -895,7 +895,8 @@ def err_omp_more_one_clause : Error<<br>
<br>
 // Pragma loop support.<br>
 def err_pragma_loop_invalid_option : Error<<br>
-  "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, vectorize_width, interleave, or interleave_count">;<br>
+  "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "<br>
+  "vectorize_width, interleave, interleave_count, unroll, or unroll_count">;<br>
 } // end of Parse Issue category.<br>
<br>
 let CategoryName = "Modules Issue" in {<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=210667&r1=210666&r2=210667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=210667&r1=210666&r2=210667&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Wed Jun 11 12:56:26 2014<br>
@@ -550,6 +550,12 @@ void CodeGenFunction::EmitCondBrHints(ll<br>
     case LoopHintAttr::InterleaveCount:<br>
       MetadataName = "llvm.vectorizer.unroll";<br>
       break;<br>
+    case LoopHintAttr::Unroll:<br>
+      MetadataName = "llvm.loopunroll.enable";<br>
+      break;<br>
+    case LoopHintAttr::UnrollCount:<br>
+      MetadataName = "llvm.loopunroll.count";<br>
+      break;<br>
     }<br>
<br>
     llvm::Value *Value;<br>
@@ -572,6 +578,14 @@ void CodeGenFunction::EmitCondBrHints(ll<br>
       Name = llvm::MDString::get(Context, MetadataName);<br>
       Value = llvm::ConstantInt::get(Int32Ty, ValueInt);<br>
       break;<br>
+    case LoopHintAttr::Unroll:<br>
+      Name = llvm::MDString::get(Context, MetadataName);<br>
+      Value = (ValueInt == 0) ? Builder.getFalse() : Builder.getTrue();<br>
+      break;<br>
+    case LoopHintAttr::UnrollCount:<br>
+      Name = llvm::MDString::get(Context, MetadataName);<br>
+      Value = llvm::ConstantInt::get(Int32Ty, ValueInt);<br>
+      break;<br>
     }<br>
<br>
     SmallVector<llvm::Value *, 2> OpValues;<br>
<br>
Modified: cfe/trunk/lib/Parse/ParsePragma.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=210667&r1=210666&r2=210667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=210667&r1=210666&r2=210667&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Wed Jun 11 12:56:26 2014<br>
@@ -1641,8 +1641,10 @@ void PragmaOptimizeHandler::HandlePragma<br>
 ///  loop-hint:<br>
 ///    'vectorize' '(' loop-hint-keyword ')'<br>
 ///    'interleave' '(' loop-hint-keyword ')'<br>
+///    'unroll' '(' loop-hint-keyword ')'<br>
 ///    'vectorize_width' '(' loop-hint-value ')'<br>
 ///    'interleave_count' '(' loop-hint-value ')'<br>
+///    'unroll_count' '(' loop-hint-value ')'<br>
 ///<br>
 ///  loop-hint-keyword:<br>
 ///    'enable'<br>
@@ -1661,6 +1663,13 @@ void PragmaOptimizeHandler::HandlePragma<br>
 /// possible and profitable, and 0 is invalid. The loop vectorizer currently<br>
 /// only works on inner loops.<br>
 ///<br>
+/// The unroll and unroll_count directives control the concatenation<br>
+/// unroller. Specifying unroll(enable) instructs llvm to try to<br>
+/// unroll the loop completely, and unroll(disable) disables unrolling<br>
+/// for the loop. Specifying unroll_count(_value_) instructs llvm to<br>
+/// try to unroll the loop the number of times indicated by the value.<br>
+/// If unroll(enable) and unroll_count are both specified only<br>
+/// unroll_count takes effect.<br>
 void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,<br>
                                          PragmaIntroducerKind Introducer,<br>
                                          Token &Tok) {<br>
@@ -1679,9 +1688,15 @@ void PragmaLoopHintHandler::HandlePragma<br>
     Token Option = Tok;<br>
     IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();<br>
<br>
-    if (!OptionInfo->isStr("vectorize") && !OptionInfo->isStr("interleave") &&<br>
-        !OptionInfo->isStr("vectorize_width") &&<br>
-        !OptionInfo->isStr("interleave_count")) {<br>
+    bool OptionValid = llvm::StringSwitch<bool>(OptionInfo->getName())<br>
+        .Case("vectorize", true)<br>
+        .Case("interleave", true)<br>
+        .Case("unroll", true)<br>
+        .Case("vectorize_width", true)<br>
+        .Case("interleave_count", true)<br>
+        .Case("unroll_count", true)<br>
+        .Default(false);<br>
+    if (!OptionValid) {<br>
       PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)<br>
           << /*MissingOption=*/false << OptionInfo;<br>
       return;<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaStmtAttr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAttr.cpp?rev=210667&r1=210666&r2=210667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAttr.cpp?rev=210667&r1=210666&r2=210667&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaStmtAttr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaStmtAttr.cpp Wed Jun 11 12:56:26 2014<br>
@@ -67,10 +67,13 @@ static Attr *handleLoopHintAttr(Sema &S,<br>
           .Case("vectorize_width", LoopHintAttr::VectorizeWidth)<br>
           .Case("interleave", LoopHintAttr::Interleave)<br>
           .Case("interleave_count", LoopHintAttr::InterleaveCount)<br>
+          .Case("unroll", LoopHintAttr::Unroll)<br>
+          .Case("unroll_count", LoopHintAttr::UnrollCount)<br>
           .Default(LoopHintAttr::Vectorize);<br>
<br>
   int ValueInt;<br>
-  if (Option == LoopHintAttr::Vectorize || Option == LoopHintAttr::Interleave) {<br>
+  if (Option == LoopHintAttr::Vectorize || Option == LoopHintAttr::Interleave ||<br>
+      Option == LoopHintAttr::Unroll) {<br>
     if (!ValueInfo) {<br>
       S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)<br>
           << /*MissingKeyword=*/true << "";<br>
@@ -87,7 +90,8 @@ static Attr *handleLoopHintAttr(Sema &S,<br>
       return nullptr;<br>
     }<br>
   } else if (Option == LoopHintAttr::VectorizeWidth ||<br>
-             Option == LoopHintAttr::InterleaveCount) {<br>
+             Option == LoopHintAttr::InterleaveCount ||<br>
+             Option == LoopHintAttr::UnrollCount) {<br>
     // FIXME: We should support template parameters for the loop hint value.<br>
     // See bug report #19610.<br>
     llvm::APSInt ValueAPS;<br>
@@ -111,9 +115,24 @@ static Attr *handleLoopHintAttr(Sema &S,<br>
<br>
 static void<br>
 CheckForIncompatibleAttributes(Sema &S, SmallVectorImpl<const Attr *> &Attrs) {<br>
-  int PrevOptionValue[4] = {-1, -1, -1, -1};<br>
-  int OptionId[4] = {LoopHintAttr::Vectorize, LoopHintAttr::VectorizeWidth,<br>
-                     LoopHintAttr::Interleave, LoopHintAttr::InterleaveCount};<br>
+  // There are 3 categories of loop hints: vectorize, interleave, and<br>
+  // unroll. Each comes in two variants: an enable/disable form and a<br>
+  // form which takes a numeric argument. For example:<br>
+  // unroll(enable|disable) and unroll_count(N). The following array<br>
+  // accumulate the hints encountered while iterating through the<br>
+  // attributes to check for compatibility.<br>
+  struct {<br>
+    int EnableOptionId;<br>
+    int NumericOptionId;<br>
+    bool EnabledIsSet;<br>
+    bool ValueIsSet;<br>
+    bool Enabled;<br>
+    int Value;<br>
+  } Options[] = {<br>
+    {LoopHintAttr::Vectorize, LoopHintAttr::VectorizeWidth},<br>
+    {LoopHintAttr::Interleave, LoopHintAttr::InterleaveCount},<br>
+    {LoopHintAttr::Unroll, LoopHintAttr::UnrollCount}<br>
+  };<br>
<br>
   for (const auto *I : Attrs) {<br>
     const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);<br>
@@ -122,76 +141,64 @@ CheckForIncompatibleAttributes(Sema &S,<br>
     if (!LH)<br>
       continue;<br>
<br>
-    int State, Value;<br>
     int Option = LH->getOption();<br>
     int ValueInt = LH->getValue();<br>
<br>
+    int Category;<br>
     switch (Option) {<br>
     case LoopHintAttr::Vectorize:<br>
     case LoopHintAttr::VectorizeWidth:<br>
-      State = 0;<br>
-      Value = 1;<br>
+      Category = 0;<br>
       break;<br>
     case LoopHintAttr::Interleave:<br>
     case LoopHintAttr::InterleaveCount:<br>
-      State = 2;<br>
-      Value = 3;<br>
+      Category = 1;<br>
       break;<br>
-    }<br>
+    case LoopHintAttr::Unroll:<br>
+    case LoopHintAttr::UnrollCount:<br>
+      Category = 2;<br>
+      break;<br>
+    };<br>
<br>
+    auto &CategoryState = Options[Category];<br>
     SourceLocation ValueLoc = LH->getRange().getEnd();<br>
-<br>
-    // Compatibility testing is split into two cases.<br>
-    // 1. if the current loop hint sets state (enable/disable) - check against<br>
-    // previous state and value.<br>
-    // 2. if the current loop hint sets a value - check against previous state<br>
-    // and value.<br>
-<br>
-    if (Option == State) {<br>
-      if (PrevOptionValue[State] != -1) {<br>
-        // Cannot specify state twice.<br>
-        int PrevValue = PrevOptionValue[State];<br>
+    if (Option == LoopHintAttr::Vectorize ||<br>
+        Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll) {<br>
+      // Enable|disable hint.  For example, vectorize(enable).<br>
+      if (CategoryState.EnabledIsSet) {<br>
+        // Cannot specify enable/disable state twice.<br>
         S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)<br>
             << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)<br>
-            << LoopHintAttr::getValueName(PrevValue)<br>
+            << LoopHintAttr::getValueName(CategoryState.Enabled)<br>
             << LoopHintAttr::getOptionName(Option)<br>
-            << LoopHintAttr::getValueName(Value);<br>
-      }<br>
-<br>
-      if (PrevOptionValue[Value] != -1) {<br>
-        // Compare state with previous width/count.<br>
-        int PrevOption = OptionId[Value];<br>
-        int PrevValueInt = PrevOptionValue[Value];<br>
-        if ((ValueInt == 0 && PrevValueInt > 1) ||<br>
-            (ValueInt == 1 && PrevValueInt <= 1))<br>
-          S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)<br>
-              << /*Duplicate=*/false << LoopHintAttr::getOptionName(PrevOption)<br>
-              << PrevValueInt << LoopHintAttr::getOptionName(Option)<br>
-              << LoopHintAttr::getValueName(ValueInt);<br>
+            << LoopHintAttr::getValueName(ValueInt);<br>
       }<br>
+      CategoryState.EnabledIsSet = true;<br>
+      CategoryState.Enabled = ValueInt;<br>
     } else {<br>
-      if (PrevOptionValue[State] != -1) {<br>
-        // Compare width/count value with previous state.<br>
-        int PrevOption = OptionId[State];<br>
-        int PrevValueInt = PrevOptionValue[State];<br>
-        if ((ValueInt > 1 && PrevValueInt == 0) ||<br>
-            (ValueInt <= 1 && PrevValueInt == 1))<br>
-          S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)<br>
-              << /*Duplicate=*/false << LoopHintAttr::getOptionName(PrevOption)<br>
-              << LoopHintAttr::getValueName(PrevValueInt)<br>
-              << LoopHintAttr::getOptionName(Option) << ValueInt;<br>
-      }<br>
-<br>
-      if (PrevOptionValue[Value] != -1) {<br>
-        // Cannot specify a width/count twice.<br>
-        int PrevValueInt = PrevOptionValue[Value];<br>
+      // Numeric hint.  For example, unroll_count(8).<br>
+      if (CategoryState.ValueIsSet) {<br>
+        // Cannot specify numeric hint twice.<br>
         S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)<br>
             << /*Duplicate=*/true << LoopHintAttr::getOptionName(Option)<br>
-            << PrevValueInt << LoopHintAttr::getOptionName(Option) << ValueInt;<br>
+            << CategoryState.Value << LoopHintAttr::getOptionName(Option)<br>
+            << ValueInt;<br>
       }<br>
+      CategoryState.ValueIsSet = true;<br>
+      CategoryState.Value = ValueInt;<br>
     }<br>
<br>
-    PrevOptionValue[Option] = ValueInt;<br>
+    if (CategoryState.EnabledIsSet && !CategoryState.Enabled &&<br>
+        CategoryState.ValueIsSet) {<br>
+      // Disable hints are not compatible with numeric hints of the<br>
+      // same category.<br>
+      S.Diag(ValueLoc, diag::err_pragma_loop_compatibility)<br>
+          << /*Duplicate=*/false<br>
+          << LoopHintAttr::getOptionName(CategoryState.EnableOptionId)<br>
+          << LoopHintAttr::getValueName(CategoryState.Enabled)<br>
+          << LoopHintAttr::getOptionName(CategoryState.NumericOptionId)<br>
+          << CategoryState.Value;<br>
+    }<br>
   }<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/test/CodeGen/pragma-loop.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/pragma-loop.cpp?rev=210667&r1=210666&r2=210667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/pragma-loop.cpp?rev=210667&r1=210666&r2=210667&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/CodeGen/pragma-loop.cpp (original)<br>
+++ cfe/trunk/test/CodeGen/pragma-loop.cpp Wed Jun 11 12:56:26 2014<br>
@@ -8,6 +8,7 @@ void while_test(int *List, int Length) {<br>
 #pragma clang loop vectorize(enable)<br>
 #pragma clang loop interleave_count(4)<br>
 #pragma clang loop vectorize_width(4)<br>
+#pragma clang loop unroll(enable)<br>
   while (i < Length) {<br>
     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_1:.*]]<br>
     List[i] = i * 2;<br>
@@ -19,7 +20,7 @@ void while_test(int *List, int Length) {<br>
 void do_test(int *List, int Length) {<br>
   int i = 0;<br>
<br>
-#pragma clang loop vectorize_width(8) interleave_count(4)<br>
+#pragma clang loop vectorize_width(8) interleave_count(4) unroll(disable)<br>
   do {<br>
     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]<br>
     List[i] = i * 2;<br>
@@ -31,6 +32,7 @@ void do_test(int *List, int Length) {<br>
 void for_test(int *List, int Length) {<br>
 #pragma clang loop interleave(enable)<br>
 #pragma clang loop interleave_count(4)<br>
+#pragma clang loop unroll_count(8)<br>
   for (int i = 0; i < Length; i++) {<br>
     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_3:.*]]<br>
     List[i] = i * 2;<br>
@@ -51,7 +53,7 @@ void for_range_test() {<br>
<br>
 // Verify disable pragma clang loop directive generates correct metadata<br>
 void disable_test(int *List, int Length) {<br>
-#pragma clang loop vectorize(disable)<br>
+#pragma clang loop vectorize(disable) unroll(disable)<br>
   for (int i = 0; i < Length; i++) {<br>
     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_5:.*]]<br>
     List[i] = i * 2;<br>
@@ -60,10 +62,12 @@ void disable_test(int *List, int Length)<br>
<br>
 #define VECWIDTH 2<br>
 #define INTCOUNT 2<br>
+#define UNROLLCOUNT 8<br>
<br>
 // Verify defines are correctly resolved in pragma clang loop directive<br>
 void for_define_test(int *List, int Length, int Value) {<br>
 #pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)<br>
+#pragma clang loop unroll_count(UNROLLCOUNT)<br>
   for (int i = 0; i < Length; i++) {<br>
     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_6:.*]]<br>
     List[i] = i * Value;<br>
@@ -74,7 +78,7 @@ void for_define_test(int *List, int Leng<br>
 template <typename A><br>
 void for_template_test(A *List, int Length, A Value) {<br>
<br>
-#pragma clang loop vectorize_width(8) interleave_count(8)<br>
+#pragma clang loop vectorize_width(8) interleave_count(8) unroll_count(8)<br>
   for (int i = 0; i < Length; i++) {<br>
     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_7:.*]]<br>
     List[i] = i * Value;<br>
@@ -85,6 +89,7 @@ void for_template_test(A *List, int Leng<br>
 template <typename A><br>
 void for_template_define_test(A *List, int Length, A Value) {<br>
 #pragma clang loop vectorize_width(VECWIDTH) interleave_count(INTCOUNT)<br>
+#pragma clang loop unroll_count(UNROLLCOUNT)<br>
   for (int i = 0; i < Length; i++) {<br>
     // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_8:.*]]<br>
     List[i] = i * Value;<br>
@@ -93,6 +98,7 @@ void for_template_define_test(A *List, i<br>
<br>
 #undef VECWIDTH<br>
 #undef INTCOUNT<br>
+#undef UNROLLCOUNT<br>
<br>
 // Use templates defined above. Test verifies metadata is generated correctly.<br>
 void template_test(double *List, int Length) {<br>
@@ -102,19 +108,22 @@ void template_test(double *List, int Len<br>
   for_template_define_test<double>(List, Length, Value);<br>
 }<br>
<br>
-// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[WIDTH_4:.*]], metadata ![[UNROLL_4:.*]], metadata ![[ENABLE_1:.*]]}<br>
+// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[UNROLLENABLE_1:.*]], metadata ![[WIDTH_4:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[INTENABLE_1:.*]]}<br>
+// CHECK: ![[UNROLLENABLE_1]] = metadata !{metadata !"llvm.loopunroll.enable", i1 true}<br>
 // CHECK: ![[WIDTH_4]] = metadata !{metadata !"llvm.vectorizer.width", i32 4}<br>
-// CHECK: ![[UNROLL_4]] = metadata !{metadata !"llvm.vectorizer.unroll", i32 4}<br>
-// CHECK: ![[ENABLE_1]] = metadata !{metadata !"llvm.vectorizer.enable", i1 true}<br>
-// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata ![[UNROLL_4:.*]], metadata ![[WIDTH_8:.*]]}<br>
+// CHECK: ![[INTERLEAVE_4]] = metadata !{metadata !"llvm.vectorizer.unroll", i32 4}<br>
+// CHECK: ![[INTENABLE_1]] = metadata !{metadata !"llvm.vectorizer.enable", i1 true}<br>
+// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata ![[UNROLLENABLE_0:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[WIDTH_8:.*]]}<br>
+// CHECK: ![[UNROLLENABLE_0]] = metadata !{metadata !"llvm.loopunroll.enable", i1 false}<br>
 // CHECK: ![[WIDTH_8]] = metadata !{metadata !"llvm.vectorizer.width", i32 8}<br>
-// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_4:.*]], metadata ![[ENABLE_1:.*]]}<br>
-// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[UNROLL_2:.*]], metadata ![[WIDTH_2:.*]]}<br>
-// CHECK: ![[UNROLL_2]] = metadata !{metadata !"llvm.vectorizer.unroll", i32 2}<br>
+// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_4:.*]], metadata ![[ENABLE_1:.*]]}<br>
+// CHECK: ![[UNROLL_8]] = metadata !{metadata !"llvm.loopunroll.count", i32 8}<br>
+// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}<br>
+// CHECK: ![[INTERLEAVE_2]] = metadata !{metadata !"llvm.vectorizer.unroll", i32 2}<br>
 // CHECK: ![[WIDTH_2]] = metadata !{metadata !"llvm.vectorizer.width", i32 2}<br>
-// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata ![[WIDTH_1:.*]]}<br>
+// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata ![[UNROLLENABLE_0:.*]], metadata ![[WIDTH_1:.*]]}<br>
 // CHECK: ![[WIDTH_1]] = metadata !{metadata !"llvm.vectorizer.width", i32 1}<br>
-// CHECK: ![[LOOP_6]] = metadata !{metadata ![[LOOP_6]], metadata ![[UNROLL_2:.*]], metadata ![[WIDTH_2:.*]]}<br>
-// CHECK: ![[LOOP_7]] = metadata !{metadata ![[LOOP_7]], metadata ![[UNROLL_8:.*]], metadata ![[WIDTH_8:.*]]}<br>
-// CHECK: ![[UNROLL_8]] = metadata !{metadata !"llvm.vectorizer.unroll", i32 8}<br>
-// CHECK: ![[LOOP_8]] = metadata !{metadata ![[LOOP_8]], metadata ![[UNROLL_2:.*]], metadata ![[WIDTH_2:.*]]}<br>
+// CHECK: ![[LOOP_6]] = metadata !{metadata ![[LOOP_6]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}<br>
+// CHECK: ![[LOOP_7]] = metadata !{metadata ![[LOOP_7]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_8:.*]], metadata ![[WIDTH_8:.*]]}<br>
+// CHECK: ![[INTERLEAVE_8]] = metadata !{metadata !"llvm.vectorizer.unroll", i32 8}<br>
+// CHECK: ![[LOOP_8]] = metadata !{metadata ![[LOOP_8]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}<br>
<br>
Modified: cfe/trunk/test/PCH/pragma-loop.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pragma-loop.cpp?rev=210667&r1=210666&r2=210667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pragma-loop.cpp?rev=210667&r1=210666&r2=210667&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/PCH/pragma-loop.cpp (original)<br>
+++ cfe/trunk/test/PCH/pragma-loop.cpp Wed Jun 11 12:56:26 2014<br>
@@ -4,10 +4,13 @@<br>
 // FIXME: A bug in ParsedAttributes causes the order of the attributes to be<br>
 // reversed. The checks are consequently in the reverse order below.<br>
<br>
+// CHECK: #pragma clang loop unroll_count(16)<br>
 // CHECK: #pragma clang loop interleave_count(8)<br>
 // CHECK: #pragma clang loop vectorize_width(4)<br>
+// CHECK: #pragma clang loop unroll(disable)<br>
 // CHECK: #pragma clang loop interleave(disable)<br>
 // CHECK: #pragma clang loop vectorize(enable)<br>
+// CHECK: #pragma clang loop unroll(enable)<br>
 // CHECK: #pragma clang loop interleave(enable)<br>
 // CHECK: #pragma clang loop vectorize(disable)<br>
<br>
@@ -20,6 +23,7 @@ public:<br>
     int i = 0;<br>
 #pragma clang loop vectorize_width(4)<br>
 #pragma clang loop interleave_count(8)<br>
+#pragma clang loop unroll_count(16)<br>
     while (i < Length) {<br>
       List[i] = i;<br>
       i++;<br>
@@ -30,6 +34,7 @@ public:<br>
     int i = 0;<br>
 #pragma clang loop vectorize(enable)<br>
 #pragma clang loop interleave(disable)<br>
+#pragma clang loop unroll(disable)<br>
     while (i - 1 < Length) {<br>
       List[i] = i;<br>
       i++;<br>
@@ -40,6 +45,7 @@ public:<br>
     int i = 0;<br>
 #pragma clang loop vectorize(disable)<br>
 #pragma clang loop interleave(enable)<br>
+#pragma clang loop unroll(enable)<br>
     while (i - 3 < Length) {<br>
       List[i] = i;<br>
       i++;<br>
<br>
Modified: cfe/trunk/test/Parser/pragma-loop.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-loop.cpp?rev=210667&r1=210666&r2=210667&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-loop.cpp?rev=210667&r1=210666&r2=210667&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/Parser/pragma-loop.cpp (original)<br>
+++ cfe/trunk/test/Parser/pragma-loop.cpp Wed Jun 11 12:56:26 2014<br>
@@ -8,23 +8,26 @@ void test(int *List, int Length) {<br>
<br>
 #pragma clang loop vectorize(enable)<br>
 #pragma clang loop interleave(enable)<br>
+#pragma clang loop unroll(enable)<br>
   while (i + 1 < Length) {<br>
     List[i] = i;<br>
   }<br>
<br>
 #pragma clang loop vectorize_width(4)<br>
 #pragma clang loop interleave_count(8)<br>
+#pragma clang loop unroll_count(16)<br>
   while (i < Length) {<br>
     List[i] = i;<br>
   }<br>
<br>
 #pragma clang loop vectorize(disable)<br>
 #pragma clang loop interleave(disable)<br>
+#pragma clang loop unroll(disable)<br>
   while (i - 1 < Length) {<br>
     List[i] = i;<br>
   }<br>
<br>
-#pragma clang loop vectorize_width(4) interleave_count(8)<br>
+#pragma clang loop vectorize_width(4) interleave_count(8) unroll_count(16)<br>
   while (i - 2 < Length) {<br>
     List[i] = i;<br>
   }<br>
@@ -35,19 +38,22 @@ void test(int *List, int Length) {<br>
   }<br>
<br>
   int VList[Length];<br>
-#pragma clang loop vectorize(disable) interleave(disable)<br>
+#pragma clang loop vectorize(disable) interleave(disable) unroll(disable)<br>
   for (int j : VList) {<br>
     VList[j] = List[j];<br>
   }<br>
<br>
 /* expected-error {{expected '('}} */ #pragma clang loop vectorize<br>
 /* expected-error {{expected '('}} */ #pragma clang loop interleave<br>
+/* expected-error {{expected '('}} */ #pragma clang loop unroll<br>
<br>
 /* expected-error {{expected ')'}} */ #pragma clang loop vectorize(enable<br>
 /* expected-error {{expected ')'}} */ #pragma clang loop interleave(enable<br>
+/* expected-error {{expected ')'}} */ #pragma clang loop unroll(enable<br>
<br>
 /* expected-error {{expected ')'}} */ #pragma clang loop vectorize_width(4<br>
 /* expected-error {{expected ')'}} */ #pragma clang loop interleave_count(4<br>
+/* expected-error {{expected ')'}} */ #pragma clang loop unroll_count(4<br>
<br>
 /* expected-error {{missing option}} */ #pragma clang loop<br>
 /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword<br>
@@ -61,24 +67,28 @@ void test(int *List, int Length) {<br>
<br>
 /* expected-error {{invalid value 0; expected a positive integer value}} */ #pragma clang loop vectorize_width(0)<br>
 /* expected-error {{invalid value 0; expected a positive integer value}} */ #pragma clang loop interleave_count(0)<br>
+/* expected-error {{invalid value 0; expected a positive integer value}} */ #pragma clang loop unroll_count(0)<br>
   while (i-5 < Length) {<br>
     List[i] = i;<br>
   }<br>
<br>
 /* expected-error {{invalid value -1294967296; expected a positive integer value}} */ #pragma clang loop vectorize_width(3000000000)<br>
 /* expected-error {{invalid value -1294967296; expected a positive integer value}} */ #pragma clang loop interleave_count(3000000000)<br>
+/* expected-error {{invalid value -1294967296; expected a positive integer value}} */ #pragma clang loop unroll_count(3000000000)<br>
   while (i-6 < Length) {<br>
     List[i] = i;<br>
   }<br>
<br>
 /* expected-error {{missing value; expected a positive integer value}} */ #pragma clang loop vectorize_width(badvalue)<br>
 /* expected-error {{missing value; expected a positive integer value}} */ #pragma clang loop interleave_count(badvalue)<br>
+/* expected-error {{missing value; expected a positive integer value}} */ #pragma clang loop unroll_count(badvalue)<br>
   while (i-6 < Length) {<br>
     List[i] = i;<br>
   }<br>
<br>
 /* expected-error {{invalid keyword 'badidentifier'; expected 'enable' or 'disable'}} */ #pragma clang loop vectorize(badidentifier)<br>
 /* expected-error {{invalid keyword 'badidentifier'; expected 'enable' or 'disable'}} */ #pragma clang loop interleave(badidentifier)<br>
+/* expected-error {{invalid keyword 'badidentifier'; expected 'enable' or 'disable'}} */ #pragma clang loop unroll(badidentifier)<br>
   while (i-7 < Length) {<br>
     List[i] = i;<br>
   }<br>
@@ -100,6 +110,8 @@ void test(int *List, int Length) {<br>
 #pragma clang loop vectorize(disable)<br>
 /* expected-error {{incompatible directives 'interleave(disable)' and 'interleave_count(4)'}} */ #pragma clang loop interleave_count(4)<br>
 #pragma clang loop interleave(disable)<br>
+/* expected-error {{incompatible directives 'unroll(disable)' and 'unroll_count(4)'}} */ #pragma clang loop unroll_count(4)<br>
+#pragma clang loop unroll(disable)<br>
   while (i-8 < Length) {<br>
     List[i] = i;<br>
   }<br>
@@ -108,14 +120,18 @@ void test(int *List, int Length) {<br>
 #pragma clang loop vectorize(disable)<br>
 /* expected-error {{duplicate directives 'interleave(disable)' and 'interleave(enable)'}} */ #pragma clang loop interleave(enable)<br>
 #pragma clang loop interleave(disable)<br>
+/* expected-error {{duplicate directives 'unroll(disable)' and 'unroll(enable)'}} */ #pragma clang loop unroll(enable)<br>
+#pragma clang loop unroll(disable)<br>
   while (i-9 < Length) {<br>
     List[i] = i;<br>
   }<br>
<br>
-/* expected-error {{incompatible directives 'vectorize_width(4)' and 'vectorize(disable)'}} */ #pragma clang loop vectorize(disable)<br>
+/* expected-error {{incompatible directives 'vectorize(disable)' and 'vectorize_width(4)'}} */ #pragma clang loop vectorize(disable)<br>
 #pragma clang loop vectorize_width(4)<br>
-/* expected-error {{incompatible directives 'interleave_count(4)' and 'interleave(disable)'}} */ #pragma clang loop interleave(disable)<br>
+/* expected-error {{incompatible directives 'interleave(disable)' and 'interleave_count(4)'}} */ #pragma clang loop interleave(disable)<br>
 #pragma clang loop interleave_count(4)<br>
+/* expected-error {{incompatible directives 'unroll(disable)' and 'unroll_count(4)'}} */ #pragma clang loop unroll(disable)<br>
+#pragma clang loop unroll_count(4)<br>
   while (i-10 < Length) {<br>
     List[i] = i;<br>
   }<br>
@@ -124,6 +140,8 @@ void test(int *List, int Length) {<br>
 #pragma clang loop vectorize_width(4)<br>
 /* expected-error {{duplicate directives 'interleave_count(4)' and 'interleave_count(8)'}} */ #pragma clang loop interleave_count(8)<br>
 #pragma clang loop interleave_count(4)<br>
+/* expected-error {{duplicate directives 'unroll_count(4)' and 'unroll_count(8)'}} */ #pragma clang loop unroll_count(8)<br>
+#pragma clang loop unroll_count(4)<br>
   while (i-11 < Length) {<br>
     List[i] = i;<br>
   }<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>~Craig
</div>