forked from OSchip/llvm-project
parent
29a2005596
commit
c888e41c0c
|
@ -111,12 +111,13 @@ interleaving, and unrolling to be enabled or disabled. Vector width as well
|
||||||
as interleave and unrolling count can be manually specified. See language
|
as interleave and unrolling count can be manually specified. See language
|
||||||
extensions for details.
|
extensions for details.
|
||||||
|
|
||||||
Clang now supports the `#pragma unroll` directive to specify loop unrolling
|
Clang now supports the `#pragma unroll` and `#pragma nounroll` directives to
|
||||||
optimization hints. Placed just prior to the desired loop, `#pragma unroll`
|
specify loop unrolling optimization hints. Placed just prior to the desired
|
||||||
directs the loop unroller to attempt to fully unroll the loop. The pragma may
|
loop, `#pragma unroll` directs the loop unroller to attempt to fully unroll the
|
||||||
also be specified with a positive integer parameter indicating the desired
|
loop. The pragma may also be specified with a positive integer parameter
|
||||||
unroll count: `#pragma unroll _value_`. The unroll count parameter can be
|
indicating the desired unroll count: `#pragma unroll _value_`. The unroll count
|
||||||
optionally enclosed in parentheses.
|
parameter can be optionally enclosed in parentheses. The directive `#pragma
|
||||||
|
nounroll` indicates that the loop should not be unrolled.
|
||||||
|
|
||||||
C Language Changes in Clang
|
C Language Changes in Clang
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
|
@ -1791,7 +1791,8 @@ def LoopHint : Attr {
|
||||||
/// unroll: fully unroll loop if 'value != 0'.
|
/// unroll: fully unroll loop if 'value != 0'.
|
||||||
/// unroll_count: unrolls loop 'value' times.
|
/// unroll_count: unrolls loop 'value' times.
|
||||||
|
|
||||||
let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">];
|
let Spellings = [Pragma<"clang", "loop">, Pragma<"", "unroll">,
|
||||||
|
Pragma<"", "nounroll">];
|
||||||
|
|
||||||
/// State of the loop optimization specified by the spelling.
|
/// State of the loop optimization specified by the spelling.
|
||||||
let Args = [EnumArgument<"Option", "OptionType",
|
let Args = [EnumArgument<"Option", "OptionType",
|
||||||
|
@ -1822,9 +1823,13 @@ def LoopHint : Attr {
|
||||||
|
|
||||||
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
|
void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const {
|
||||||
unsigned SpellingIndex = getSpellingListIndex();
|
unsigned SpellingIndex = getSpellingListIndex();
|
||||||
|
// For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
|
||||||
|
// "nounroll" is already emitted as the pragma name.
|
||||||
|
if (SpellingIndex == Pragma_nounroll) {
|
||||||
|
OS << "\n";
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (SpellingIndex == Pragma_unroll) {
|
if (SpellingIndex == Pragma_unroll) {
|
||||||
// String "unroll" of "#pragma unroll" is already emitted as the
|
|
||||||
// pragma name.
|
|
||||||
if (option == UnrollCount)
|
if (option == UnrollCount)
|
||||||
printArgument(OS);
|
printArgument(OS);
|
||||||
OS << "\n";
|
OS << "\n";
|
||||||
|
@ -1858,11 +1863,12 @@ def LoopHint : Attr {
|
||||||
std::string DiagnosticName;
|
std::string DiagnosticName;
|
||||||
llvm::raw_string_ostream OS(DiagnosticName);
|
llvm::raw_string_ostream OS(DiagnosticName);
|
||||||
unsigned SpellingIndex = getSpellingListIndex();
|
unsigned SpellingIndex = getSpellingListIndex();
|
||||||
if (SpellingIndex == Pragma_unroll && option == Unroll)
|
if (SpellingIndex == Pragma_nounroll)
|
||||||
|
OS << "#pragma nounroll";
|
||||||
|
else if (SpellingIndex == Pragma_unroll) {
|
||||||
OS << "#pragma unroll";
|
OS << "#pragma unroll";
|
||||||
else if (SpellingIndex == Pragma_unroll && option == UnrollCount) {
|
if (option == UnrollCount)
|
||||||
OS << "#pragma unroll";
|
printArgument(OS);
|
||||||
printArgument(OS);
|
|
||||||
} else {
|
} else {
|
||||||
assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
|
assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
|
||||||
OS << getOptionName(option);
|
OS << getOptionName(option);
|
||||||
|
|
|
@ -1065,11 +1065,11 @@ for details.
|
||||||
|
|
||||||
def UnrollHintDocs : Documentation {
|
def UnrollHintDocs : Documentation {
|
||||||
let Category = DocCatStmt;
|
let Category = DocCatStmt;
|
||||||
let Heading = "#pragma unroll";
|
let Heading = "#pragma unroll, #pragma nounroll";
|
||||||
let Content = [{
|
let Content = [{
|
||||||
Loop unrolling optimization hints can be specified with ``#pragma unroll``. The
|
Loop unrolling optimization hints can be specified with ``#pragma unroll`` and
|
||||||
pragma is placed immediately before a for, while, do-while, or c++11 range-based
|
``#pragma nounroll``. The pragma is placed immediately before a for, while,
|
||||||
for loop.
|
do-while, or c++11 range-based for loop.
|
||||||
|
|
||||||
Specifying ``#pragma unroll`` without a parameter directs the loop unroller to
|
Specifying ``#pragma unroll`` without a parameter directs the loop unroller to
|
||||||
attempt to fully unroll the loop if the trip count is known at compile time:
|
attempt to fully unroll the loop if the trip count is known at compile time:
|
||||||
|
@ -1097,9 +1097,20 @@ enclosed in parentheses:
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Specifying ``#pragma nounroll`` indicates that the loop should not be unrolled:
|
||||||
|
|
||||||
|
.. code-block:: c++
|
||||||
|
|
||||||
|
#pragma nounroll
|
||||||
|
for (...) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to
|
``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to
|
||||||
``#pragma clang loop unroll(full)`` and ``#pragma clang loop
|
``#pragma clang loop unroll(full)`` and
|
||||||
unroll_count(_value_)`` respectively. See `language extensions
|
``#pragma clang loop unroll_count(_value_)`` respectively. ``#pragma nounroll``
|
||||||
|
is equivalent to ``#pragma clang loop unroll(disable)``. See
|
||||||
|
`language extensions
|
||||||
<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
|
<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
|
||||||
for further details including limitations of the unroll hints.
|
for further details including limitations of the unroll hints.
|
||||||
}];
|
}];
|
||||||
|
|
|
@ -164,6 +164,7 @@ class Parser : public CodeCompletionHandler {
|
||||||
std::unique_ptr<PragmaHandler> OptimizeHandler;
|
std::unique_ptr<PragmaHandler> OptimizeHandler;
|
||||||
std::unique_ptr<PragmaHandler> LoopHintHandler;
|
std::unique_ptr<PragmaHandler> LoopHintHandler;
|
||||||
std::unique_ptr<PragmaHandler> UnrollHintHandler;
|
std::unique_ptr<PragmaHandler> UnrollHintHandler;
|
||||||
|
std::unique_ptr<PragmaHandler> NoUnrollHintHandler;
|
||||||
|
|
||||||
std::unique_ptr<CommentHandler> CommentSemaHandler;
|
std::unique_ptr<CommentHandler> CommentSemaHandler;
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,8 @@ struct LoopHint {
|
||||||
// hints.
|
// hints.
|
||||||
IdentifierLoc *PragmaNameLoc;
|
IdentifierLoc *PragmaNameLoc;
|
||||||
// Name of the loop hint. Examples: "unroll", "vectorize". In the
|
// Name of the loop hint. Examples: "unroll", "vectorize". In the
|
||||||
// "#pragma unroll" case, this is identical to PragmaNameLoc.
|
// "#pragma unroll" and "#pragma nounroll" cases, this is identical to
|
||||||
|
// PragmaNameLoc.
|
||||||
IdentifierLoc *OptionLoc;
|
IdentifierLoc *OptionLoc;
|
||||||
// Identifier for the hint argument. If null, then the hint has no argument
|
// Identifier for the hint argument. If null, then the hint has no argument
|
||||||
// such as for "#pragma unroll".
|
// such as for "#pragma unroll".
|
||||||
|
|
|
@ -227,6 +227,9 @@ void Parser::initializePragmaHandlers() {
|
||||||
|
|
||||||
UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll"));
|
UnrollHintHandler.reset(new PragmaUnrollHintHandler("unroll"));
|
||||||
PP.AddPragmaHandler(UnrollHintHandler.get());
|
PP.AddPragmaHandler(UnrollHintHandler.get());
|
||||||
|
|
||||||
|
NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll"));
|
||||||
|
PP.AddPragmaHandler(NoUnrollHintHandler.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::resetPragmaHandlers() {
|
void Parser::resetPragmaHandlers() {
|
||||||
|
@ -290,6 +293,9 @@ void Parser::resetPragmaHandlers() {
|
||||||
|
|
||||||
PP.RemovePragmaHandler(UnrollHintHandler.get());
|
PP.RemovePragmaHandler(UnrollHintHandler.get());
|
||||||
UnrollHintHandler.reset();
|
UnrollHintHandler.reset();
|
||||||
|
|
||||||
|
PP.RemovePragmaHandler(NoUnrollHintHandler.get());
|
||||||
|
NoUnrollHintHandler.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Handle the annotation token produced for #pragma unused(...)
|
/// \brief Handle the annotation token produced for #pragma unused(...)
|
||||||
|
@ -1908,29 +1914,36 @@ void PragmaLoopHintHandler::HandlePragma(Preprocessor &PP,
|
||||||
/// #pragma unroll
|
/// #pragma unroll
|
||||||
/// #pragma unroll unroll-hint-value
|
/// #pragma unroll unroll-hint-value
|
||||||
/// #pragma unroll '(' unroll-hint-value ')'
|
/// #pragma unroll '(' unroll-hint-value ')'
|
||||||
|
/// #pragma nounroll
|
||||||
///
|
///
|
||||||
/// unroll-hint-value:
|
/// unroll-hint-value:
|
||||||
/// constant-expression
|
/// constant-expression
|
||||||
///
|
///
|
||||||
/// Loop unrolling hints are specified with '#pragma unroll'. '#pragma unroll'
|
/// Loop unrolling hints can be specified with '#pragma unroll' or
|
||||||
/// can take a numeric argument optionally contained in parentheses. With no
|
/// '#pragma nounroll'. '#pragma unroll' can take a numeric argument optionally
|
||||||
/// argument the directive instructs llvm to try to unroll the loop
|
/// contained in parentheses. With no argument the directive instructs llvm to
|
||||||
/// completely. A positive integer argument can be specified to indicate the
|
/// try to unroll the loop completely. A positive integer argument can be
|
||||||
/// number of times the loop should be unrolled. To maximize compatibility with
|
/// specified to indicate the number of times the loop should be unrolled. To
|
||||||
/// other compilers the unroll count argument can be specified with or without
|
/// maximize compatibility with other compilers the unroll count argument can be
|
||||||
/// parentheses.
|
/// specified with or without parentheses. Specifying, '#pragma nounroll'
|
||||||
|
/// disables unrolling of the loop.
|
||||||
void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
|
void PragmaUnrollHintHandler::HandlePragma(Preprocessor &PP,
|
||||||
PragmaIntroducerKind Introducer,
|
PragmaIntroducerKind Introducer,
|
||||||
Token &Tok) {
|
Token &Tok) {
|
||||||
// Incoming token is "unroll" of "#pragma unroll".
|
// Incoming token is "unroll" for "#pragma unroll", or "nounroll" for
|
||||||
|
// "#pragma nounroll".
|
||||||
Token PragmaName = Tok;
|
Token PragmaName = Tok;
|
||||||
PP.Lex(Tok);
|
PP.Lex(Tok);
|
||||||
auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
|
auto *Info = new (PP.getPreprocessorAllocator()) PragmaLoopHintInfo;
|
||||||
if (Tok.is(tok::eod)) {
|
if (Tok.is(tok::eod)) {
|
||||||
// Unroll pragma without an argument.
|
// nounroll or unroll pragma without an argument.
|
||||||
Info->PragmaName = PragmaName;
|
Info->PragmaName = PragmaName;
|
||||||
Info->Option = PragmaName;
|
Info->Option = PragmaName;
|
||||||
Info->HasValue = false;
|
Info->HasValue = false;
|
||||||
|
} else if (PragmaName.getIdentifierInfo()->getName() == "nounroll") {
|
||||||
|
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
|
||||||
|
<< "nounroll";
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
// Unroll pragma with an argument: "#pragma unroll N" or
|
// Unroll pragma with an argument: "#pragma unroll N" or
|
||||||
// "#pragma unroll(N)".
|
// "#pragma unroll(N)".
|
||||||
|
|
|
@ -58,9 +58,11 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
|
||||||
St->getStmtClass() != Stmt::ForStmtClass &&
|
St->getStmtClass() != Stmt::ForStmtClass &&
|
||||||
St->getStmtClass() != Stmt::CXXForRangeStmtClass &&
|
St->getStmtClass() != Stmt::CXXForRangeStmtClass &&
|
||||||
St->getStmtClass() != Stmt::WhileStmtClass) {
|
St->getStmtClass() != Stmt::WhileStmtClass) {
|
||||||
const char *Pragma = PragmaNameLoc->Ident->getName() == "unroll"
|
const char *Pragma =
|
||||||
? "#pragma unroll"
|
llvm::StringSwitch<const char *>(PragmaNameLoc->Ident->getName())
|
||||||
: "#pragma clang loop";
|
.Case("unroll", "#pragma unroll")
|
||||||
|
.Case("nounroll", "#pragma nounroll")
|
||||||
|
.Default("#pragma clang loop");
|
||||||
S.Diag(St->getLocStart(), diag::err_pragma_loop_precedes_nonloop) << Pragma;
|
S.Diag(St->getLocStart(), diag::err_pragma_loop_precedes_nonloop) << Pragma;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -70,6 +72,9 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
|
||||||
if (PragmaNameLoc->Ident->getName() == "unroll") {
|
if (PragmaNameLoc->Ident->getName() == "unroll") {
|
||||||
Option = ValueLoc ? LoopHintAttr::UnrollCount : LoopHintAttr::Unroll;
|
Option = ValueLoc ? LoopHintAttr::UnrollCount : LoopHintAttr::Unroll;
|
||||||
Spelling = LoopHintAttr::Pragma_unroll;
|
Spelling = LoopHintAttr::Pragma_unroll;
|
||||||
|
} else if (PragmaNameLoc->Ident->getName() == "nounroll") {
|
||||||
|
Option = LoopHintAttr::Unroll;
|
||||||
|
Spelling = LoopHintAttr::Pragma_nounroll;
|
||||||
} else {
|
} else {
|
||||||
Option = llvm::StringSwitch<LoopHintAttr::OptionType>(OptionInfo->getName())
|
Option = llvm::StringSwitch<LoopHintAttr::OptionType>(OptionInfo->getName())
|
||||||
.Case("vectorize", LoopHintAttr::Vectorize)
|
.Case("vectorize", LoopHintAttr::Vectorize)
|
||||||
|
@ -86,6 +91,9 @@ static Attr *handleLoopHintAttr(Sema &S, Stmt *St, const AttributeList &A,
|
||||||
if (Option == LoopHintAttr::Unroll &&
|
if (Option == LoopHintAttr::Unroll &&
|
||||||
Spelling == LoopHintAttr::Pragma_unroll) {
|
Spelling == LoopHintAttr::Pragma_unroll) {
|
||||||
ValueInt = 1;
|
ValueInt = 1;
|
||||||
|
} else if (Option == LoopHintAttr::Unroll &&
|
||||||
|
Spelling == LoopHintAttr::Pragma_nounroll) {
|
||||||
|
ValueInt = 0;
|
||||||
} else if (Option == LoopHintAttr::Vectorize ||
|
} else if (Option == LoopHintAttr::Vectorize ||
|
||||||
Option == LoopHintAttr::Interleave ||
|
Option == LoopHintAttr::Interleave ||
|
||||||
Option == LoopHintAttr::Unroll) {
|
Option == LoopHintAttr::Unroll) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ void while_test(int *List, int Length) {
|
||||||
void do_test(int *List, int Length) {
|
void do_test(int *List, int Length) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
#pragma unroll 16
|
#pragma nounroll
|
||||||
do {
|
do {
|
||||||
// CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
|
// CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
|
||||||
List[i] = i * 2;
|
List[i] = i * 2;
|
||||||
|
@ -88,8 +88,8 @@ void template_test(double *List, int Length) {
|
||||||
|
|
||||||
// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[UNROLL_FULL:.*]]}
|
// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[UNROLL_FULL:.*]]}
|
||||||
// CHECK: ![[UNROLL_FULL]] = metadata !{metadata !"llvm.loop.unroll.full"}
|
// CHECK: ![[UNROLL_FULL]] = metadata !{metadata !"llvm.loop.unroll.full"}
|
||||||
// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata ![[UNROLL_16:.*]]}
|
// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata ![[UNROLL_DISABLE:.*]]}
|
||||||
// CHECK: ![[UNROLL_16]] = metadata !{metadata !"llvm.loop.unroll.count", i32 16}
|
// CHECK: ![[UNROLL_DISABLE]] = metadata !{metadata !"llvm.loop.unroll.disable"}
|
||||||
// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_8:.*]]}
|
// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_8:.*]]}
|
||||||
// CHECK: ![[UNROLL_8]] = metadata !{metadata !"llvm.loop.unroll.count", i32 8}
|
// CHECK: ![[UNROLL_8]] = metadata !{metadata !"llvm.loop.unroll.count", i32 8}
|
||||||
// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[UNROLL_4:.*]]}
|
// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[UNROLL_4:.*]]}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
// CHECK: #pragma clang loop vectorize(disable)
|
// CHECK: #pragma clang loop vectorize(disable)
|
||||||
// CHECK: #pragma unroll
|
// CHECK: #pragma unroll
|
||||||
// CHECK: #pragma unroll (32)
|
// CHECK: #pragma unroll (32)
|
||||||
|
// CHECK: #pragma nounroll
|
||||||
|
|
||||||
#ifndef HEADER
|
#ifndef HEADER
|
||||||
#define HEADER
|
#define HEADER
|
||||||
|
@ -71,8 +72,16 @@ public:
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
inline void run6(int *List, int Length) {
|
||||||
|
int i = 0;
|
||||||
|
#pragma nounroll
|
||||||
|
while (i - 3 < Length) {
|
||||||
|
List[i] = i;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
#else
|
#else
|
||||||
|
|
||||||
void test() {
|
void test() {
|
||||||
|
@ -85,6 +94,7 @@ void test() {
|
||||||
pt.run3(List, 100);
|
pt.run3(List, 100);
|
||||||
pt.run4(List, 100);
|
pt.run4(List, 100);
|
||||||
pt.run5(List, 100);
|
pt.run5(List, 100);
|
||||||
|
pt.run6(List, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -11,6 +11,11 @@ void test(int *List, int Length) {
|
||||||
List[i] = i;
|
List[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma nounroll
|
||||||
|
while (i < Length) {
|
||||||
|
List[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma unroll 4
|
#pragma unroll 4
|
||||||
while (i - 1 < Length) {
|
while (i - 1 < Length) {
|
||||||
List[i] = i;
|
List[i] = i;
|
||||||
|
@ -28,6 +33,11 @@ void test(int *List, int Length) {
|
||||||
List[i] = i;
|
List[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* expected-warning {{extra tokens at end of '#pragma nounroll'}} */ #pragma nounroll 1
|
||||||
|
while (i-7 < Length) {
|
||||||
|
List[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll(()
|
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll(()
|
||||||
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll -
|
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll -
|
||||||
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll(0)
|
/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll(0)
|
||||||
|
@ -42,6 +52,8 @@ void test(int *List, int Length) {
|
||||||
/* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int j = Length;
|
/* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int j = Length;
|
||||||
#pragma unroll 4
|
#pragma unroll 4
|
||||||
/* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int k = Length;
|
/* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int k = Length;
|
||||||
|
#pragma nounroll
|
||||||
|
/* expected-error {{expected a for, while, or do-while loop to follow '#pragma nounroll'}} */ int l = Length;
|
||||||
|
|
||||||
/* expected-error {{incompatible directives 'unroll(disable)' and '#pragma unroll(4)'}} */ #pragma unroll 4
|
/* expected-error {{incompatible directives 'unroll(disable)' and '#pragma unroll(4)'}} */ #pragma unroll 4
|
||||||
#pragma clang loop unroll(disable)
|
#pragma clang loop unroll(disable)
|
||||||
|
@ -61,6 +73,18 @@ void test(int *List, int Length) {
|
||||||
List[i] = i;
|
List[i] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* expected-error {{incompatible directives '#pragma nounroll' and 'unroll_count(4)'}} */ #pragma clang loop unroll_count(4)
|
||||||
|
#pragma nounroll
|
||||||
|
while (i-12 < Length) {
|
||||||
|
List[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* expected-error {{duplicate directives '#pragma nounroll' and '#pragma nounroll'}} */ #pragma nounroll
|
||||||
|
#pragma nounroll
|
||||||
|
while (i-13 < Length) {
|
||||||
|
List[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
/* expected-error {{duplicate directives '#pragma unroll' and '#pragma unroll'}} */ #pragma unroll
|
/* expected-error {{duplicate directives '#pragma unroll' and '#pragma unroll'}} */ #pragma unroll
|
||||||
#pragma unroll
|
#pragma unroll
|
||||||
while (i-14 < Length) {
|
while (i-14 < Length) {
|
||||||
|
|
Loading…
Reference in New Issue