summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/LanguageExtensions.rst4
-rw-r--r--include/clang/Basic/Attr.td6
-rw-r--r--include/clang/Basic/AttrDocs.td2
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td2
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/CodeGen/CGStmt.cpp15
-rw-r--r--lib/Parse/ParsePragma.cpp19
-rw-r--r--lib/Sema/SemaStmtAttr.cpp42
-rw-r--r--test/CodeGen/pragma-loop.cpp4
-rw-r--r--test/CodeGen/pragma-unroll.cpp4
-rw-r--r--test/PCH/pragma-loop.cpp4
-rw-r--r--test/Parser/pragma-loop.cpp23
-rw-r--r--test/Parser/pragma-unroll.cpp36
13 files changed, 91 insertions, 72 deletions
diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index 50e1ccebe8..26c1418cb6 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -1843,7 +1843,7 @@ iterations. Full unrolling is only possible if the loop trip count is known at
compile time. Partial unrolling replicates the loop body within the loop and
reduces the trip count.
-If ``unroll(enable)`` is specified the unroller will attempt to fully unroll the
+If ``unroll(full)`` is specified the unroller will attempt to fully unroll the
loop if the trip count is known at compile time. If the loop count is not known
or the fully unrolled code size is greater than the limit specified by the
`-pragma-unroll-threshold` command line option the loop will be partially
@@ -1851,7 +1851,7 @@ unrolled subject to the same limit.
.. code-block:: c++
- #pragma clang loop unroll(enable)
+ #pragma clang loop unroll(full)
for(...) {
...
}
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 704a375ba2..708f4f49bd 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -1788,7 +1788,7 @@ def LoopHint : Attr {
/// vectorize_width: vectorize loop operations with width 'value'.
/// interleave: interleave multiple loop iterations if 'value != 0'.
/// interleave_count: interleaves 'value' loop interations.
- /// unroll: unroll loop if 'value != 0'.
+ /// unroll: fully unroll loop if 'value != 0'.
/// unroll_count: unrolls loop 'value' times.
let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">];
@@ -1842,6 +1842,10 @@ def LoopHint : Attr {
if (option == VectorizeWidth || option == InterleaveCount ||
option == UnrollCount)
OS << value;
+ else if (option == Unroll && value)
+ // Unroll loop hint does not use the keyword "enable". Instead, a nonzero value
+ // indicates full unrolling which uses the keyword "full".
+ OS << "full";
else if (value)
OS << "enable";
else
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 758705b4ad..655cc45ab9 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -1097,7 +1097,7 @@ enclosed in parentheses:
}
``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to
-``#pragma clang loop unroll(enable)`` and ``#pragma clang loop
+``#pragma clang loop unroll(full)`` and ``#pragma clang loop
unroll_count(_value_)`` respectively. See `language extensions
<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
for further details including limitations of the unroll hints.
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 35ed795c9f..38a4eac123 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -818,7 +818,7 @@ def warn_pragma_expected_non_wide_string : Warning<
"expected non-wide string literal in '#pragma %0'">, InGroup<IgnoredPragmas>;
// - Generic errors
def err_pragma_missing_argument : Error<
- "missing argument to '#pragma %0'; expected %1">;
+ "missing argument to '#pragma %0'%select{|; expected %2}1">;
// - #pragma options
def warn_pragma_options_expected_align : Warning<
"expected 'align' following '#pragma options' - ignored">,
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 85072f1d15..9c6ffc0517 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -539,7 +539,7 @@ def note_surrounding_namespace_starts_here : Note<
def err_pragma_loop_invalid_value : Error<
"invalid argument; expected a positive integer value">;
def err_pragma_loop_invalid_keyword : Error<
- "invalid argument; expected 'enable' or 'disable'">;
+ "invalid argument; expected '%0' or 'disable'">;
def err_pragma_loop_compatibility : Error<
"%select{incompatible|duplicate}0 directives '%1' and '%2'">;
def err_pragma_loop_precedes_nonloop : Error<
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index fdeaaf6bb8..62a80a334e 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -601,13 +601,14 @@ void CodeGenFunction::EmitCondBrHints(llvm::LLVMContext &Context,
MetadataName = "llvm.loop.interleave.count";
break;
case LoopHintAttr::Unroll:
- MetadataName = "llvm.loop.unroll.enable";
+ // With the unroll loop hint, a non-zero value indicates full unrolling.
+ MetadataName =
+ ValueInt == 0 ? "llvm.loop.unroll.disable" : "llvm.loop.unroll.full";
break;
case LoopHintAttr::UnrollCount:
MetadataName = "llvm.loop.unroll.count";
break;
}
-
llvm::Value *Value;
llvm::MDString *Name;
switch (Option) {
@@ -625,22 +626,20 @@ void CodeGenFunction::EmitCondBrHints(llvm::LLVMContext &Context,
// Fallthrough.
case LoopHintAttr::VectorizeWidth:
case LoopHintAttr::InterleaveCount:
+ case LoopHintAttr::UnrollCount:
Name = llvm::MDString::get(Context, MetadataName);
Value = llvm::ConstantInt::get(Int32Ty, ValueInt);
break;
case LoopHintAttr::Unroll:
Name = llvm::MDString::get(Context, MetadataName);
- Value = (ValueInt == 0) ? Builder.getFalse() : Builder.getTrue();
- break;
- case LoopHintAttr::UnrollCount:
- Name = llvm::MDString::get(Context, MetadataName);
- Value = llvm::ConstantInt::get(Int32Ty, ValueInt);
+ Value = nullptr;
break;
}
SmallVector<llvm::Value *, 2> OpValues;
OpValues.push_back(Name);
- OpValues.push_back(Value);
+ if (Value)
+ OpValues.push_back(Value);
// Set or overwrite metadata indicated by Name.
Metadata.push_back(llvm::MDNode::get(Context, OpValues));
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index b94c4bc944..5fb999d749 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -1719,8 +1719,7 @@ void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
PP.Lex(Tok);
if (Tok.is(tok::eod)) {
PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
- << "clang optimize"
- << "'on' or 'off'";
+ << "clang optimize" << /*Expected=*/true << "'on' or 'off'";
return;
}
if (Tok.isNot(tok::identifier)) {
@@ -1767,8 +1766,12 @@ static bool ParseLoopHintValue(Preprocessor &PP, Token Tok, Token &PragmaName,
"Unexpected pragma name");
PragmaString = "unroll";
}
+ // Don't try to emit what the pragma is expecting with the diagnostic
+ // because the logic is non-trivial and we give expected values in sema
+ // diagnostics if an invalid argument is given. Here, just note that the
+ // pragma is missing an argument.
PP.Diag(Tok.getLocation(), diag::err_pragma_missing_argument)
- << PragmaString << "a positive integer value";
+ << PragmaString << /*Expected=*/false;
return true;
}
}
@@ -1800,7 +1803,7 @@ static bool ParseLoopHintValue(Preprocessor &PP, Token Tok, Token &PragmaName,
/// loop-hint:
/// 'vectorize' '(' loop-hint-keyword ')'
/// 'interleave' '(' loop-hint-keyword ')'
-/// 'unroll' '(' loop-hint-keyword ')'
+/// 'unroll' '(' unroll-hint-keyword ')'
/// 'vectorize_width' '(' loop-hint-value ')'
/// 'interleave_count' '(' loop-hint-value ')'
/// 'unroll_count' '(' loop-hint-value ')'
@@ -1809,6 +1812,10 @@ static bool ParseLoopHintValue(Preprocessor &PP, Token Tok, Token &PragmaName,
/// 'enable'
/// 'disable'
///
+/// unroll-hint-keyword:
+/// 'full'
+/// 'disable'
+///
/// loop-hint-value:
/// constant-expression
///
@@ -1823,12 +1830,10 @@ static bool ParseLoopHintValue(Preprocessor &PP, Token Tok, Token &PragmaName,
/// only works on inner loops.
///
/// The unroll and unroll_count directives control the concatenation
-/// unroller. Specifying unroll(enable) instructs llvm to try to
+/// unroller. Specifying unroll(full) instructs llvm to try to
/// unroll the loop completely, and unroll(disable) disables unrolling
/// for the loop. Specifying unroll_count(_value_) instructs llvm to
/// try to unroll the loop the number of times indicated by the value.
-/// If unroll(enable) and unroll_count are both specified only
-/// unroll_count takes effect.
void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
PragmaIntroducerKind Introducer,
Token &Tok) {
diff --git a/lib/Sema/SemaStmtAttr.cpp b/lib/Sema/SemaStmtAttr.cpp
index a32e0fbcb6..603581d117 100644
--- a/lib/Sema/SemaStmtAttr.cpp
+++ b/lib/Sema/SemaStmtAttr.cpp
@@ -89,16 +89,22 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
} else if (Option == LoopHintAttr::Vectorize ||
Option == LoopHintAttr::Interleave ||
Option == LoopHintAttr::Unroll) {
+ // Unrolling uses the keyword "full" rather than "enable" to indicate full
+ // unrolling.
+ const char *TrueKeyword =
+ Option == LoopHintAttr::Unroll ? "full" : "enable";
if (!ValueInfo) {
- S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)
+ << TrueKeyword;
return nullptr;
}
if (ValueInfo->isStr("disable"))
ValueInt = 0;
- else if (ValueInfo->isStr("enable"))
+ else if (ValueInfo->getName() == TrueKeyword)
ValueInt = 1;
else {
- S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword);
+ S.Diag(ValueLoc->Loc, diag::err_pragma_loop_invalid_keyword)
+ << TrueKeyword;
return nullptr;
}
} else if (Option == LoopHintAttr::VectorizeWidth ||
@@ -121,12 +127,14 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
static void CheckForIncompatibleAttributes(
Sema &S, const SmallVectorImpl<const Attr *> &Attrs) {
- // There are 3 categories of loop hints: vectorize, interleave, and
- // unroll. Each comes in two variants: an enable/disable form and a
- // form which takes a numeric argument. For example:
- // unroll(enable|disable) and unroll_count(N). The following array
- // accumulate the hints encountered while iterating through the
- // attributes to check for compatibility.
+ // There are 3 categories of loop hints attributes: vectorize, interleave, and
+ // unroll. Each comes in two variants: a boolean form and a numeric form. The
+ // boolean hints selectively enables/disables the transformation for the loop
+ // (for unroll, a nonzero value indicates full unrolling rather than enabling
+ // the transformation). The numeric hint provides an integer hint (for
+ // example, unroll count) to the transformer. The following array accumulates
+ // the hints encountered while iterating through the attributes to check for
+ // compatibility.
struct {
const LoopHintAttr *EnableAttr;
const LoopHintAttr *NumericAttr;
@@ -141,18 +149,19 @@ static void CheckForIncompatibleAttributes(
int Option = LH->getOption();
int Category;
+ enum { Vectorize, Interleave, Unroll };
switch (Option) {
case LoopHintAttr::Vectorize:
case LoopHintAttr::VectorizeWidth:
- Category = 0;
+ Category = Vectorize;
break;
case LoopHintAttr::Interleave:
case LoopHintAttr::InterleaveCount:
- Category = 1;
+ Category = Interleave;
break;
case LoopHintAttr::Unroll:
case LoopHintAttr::UnrollCount:
- Category = 2;
+ Category = Unroll;
break;
};
@@ -176,10 +185,11 @@ static void CheckForIncompatibleAttributes(
<< /*Duplicate=*/true << PrevAttr->getDiagnosticName()
<< LH->getDiagnosticName();
- if (CategoryState.EnableAttr && !CategoryState.EnableAttr->getValue() &&
- CategoryState.NumericAttr) {
- // Disable hints are not compatible with numeric hints of the
- // same category.
+ if (CategoryState.EnableAttr && CategoryState.NumericAttr &&
+ (Category == Unroll || !CategoryState.EnableAttr->getValue())) {
+ // Disable hints are not compatible with numeric hints of the same
+ // category. As a special case, numeric unroll hints are also not
+ // compatible with "enable" form of the unroll pragma, unroll(full).
S.Diag(OptionLoc, diag::err_pragma_loop_compatibility)
<< /*Duplicate=*/false
<< CategoryState.EnableAttr->getDiagnosticName()
diff --git a/test/CodeGen/pragma-loop.cpp b/test/CodeGen/pragma-loop.cpp
index bdcd304263..331c5cf204 100644
--- a/test/CodeGen/pragma-loop.cpp
+++ b/test/CodeGen/pragma-loop.cpp
@@ -8,7 +8,7 @@ void while_test(int *List, int Length) {
#pragma clang loop vectorize(enable)
#pragma clang loop interleave_count(4)
#pragma clang loop vectorize_width(4)
-#pragma clang loop unroll(enable)
+#pragma clang loop unroll(full)
while (i < Length) {
// CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
List[i] = i * 2;
@@ -121,7 +121,7 @@ void template_test(double *List, int Length) {
// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
// CHECK: ![[INTERLEAVE_2]] = metadata !{metadata !"llvm.loop.interleave.count", i32 2}
// CHECK: ![[WIDTH_2]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 2}
-// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata ![[UNROLLENABLE_0:.*]], metadata ![[WIDTH_1:.*]]}
+// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata ![[UNROLL_DISABLE:.*]], metadata ![[WIDTH_1:.*]]}
// CHECK: ![[WIDTH_1]] = metadata !{metadata !"llvm.loop.vectorize.width", i32 1}
// CHECK: ![[LOOP_6]] = metadata !{metadata ![[LOOP_6]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_2:.*]], metadata ![[WIDTH_2:.*]]}
// CHECK: ![[LOOP_7]] = metadata !{metadata ![[LOOP_7]], metadata ![[UNROLL_8:.*]], metadata ![[INTERLEAVE_8:.*]], metadata ![[WIDTH_8:.*]]}
diff --git a/test/CodeGen/pragma-unroll.cpp b/test/CodeGen/pragma-unroll.cpp
index b321e74a11..9c3617e564 100644
--- a/test/CodeGen/pragma-unroll.cpp
+++ b/test/CodeGen/pragma-unroll.cpp
@@ -86,8 +86,8 @@ void template_test(double *List, int Length) {
for_template_define_test<double>(List, Length, Value);
}
-// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[UNROLLENABLE_1:.*]]}
-// CHECK: ![[UNROLLENABLE_1]] = metadata !{metadata !"llvm.loop.unroll.enable", i1 true}
+// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[UNROLL_FULL:.*]]}
+// CHECK: ![[UNROLL_FULL]] = metadata !{metadata !"llvm.loop.unroll.full"}
// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata ![[UNROLL_16:.*]]}
// CHECK: ![[UNROLL_16]] = metadata !{metadata !"llvm.loop.unroll.count", i32 16}
// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_8:.*]]}
diff --git a/test/PCH/pragma-loop.cpp b/test/PCH/pragma-loop.cpp
index 1456a2778f..670830d912 100644
--- a/test/PCH/pragma-loop.cpp
+++ b/test/PCH/pragma-loop.cpp
@@ -10,7 +10,7 @@
// CHECK: #pragma clang loop unroll(disable)
// CHECK: #pragma clang loop interleave(disable)
// CHECK: #pragma clang loop vectorize(enable)
-// CHECK: #pragma clang loop unroll(enable)
+// CHECK: #pragma clang loop unroll(full)
// CHECK: #pragma clang loop interleave(enable)
// CHECK: #pragma clang loop vectorize(disable)
// CHECK: #pragma unroll
@@ -47,7 +47,7 @@ public:
int i = 0;
#pragma clang loop vectorize(disable)
#pragma clang loop interleave(enable)
-#pragma clang loop unroll(enable)
+#pragma clang loop unroll(full)
while (i - 3 < Length) {
List[i] = i;
i++;
diff --git a/test/Parser/pragma-loop.cpp b/test/Parser/pragma-loop.cpp
index 23f185d522..ac07af9bc7 100644
--- a/test/Parser/pragma-loop.cpp
+++ b/test/Parser/pragma-loop.cpp
@@ -8,7 +8,7 @@ void test(int *List, int Length) {
#pragma clang loop vectorize(enable)
#pragma clang loop interleave(enable)
-#pragma clang loop unroll(enable)
+#pragma clang loop unroll(full)
while (i + 1 < Length) {
List[i] = i;
}
@@ -49,15 +49,15 @@ void test(int *List, int Length) {
/* expected-error {{expected ')'}} */ #pragma clang loop vectorize(enable
/* expected-error {{expected ')'}} */ #pragma clang loop interleave(enable
-/* expected-error {{expected ')'}} */ #pragma clang loop unroll(enable
+/* expected-error {{expected ')'}} */ #pragma clang loop unroll(full
/* expected-error {{expected ')'}} */ #pragma clang loop vectorize_width(4
/* expected-error {{expected ')'}} */ #pragma clang loop interleave_count(4
/* expected-error {{expected ')'}} */ #pragma clang loop unroll_count(4
-/* expected-error {{missing argument to '#pragma clang loop vectorize'; expected a positive integer value}} */ #pragma clang loop vectorize()
-/* expected-error {{missing argument to '#pragma clang loop interleave_count'; expected a positive integer value}} */ #pragma clang loop interleave_count()
-/* expected-error {{missing argument to '#pragma clang loop unroll'; expected a positive integer value}} */ #pragma clang loop unroll()
+/* expected-error {{missing argument to '#pragma clang loop vectorize'}} */ #pragma clang loop vectorize()
+/* expected-error {{missing argument to '#pragma clang loop interleave_count'}} */ #pragma clang loop interleave_count()
+/* expected-error {{missing argument to '#pragma clang loop unroll'}} */ #pragma clang loop unroll()
/* expected-error {{missing option}} */ #pragma clang loop
/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword
@@ -92,7 +92,7 @@ void test(int *List, int Length) {
/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop vectorize(badidentifier)
/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop interleave(badidentifier)
-/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop unroll(badidentifier)
+/* expected-error {{invalid argument; expected 'full' or 'disable'}} */ #pragma clang loop unroll(badidentifier)
while (i-7 < Length) {
List[i] = i;
}
@@ -101,7 +101,7 @@ void test(int *List, int Length) {
// constants crash FE.
/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop vectorize(()
/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop interleave(*)
-/* expected-error {{invalid argument; expected 'enable' or 'disable'}} */ #pragma clang loop unroll(=)
+/* expected-error {{invalid argument; expected 'full' or 'disable'}} */ #pragma clang loop unroll(=)
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop vectorize_width(^)
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop interleave_count(/)
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma clang loop unroll_count(==)
@@ -136,7 +136,7 @@ void test(int *List, int Length) {
#pragma clang loop vectorize(disable)
/* expected-error {{duplicate directives 'interleave(disable)' and 'interleave(enable)'}} */ #pragma clang loop interleave(enable)
#pragma clang loop interleave(disable)
-/* expected-error {{duplicate directives 'unroll(disable)' and 'unroll(enable)'}} */ #pragma clang loop unroll(enable)
+/* expected-error {{duplicate directives 'unroll(disable)' and 'unroll(full)'}} */ #pragma clang loop unroll(full)
#pragma clang loop unroll(disable)
while (i-9 < Length) {
List[i] = i;
@@ -162,5 +162,12 @@ void test(int *List, int Length) {
List[i] = i;
}
+
+/* expected-error {{incompatible directives 'unroll(full)' and 'unroll_count(4)'}} */ #pragma clang loop unroll(full)
+#pragma clang loop unroll_count(4)
+ while (i-11 < Length) {
+ List[i] = i;
+ }
+
#pragma clang loop interleave(enable)
/* expected-error {{expected statement}} */ }
diff --git a/test/Parser/pragma-unroll.cpp b/test/Parser/pragma-unroll.cpp
index 1d89e63028..1fa23ef467 100644
--- a/test/Parser/pragma-unroll.cpp
+++ b/test/Parser/pragma-unroll.cpp
@@ -21,26 +21,8 @@ void test(int *List, int Length) {
List[i] = i;
}
-#pragma unroll
-#pragma unroll(8)
- while (i - 3 < Length) {
- List[i] = i;
- }
-
-#pragma clang loop unroll(enable)
-#pragma unroll(8)
- while (i - 4 < Length) {
- List[i] = i;
- }
-
-#pragma unroll
-#pragma clang loop unroll_count(4)
- while (i - 5 < Length) {
- List[i] = i;
- }
-
/* expected-error {{expected ')'}} */ #pragma unroll(4
-/* expected-error {{missing argument to '#pragma unroll'; expected a positive integer value}} */ #pragma unroll()
+/* expected-error {{missing argument to '#pragma unroll'}} */ #pragma unroll()
/* expected-warning {{extra tokens at end of '#pragma unroll'}} */ #pragma unroll 1 2
while (i-6 < Length) {
List[i] = i;
@@ -67,14 +49,26 @@ void test(int *List, int Length) {
List[i] = i;
}
+/* expected-error {{incompatible directives 'unroll(full)' and '#pragma unroll(4)'}} */ #pragma unroll(4)
+#pragma clang loop unroll(full)
+ while (i-11 < Length) {
+ List[i] = i;
+ }
+
+/* expected-error {{incompatible directives '#pragma unroll' and '#pragma unroll(4)'}} */ #pragma unroll(4)
+#pragma unroll
+ while (i-11 < Length) {
+ List[i] = i;
+ }
+
/* expected-error {{duplicate directives '#pragma unroll' and '#pragma unroll'}} */ #pragma unroll
#pragma unroll
while (i-14 < Length) {
List[i] = i;
}
-/* expected-error {{duplicate directives 'unroll(enable)' and '#pragma unroll'}} */ #pragma unroll
-#pragma clang loop unroll(enable)
+/* expected-error {{duplicate directives 'unroll(full)' and '#pragma unroll'}} */ #pragma unroll
+#pragma clang loop unroll(full)
while (i-15 < Length) {
List[i] = i;
}