/// unroll_count: unrolls loop 'Value' times.
/// unroll_and_jam: attempt to unroll and jam loop if State == Enable.
/// unroll_and_jam_count: unroll and jams loop 'Value' times.
- /// distribute: attempt to distribute loop if State == Enable
+ /// distribute: attempt to distribute loop if State == Enable.
+ /// pipeline: disable pipelining loop if State == Disable.
+ /// pipeline_initiation_interval: create loop schedule with initiation interval equal to 'Value'.
/// #pragma unroll <argument> directive
/// <no arg>: fully unrolls loop.
let Args = [EnumArgument<"Option", "OptionType",
["vectorize", "vectorize_width", "interleave", "interleave_count",
"unroll", "unroll_count", "unroll_and_jam", "unroll_and_jam_count",
- "distribute"],
+ "pipeline", "pipeline_initiation_interval", "distribute"],
["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount",
"Unroll", "UnrollCount", "UnrollAndJam", "UnrollAndJamCount",
- "Distribute"]>,
+ "PipelineDisabled", "PipelineInitiationInterval", "Distribute"]>,
EnumArgument<"State", "LoopHintState",
["enable", "disable", "numeric", "assume_safety", "full"],
["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>,
case UnrollCount: return "unroll_count";
case UnrollAndJam: return "unroll_and_jam";
case UnrollAndJamCount: return "unroll_and_jam_count";
+ case PipelineDisabled: return "pipeline";
+ case PipelineInitiationInterval: return "pipeline_initiation_interval";
case Distribute: return "distribute";
}
llvm_unreachable("Unhandled LoopHint option.");
let Heading = "#pragma clang loop";
let Content = [{
The ``#pragma clang loop`` directive allows loop optimization hints to be
-specified for the subsequent loop. The directive allows vectorization,
-interleaving, and unrolling to be enabled or disabled. Vector width as well
-as interleave and unrolling count can be manually specified. See
-`language extensions
+specified for the subsequent loop. The directive allows pipelining to be
+disabled, or vectorization, interleaving, and unrolling to be enabled or disabled.
+Vector width, interleave count, unrolling count, and the initiation interval
+for pipelining can be explicitly specified. See `language extensions
<http://clang.llvm.org/docs/LanguageExtensions.html#extensions-for-loop-hint-optimizations>`_
for details.
}];
}];
}
+def PipelineHintDocs : Documentation {
+ let Category = DocCatStmt;
+ let Heading = "#pragma clang loop pipeline, #pragma clang loop pipeline_initiation_interval";
+ let Content = [{
+ Software Pipelining optimization is a technique used to optimize loops by
+ utilizing instruction-level parallelism. It reorders loop instructions to
+ overlap iterations. As a result, the next iteration starts before the previous
+ iteration has finished. The module scheduling technique creates a schedule for
+ one iteration such that when repeating at regular intervals, no inter-iteration
+ dependencies are violated. This constant interval(in cycles) between the start
+ of iterations is called the initiation interval. i.e. The initiation interval
+ is the number of cycles between two iterations of an unoptimized loop in the
+ newly created schedule. A new, optimized loop is created such that a single iteration
+ of the loop executes in the same number of cycles as the initiation interval.
+ For further details see <https://llvm.org/pubs/2005-06-17-LattnerMSThesis-book.pdf>.
+
+ ``#pragma clang loop pipeline and #pragma loop pipeline_initiation_interval``
+ could be used as hints for the software pipelining optimization. The pragma is
+ placed immediately before a for, while, do-while, or a C++11 range-based for
+ loop.
+
+ Using ``#pragma clang loop pipeline(disable)`` avoids the software pipelining
+ optimization. The disable state can only be specified:
+
+ .. code-block:: c++
+
+ #pragma clang loop pipeline(disable)
+ for (...) {
+ ...
+ }
+
+ Using ``#pragma loop pipeline_initiation_interval`` instructs
+ the software pipeliner to try the specified initiation interval.
+ If a schedule was found then the resulting loop iteration would have
+ the specified cycle count. If a schedule was not found then loop
+ remains unchanged. The initiation interval must be a positive number
+ greater than zero:
+
+ .. code-block:: c++
+
+ #pragma loop pipeline_initiation_interval(10)
+ for (...) {
+ ...
+ }
+
+ }];
+}
+
+
+
def OpenCLUnrollHintDocs : Documentation {
let Category = DocCatStmt;
let Content = [{
"'enable'%select{|, 'full'}1%select{|, 'assume_safety'}2 or 'disable'}0">;
def err_pragma_loop_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
- "vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute">;
+ "vectorize_width, interleave, interleave_count, unroll, unroll_count, "
+ "pipeline, pipeline_initiation_interval, or distribute">;
def err_pragma_fp_invalid_option : Error<
"%select{invalid|missing}0 option%select{ %1|}0; expected contract">;
def err_pragma_invalid_keyword : Error<
"invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">;
+def err_pragma_pipeline_invalid_keyword : Error<
+ "invalid argument; expected 'disable'">;
// Pragma unroll support.
def warn_pragma_unroll_cuda_value_in_parens : Warning<
if (!Attrs.IsParallel && Attrs.VectorizeWidth == 0 &&
Attrs.InterleaveCount == 0 && Attrs.UnrollCount == 0 &&
- Attrs.UnrollAndJamCount == 0 &&
+ Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled &&
+ Attrs.PipelineInitiationInterval == 0 &&
Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
Attrs.UnrollEnable == LoopAttributes::Unspecified &&
Attrs.UnrollAndJamEnable == LoopAttributes::Unspecified &&
Ctx, {MDString::get(Ctx, "llvm.loop.parallel_accesses"), AccGroup}));
}
+ if (Attrs.PipelineDisabled) {
+ Metadata *Vals[] = {
+ MDString::get(Ctx, "llvm.loop.pipeline.disable"),
+ ConstantAsMetadata::get(ConstantInt::get(
+ Type::getInt1Ty(Ctx), (Attrs.PipelineDisabled == true)))};
+ Args.push_back(MDNode::get(Ctx, Vals));
+ }
+
+ if (Attrs.PipelineInitiationInterval > 0) {
+ Metadata *Vals[] = {
+ MDString::get(Ctx, "llvm.loop.pipeline.initiationinterval"),
+ ConstantAsMetadata::get(ConstantInt::get(
+ Type::getInt32Ty(Ctx), Attrs.PipelineInitiationInterval))};
+ Args.push_back(MDNode::get(Ctx, Vals));
+ }
+
// Set the first operand to itself.
MDNode *LoopID = MDNode::get(Ctx, Args);
LoopID->replaceOperandWith(0, LoopID);
UnrollEnable(LoopAttributes::Unspecified),
UnrollAndJamEnable(LoopAttributes::Unspecified), VectorizeWidth(0),
InterleaveCount(0), UnrollCount(0), UnrollAndJamCount(0),
- DistributeEnable(LoopAttributes::Unspecified) {}
+ DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false),
+ PipelineInitiationInterval(0) {}
void LoopAttributes::clear() {
IsParallel = false;
UnrollEnable = LoopAttributes::Unspecified;
UnrollAndJamEnable = LoopAttributes::Unspecified;
DistributeEnable = LoopAttributes::Unspecified;
+ PipelineDisabled = false;
+ PipelineInitiationInterval = 0;
}
LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
case LoopHintAttr::Distribute:
setDistributeState(false);
break;
+ case LoopHintAttr::PipelineDisabled:
+ setPipelineDisabled(true);
+ break;
case LoopHintAttr::UnrollCount:
case LoopHintAttr::UnrollAndJamCount:
case LoopHintAttr::VectorizeWidth:
case LoopHintAttr::InterleaveCount:
+ case LoopHintAttr::PipelineInitiationInterval:
llvm_unreachable("Options cannot be disabled.");
break;
}
case LoopHintAttr::UnrollAndJamCount:
case LoopHintAttr::VectorizeWidth:
case LoopHintAttr::InterleaveCount:
+ case LoopHintAttr::PipelineDisabled:
+ case LoopHintAttr::PipelineInitiationInterval:
llvm_unreachable("Options cannot enabled.");
break;
}
case LoopHintAttr::VectorizeWidth:
case LoopHintAttr::InterleaveCount:
case LoopHintAttr::Distribute:
+ case LoopHintAttr::PipelineDisabled:
+ case LoopHintAttr::PipelineInitiationInterval:
llvm_unreachable("Options cannot be used to assume mem safety.");
break;
}
case LoopHintAttr::VectorizeWidth:
case LoopHintAttr::InterleaveCount:
case LoopHintAttr::Distribute:
+ case LoopHintAttr::PipelineDisabled:
+ case LoopHintAttr::PipelineInitiationInterval:
llvm_unreachable("Options cannot be used with 'full' hint.");
break;
}
case LoopHintAttr::UnrollAndJamCount:
setUnrollAndJamCount(ValueInt);
break;
+ case LoopHintAttr::PipelineInitiationInterval:
+ setPipelineInitiationInterval(ValueInt);
+ break;
case LoopHintAttr::Unroll:
case LoopHintAttr::UnrollAndJam:
case LoopHintAttr::Vectorize:
case LoopHintAttr::Interleave:
case LoopHintAttr::Distribute:
+ case LoopHintAttr::PipelineDisabled:
llvm_unreachable("Options cannot be assigned a value.");
break;
}
/// Value for llvm.loop.distribute.enable metadata.
LVEnableState DistributeEnable;
+
+ /// Value for llvm.loop.pipeline.disable metadata.
+ bool PipelineDisabled;
+
+ /// Value for llvm.loop.pipeline.iicount metadata.
+ unsigned PipelineInitiationInterval;
};
/// Information used when generating a structured loop.
/// \brief Set the unroll count for the next loop pushed.
void setUnrollAndJamCount(unsigned C) { StagedAttrs.UnrollAndJamCount = C; }
+ /// Set the pipeline disabled state.
+ void setPipelineDisabled(bool S) { StagedAttrs.PipelineDisabled = S; }
+
+ /// Set the pipeline initiation interval.
+ void setPipelineInitiationInterval(unsigned C) {
+ StagedAttrs.PipelineInitiationInterval = C;
+ }
+
private:
/// Returns true if there is LoopInfo on the stack.
bool hasInfo() const { return !Active.empty(); }
bool OptionUnroll = false;
bool OptionUnrollAndJam = false;
bool OptionDistribute = false;
+ bool OptionPipelineDisabled = false;
bool StateOption = false;
if (OptionInfo) { // Pragma Unroll does not specify an option.
OptionUnroll = OptionInfo->isStr("unroll");
OptionUnrollAndJam = OptionInfo->isStr("unroll_and_jam");
OptionDistribute = OptionInfo->isStr("distribute");
+ OptionPipelineDisabled = OptionInfo->isStr("pipeline");
StateOption = llvm::StringSwitch<bool>(OptionInfo->getName())
.Case("vectorize", true)
.Case("interleave", true)
.Default(false) ||
- OptionUnroll || OptionUnrollAndJam || OptionDistribute;
+ OptionUnroll || OptionUnrollAndJam || OptionDistribute ||
+ OptionPipelineDisabled;
}
- bool AssumeSafetyArg =
- !OptionUnroll && !OptionUnrollAndJam && !OptionDistribute;
+ bool AssumeSafetyArg = !OptionUnroll && !OptionUnrollAndJam &&
+ !OptionDistribute && !OptionPipelineDisabled;
// Verify loop hint has an argument.
if (Toks[0].is(tok::eof)) {
ConsumeAnnotationToken();
SourceLocation StateLoc = Toks[0].getLocation();
IdentifierInfo *StateInfo = Toks[0].getIdentifierInfo();
- bool Valid =
- StateInfo && llvm::StringSwitch<bool>(StateInfo->getName())
- .Cases("enable", "disable", true)
- .Case("full", OptionUnroll || OptionUnrollAndJam)
- .Case("assume_safety", AssumeSafetyArg)
- .Default(false);
+ bool Valid = StateInfo &&
+ llvm::StringSwitch<bool>(StateInfo->getName())
+ .Case("disable", true)
+ .Case("enable", !OptionPipelineDisabled)
+ .Case("full", OptionUnroll || OptionUnrollAndJam)
+ .Case("assume_safety", AssumeSafetyArg)
+ .Default(false);
if (!Valid) {
- Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
- << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
- << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
+ if (OptionPipelineDisabled) {
+ Diag(Toks[0].getLocation(), diag::err_pragma_pipeline_invalid_keyword);
+ } else {
+ Diag(Toks[0].getLocation(), diag::err_pragma_invalid_keyword)
+ << /*FullKeyword=*/(OptionUnroll || OptionUnrollAndJam)
+ << /*AssumeSafetyKeyword=*/AssumeSafetyArg;
+ }
return false;
}
if (Toks.size() > 2)
/// 'vectorize_width' '(' loop-hint-value ')'
/// 'interleave_count' '(' loop-hint-value ')'
/// 'unroll_count' '(' loop-hint-value ')'
+/// 'pipeline' '(' disable ')'
+/// 'pipeline_initiation_interval' '(' loop-hint-value ')'
///
/// loop-hint-keyword:
/// 'enable'
.Case("vectorize_width", true)
.Case("interleave_count", true)
.Case("unroll_count", true)
+ .Case("pipeline", true)
+ .Case("pipeline_initiation_interval", true)
.Default(false);
if (!OptionValid) {
PP.Diag(Tok.getLocation(), diag::err_pragma_loop_invalid_option)
.Case("interleave_count", LoopHintAttr::InterleaveCount)
.Case("unroll", LoopHintAttr::Unroll)
.Case("unroll_count", LoopHintAttr::UnrollCount)
+ .Case("pipeline", LoopHintAttr::PipelineDisabled)
+ .Case("pipeline_initiation_interval",
+ LoopHintAttr::PipelineInitiationInterval)
.Case("distribute", LoopHintAttr::Distribute)
.Default(LoopHintAttr::Vectorize);
if (Option == LoopHintAttr::VectorizeWidth ||
Option == LoopHintAttr::InterleaveCount ||
- Option == LoopHintAttr::UnrollCount) {
+ Option == LoopHintAttr::UnrollCount ||
+ Option == LoopHintAttr::PipelineInitiationInterval) {
assert(ValueExpr && "Attribute must have a valid value expression.");
if (S.CheckLoopHintExpr(ValueExpr, St->getBeginLoc()))
return nullptr;
} else if (Option == LoopHintAttr::Vectorize ||
Option == LoopHintAttr::Interleave ||
Option == LoopHintAttr::Unroll ||
- Option == LoopHintAttr::Distribute) {
+ Option == LoopHintAttr::Distribute ||
+ Option == LoopHintAttr::PipelineDisabled) {
assert(StateLoc && StateLoc->Ident && "Loop hint must have an argument");
if (StateLoc->Ident->isStr("disable"))
State = LoopHintAttr::Disable;
static void
CheckForIncompatibleAttributes(Sema &S,
const SmallVectorImpl<const Attr *> &Attrs) {
- // There are 5 categories of loop hints attributes: vectorize, interleave,
- // unroll, unroll_and_jam and distribute. Except for distribute they come
- // in two variants: a state form and a numeric form. The state form
+ // There are 6 categories of loop hints attributes: vectorize, interleave,
+ // unroll, unroll_and_jam, pipeline and distribute. Except for distribute they
+ // come in two variants: a state form and a numeric form. The state form
// selectively defaults/enables/disables the transformation for the loop
// (for unroll, default indicates full unrolling rather than enabling the
// transformation). The numeric form form provides an integer hint (for
struct {
const LoopHintAttr *StateAttr;
const LoopHintAttr *NumericAttr;
- } HintAttrs[] = {{nullptr, nullptr},
- {nullptr, nullptr},
- {nullptr, nullptr},
- {nullptr, nullptr},
- {nullptr, nullptr}};
+ } HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr},
+ {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr}};
for (const auto *I : Attrs) {
const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
continue;
LoopHintAttr::OptionType Option = LH->getOption();
- enum { Vectorize, Interleave, Unroll, UnrollAndJam, Distribute } Category;
+ enum {
+ Vectorize,
+ Interleave,
+ Unroll,
+ UnrollAndJam,
+ Distribute,
+ Pipeline
+ } Category;
switch (Option) {
case LoopHintAttr::Vectorize:
case LoopHintAttr::VectorizeWidth:
// Perform the check for duplicated 'distribute' hints.
Category = Distribute;
break;
+ case LoopHintAttr::PipelineDisabled:
+ case LoopHintAttr::PipelineInitiationInterval:
+ Category = Pipeline;
+ break;
};
assert(Category < sizeof(HintAttrs) / sizeof(HintAttrs[0]));
if (Option == LoopHintAttr::Vectorize ||
Option == LoopHintAttr::Interleave || Option == LoopHintAttr::Unroll ||
Option == LoopHintAttr::UnrollAndJam ||
+ Option == LoopHintAttr::PipelineDisabled ||
Option == LoopHintAttr::Distribute) {
// Enable|Disable|AssumeSafety hint. For example, vectorize(enable).
PrevAttr = CategoryState.StateAttr;
--- /dev/null
+// RUN: %clang_cc1 -triple hexagon -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+void pipeline_disabled(int *List, int Length, int Value) {
+// CHECK-LABEL: define {{.*}} @_Z17pipeline_disabled
+#pragma clang loop pipeline(disable)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ List[i] = Value;
+ }
+}
+
+void pipeline_not_disabled(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z21pipeline_not_disabled
+ for (int i = 0; i < Length; i++) {
+ List[i] = Value;
+ }
+}
+
+void pipeline_initiation_interval(int *List, int Length, int Value) {
+// CHECK-LABEL: define {{.*}} @_Z28pipeline_initiation_interval
+#pragma clang loop pipeline_initiation_interval(10)
+ for (int i = 0; i < Length; i++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ List[i] = Value;
+ }
+}
+
+void pipeline_disabled_on_nested_loop(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z32pipeline_disabled_on_nested_loop
+ for (int i = 0; i < Length; i++) {
+#pragma clang loop pipeline(disable)
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[PIPELINE_DISABLE:.*]]}
+// CHECK: ![[PIPELINE_DISABLE]] = !{!"llvm.loop.pipeline.disable", i1 true}
+
+// CHECK-NOT:llvm.loop.pipeline
+
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[PIPELINE_II_10:.*]]}
+// CHECK: ![[PIPELINE_II_10]] = !{!"llvm.loop.pipeline.initiationinterval", i32 10}
+
+// CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[PIPELINE_DISABLE]]}
/* expected-error {{missing argument; expected 'enable', 'full' or 'disable'}} */ #pragma clang loop unroll()
/* expected-error {{missing argument; expected 'enable' or 'disable'}} */ #pragma clang loop distribute()
-/* expected-error {{missing option; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute}} */ #pragma clang loop
+/* expected-error {{missing option; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, or distribute}} */ #pragma clang loop
/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword
/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword(enable)
/* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop vectorize(enable) badkeyword(4)
--- /dev/null
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// Note that this puts the expected lines before the directives to work around
+// limitations in the -verify mode.
+
+void test(int *List, int Length, int Value) {
+ int i = 0;
+
+#pragma clang loop pipeline(disable)
+ for (int i = 0; i < Length; i++) {
+ List[i] = Value;
+ }
+
+#pragma clang loop pipeline_initiation_interval(10)
+ for (int i = 0; i < Length; i++) {
+ List[i] = Value;
+ }
+
+/* expected-error {{expected ')'}} */ #pragma clang loop pipeline(disable
+/* expected-error {{invalid argument; expected 'disable'}} */ #pragma clang loop pipeline(enable)
+/* expected-error {{invalid argument; expected 'disable'}} */ #pragma clang loop pipeline(error)
+/* expected-error {{expected '('}} */ #pragma clang loop pipeline disable
+/* expected-error {{missing argument; expected an integer value}} */ #pragma clang loop pipeline_initiation_interval()
+/* expected-error {{use of undeclared identifier 'error'}} */ #pragma clang loop pipeline_initiation_interval(error)
+/* expected-error {{expected '('}} */ #pragma clang loop pipeline_initiation_interval 1 2
+/* expected-error {{expected ')'}} */ #pragma clang loop pipeline_initiation_interval(1
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ List[i * Length + j] = Value;
+ }
+ }
+
+}
}
// pragma clang unroll_and_jam is disabled for the moment
-/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute}} */ #pragma clang loop unroll_and_jam(4)
+/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, pipeline, pipeline_initiation_interval, or distribute}} */ #pragma clang loop unroll_and_jam(4)
for (int i = 0; i < Length; i++) {
for (int j = 0; j < Length; j++) {
List[i * Length + j] = Value;
--- /dev/null
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+#pragma clang loop pipeline(disable) /* expected-error {{expected unqualified-id}} */
+int main() {
+ for (int i = 0; i < 10; ++i)
+ ;
+}
+
+void test(int *List, int Length, int Value) {
+ int i = 0;
+
+/* expected-error {{invalid argument of type 'double'; expected an integer type}} */ #pragma clang loop pipeline_initiation_interval(1.0)
+/* expected-error {{invalid value '0'; must be positive}} */ #pragma clang loop pipeline_initiation_interval(0)
+/* expected-error {{invalid value '-1'; must be positive}} */ #pragma clang loop pipeline_initiation_interval(-1)
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ List[i * Length + j] = Value;
+ }
+ }
+
+#pragma clang loop pipeline(disable)
+/* expected-error {{expected a for, while, or do-while loop to follow '#pragma clang loop'}} */ int j = Length;
+#pragma clang loop pipeline_initiation_interval(4)
+/* expected-error {{expected a for, while, or do-while loop to follow '#pragma clang loop'}} */ int k = Length;
+
+#pragma clang loop pipeline(disable)
+#pragma clang loop pipeline_initiation_interval(4) /* expected-error {{incompatible directives 'pipeline(disable)' and 'pipeline_initiation_interval(4)'}} */
+ for (int i = 0; i < Length; i++) {
+ List[i] = Value;
+ }
+
+#pragma clang loop pipeline(disable)
+/* expected-error {{expected statement}} */ }
+