Skip to content
Merged
Show file tree
Hide file tree
Changes from 32 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
488dfb9
[SYCL] Implementation of loop attribute control_avg.
zahiraam Mar 29, 2021
b0f255e
Merge remote-tracking branch 'remote/sycl' into control-avg-attr
zahiraam Mar 29, 2021
0324f5f
Fixing Attr name
zahiraam Mar 29, 2021
a3a8613
Complete implementation
zahiraam Apr 9, 2021
5abbbe6
Merge remote-tracking branch 'remote/sycl' into control-avg-attr
zahiraam Apr 9, 2021
48d6df0
Adding test cases
zahiraam Apr 9, 2021
61fba57
Merge remote-tracking branch 'remote/sycl' into control-avg-attr
zahiraam Apr 9, 2021
99cb85f
Merge remote-tracking branch 'remote/sycl' into control-avg-attr
zahiraam Apr 12, 2021
44b8681
Indent
zahiraam Apr 12, 2021
7622568
Indent
zahiraam Apr 12, 2021
c3d8c59
Indent
zahiraam Apr 12, 2021
4dba2ea
CodeGen impl
zahiraam Apr 12, 2021
50a06c7
After review comments
zahiraam Apr 12, 2021
1bb84bc
Changing name
zahiraam Apr 12, 2021
40a3279
Format
zahiraam Apr 12, 2021
1f84add
Merge remote-tracking branch 'remote/sycl' into control-avg-attr
zahiraam Apr 13, 2021
6ab3b07
After review
zahiraam Apr 13, 2021
a5ad650
Merge remote-tracking branch 'remote/sycl' into control-avg-attr
zahiraam Apr 14, 2021
fd34d55
Formatting
zahiraam Apr 14, 2021
d812fa4
Formatting
zahiraam Apr 14, 2021
fd74842
Looks like the HasCustomTypeTransform is needed
zahiraam Apr 14, 2021
93cbc1d
Merge remote-tracking branch 'remote/sycl' into control-avg-attr
zahiraam Apr 15, 2021
73f92a4
Added min/max
zahiraam Apr 16, 2021
80f372a
Added min/max
zahiraam Apr 19, 2021
639794e
Merge remote-tracking branch 'remote/sycl' into control-avg-attr
zahiraam Apr 19, 2021
d2884f0
Indentation
zahiraam Apr 19, 2021
5ab429b
Added all 3 variants
zahiraam Apr 21, 2021
c73cd83
Merge remote-tracking branch 'remote/sycl' into control-avg-attr
zahiraam Apr 21, 2021
86ae532
Added all 3 variants
zahiraam Apr 21, 2021
3044f88
Indentation
zahiraam Apr 21, 2021
453b654
Indentation
zahiraam Apr 21, 2021
9d46fc0
Indentation
zahiraam Apr 21, 2021
a44e1ce
Merge remote-tracking branch 'remote/sycl' into control-avg-attr
zahiraam Apr 27, 2021
1a20635
Fixes after review
zahiraam Apr 27, 2021
c10bfaf
Identation
zahiraam Apr 27, 2021
cefac8a
Fixes after review
zahiraam Apr 27, 2021
6ddf9ce
Fixes after review
zahiraam Apr 27, 2021
d0ddcdd
Fixes after review
zahiraam Apr 27, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1975,6 +1975,29 @@ def : MutualExclusions<[SYCLIntelFPGAIVDep,
def : MutualExclusions<[SYCLIntelFPGAMaxConcurrency,
SYCLIntelFPGADisableLoopPipelining]>;

def SYCLIntelFPGALoopCount : StmtAttr {
let Spellings = [CXX11<"intel", "loop_count_min">,
CXX11<"intel", "loop_count_max">,
CXX11<"intel", "loop_count_avg">];
let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt],
ErrorDiag, "'for', 'while', and 'do' statements">;
let Accessors = [Accessor<"isMin", [CXX11<"intel", "loop_count_min">]>,
Accessor<"isMax", [CXX11<"intel", "loop_count_max">]>,
Accessor<"isAvg", [CXX11<"intel", "loop_count_avg">]>];
let Args = [ExprArgument<"NTripCount">];
let LangOpts = [SYCLIsDevice, SilentlyIgnoreSYCLIsHost];
let HasCustomTypeTransform = 1;
Comment thread
AaronBallman marked this conversation as resolved.
Outdated
let AdditionalMembers = [{
enum CountKind { loop_count_min, loop_count_max, loop_count_avg };
CountKind getCountKind() const {
return isMin() ? loop_count_min :
isMax() ? loop_count_max :
loop_count_avg;
}
}];
Comment thread
AaronBallman marked this conversation as resolved.
Outdated
let Documentation = [SYCLIntelFPGALoopCountAttrDocs];
}

def : MutualExclusions<[SYCLIntelFPGAMaxConcurrency,
SYCLIntelFPGADisableLoopPipelining]>;

Expand Down
37 changes: 37 additions & 0 deletions clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -2951,6 +2951,43 @@ or ``ivdep``.
}];
}

def SYCLIntelFPGALoopCountAttrDocs : Documentation {
let Category = DocCatVariable;
let Heading = "intel::loop_count_min, intel::loop_count_max, intel::loop_count_avg";
let Content = [{
The "loop_count" attribute specifies the minimum, maximum, or average number of

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The "loop_count" attribute specifies the minimum, maximum, or average number of
The loop count attributes specify the minimum, maximum, or average number of

iterations for a for loop. In addition, a list of commonly occurring values
Comment thread
AaronBallman marked this conversation as resolved.
Outdated
can be specified to help the compiler generate multiple versions and perform
Comment thread
AaronBallman marked this conversation as resolved.
Outdated
complete unrolling.

.. code-block:: c++
Comment thread
AaronBallman marked this conversation as resolved.

void foo() {
int a[10];
[[intel::loop_count_min(40)] for (int i = 0; i < 10; ++i) a[i] = 0;
}

void zoo() {
int a[10];
[[intel::loop_count_max(40)] for (int i = 0; i < 10; ++i) a[i] = 0;
}

void goo() {
int a[10];
[[intel::loop_count_min(10)]
[[intel::loop_count_max(40)]
[[intel::loop_count_avg(15)]
for (int i = 0; i < 10; ++i) a[i] = 0;
}

template<int N>
void bar() {
[[intel::loop_count_avg(N)]] for(;;) { }
}

}];
}

def SYCLIntelFPGAMaxInterleavingAttrDocs : Documentation {
let Category = DocCatVariable;
let Heading = "intel::max_interleaving";
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2121,6 +2121,9 @@ class Sema final {
OpenCLUnrollHintAttr *
BuildOpenCLLoopUnrollHintAttr(const AttributeCommonInfo &A, Expr *E);

SYCLIntelFPGALoopCountAttr *
BuildSYCLIntelFPGALoopCount(const AttributeCommonInfo &CI, Expr *E);

bool CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc);

bool CheckFunctionReturnType(QualType T, SourceLocation Loc);
Expand Down Expand Up @@ -13439,7 +13442,8 @@ FPGALoopAttrT *Sema::BuildSYCLIntelFPGALoopAttr(const AttributeCommonInfo &A,
A.getParsedKind() ==
ParsedAttr::AT_SYCLIntelFPGAMaxInterleaving ||
A.getParsedKind() ==
ParsedAttr::AT_SYCLIntelFPGASpeculatedIterations) {
ParsedAttr::AT_SYCLIntelFPGASpeculatedIterations ||
A.getParsedKind() == ParsedAttr::AT_SYCLIntelFPGALoopCount) {
if (Val < 0) {
Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
<< A.getAttrName() << /* non-negative */ 1;
Expand Down
52 changes: 42 additions & 10 deletions clang/lib/CodeGen/CGLoopInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,10 @@ MDNode *LoopInfo::createMetadata(

// Setting max_concurrency attribute with number of threads
if (Attrs.SYCLMaxConcurrencyEnable) {
Metadata *Vals[] = {MDString::get(Ctx, "llvm.loop.max_concurrency.count"),
ConstantAsMetadata::get(ConstantInt::get(
llvm::Type::getInt32Ty(Ctx),
Attrs.SYCLMaxConcurrencyNThreads))};
Metadata *Vals[] = {
MDString::get(Ctx, "llvm.loop.max_concurrency.count"),
ConstantAsMetadata::get(ConstantInt::get(
llvm::Type::getInt32Ty(Ctx), Attrs.SYCLMaxConcurrencyNThreads))};
Comment thread
smanna12 marked this conversation as resolved.
Outdated
LoopProperties.push_back(MDNode::get(Ctx, Vals));
}

Expand Down Expand Up @@ -605,6 +605,16 @@ MDNode *LoopInfo::createMetadata(
LoopProperties.push_back(MDNode::get(Ctx, Vals));
}

if (Attrs.SYCLIntelFPGALoopCountEnable) {
for (int i = 0; i < Attrs.SYCLIntelFPGALoopCountVariant.size(); i++) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd be nice to replace this with a range-based for loop once you unify the lists.

Metadata *Vals[] = {
MDString::get(Ctx, Attrs.SYCLIntelFPGALoopCountVariant[i]),
ConstantAsMetadata::get(
ConstantInt::get(llvm::Type::getInt32Ty(Ctx),
Attrs.SYCLIntelFPGALoopCountValue[i]))};
LoopProperties.push_back(MDNode::get(Ctx, Vals));
}
}
LoopProperties.insert(LoopProperties.end(), AdditionalLoopProperties.begin(),
AdditionalLoopProperties.end());
return createFullUnrollMetadata(Attrs, LoopProperties, HasUserTransforms);
Expand All @@ -621,10 +631,12 @@ LoopAttributes::LoopAttributes(bool IsParallel)
SYCLLoopCoalesceNLevels(0), SYCLLoopPipeliningDisable(false),
SYCLMaxInterleavingEnable(false), SYCLMaxInterleavingNInvocations(0),
SYCLSpeculatedIterationsEnable(false),
SYCLSpeculatedIterationsNIterations(0), UnrollCount(0),
UnrollAndJamCount(0), DistributeEnable(LoopAttributes::Unspecified),
PipelineDisabled(false), PipelineInitiationInterval(0),
SYCLNofusionEnable(false), MustProgress(false) {}
SYCLSpeculatedIterationsNIterations(0),
SYCLIntelFPGALoopCountEnable(false), SYCLIntelFPGALoopCountValue(0),
SYCLIntelFPGALoopCountVariant(0), UnrollCount(0), UnrollAndJamCount(0),
DistributeEnable(LoopAttributes::Unspecified), PipelineDisabled(false),
PipelineInitiationInterval(0), SYCLNofusionEnable(false),
MustProgress(false) {}

void LoopAttributes::clear() {
IsParallel = false;
Expand All @@ -643,6 +655,9 @@ void LoopAttributes::clear() {
SYCLMaxInterleavingNInvocations = 0;
SYCLSpeculatedIterationsEnable = false;
SYCLSpeculatedIterationsNIterations = 0;
SYCLIntelFPGALoopCountEnable = false;
SYCLIntelFPGALoopCountVariant.clear();
SYCLIntelFPGALoopCountValue.clear();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not keen on keeping parallel lists for this sort of thing -- why not a single list of pairs, or some other data structure that keeps the variants and their values tied together?

UnrollCount = 0;
UnrollAndJamCount = 0;
VectorizeEnable = LoopAttributes::Unspecified;
Expand Down Expand Up @@ -680,8 +695,11 @@ LoopInfo::LoopInfo(BasicBlock *Header, const LoopAttributes &Attrs,
Attrs.SYCLMaxInterleavingNInvocations == 0 &&
Attrs.SYCLSpeculatedIterationsEnable == false &&
Attrs.SYCLSpeculatedIterationsNIterations == 0 &&
Attrs.UnrollCount == 0 && Attrs.UnrollAndJamCount == 0 &&
!Attrs.PipelineDisabled && Attrs.PipelineInitiationInterval == 0 &&
Attrs.SYCLIntelFPGALoopCountEnable == 0 &&
Attrs.SYCLIntelFPGALoopCountVariant.empty() &&
Attrs.SYCLIntelFPGALoopCountValue.empty() && Attrs.UnrollCount == 0 &&
Attrs.UnrollAndJamCount == 0 && !Attrs.PipelineDisabled &&
Attrs.PipelineInitiationInterval == 0 &&
Attrs.VectorizePredicateEnable == LoopAttributes::Unspecified &&
Attrs.VectorizeEnable == LoopAttributes::Unspecified &&
Attrs.UnrollEnable == LoopAttributes::Unspecified &&
Expand Down Expand Up @@ -1030,6 +1048,20 @@ void LoopInfoStack::push(BasicBlock *Header, clang::ASTContext &Ctx,
->getSExtValue());
}

if (const auto *IntelFPGALoopCountAvg =
dyn_cast<SYCLIntelFPGALoopCountAttr>(A)) {
setSYCLIntelFPGALoopCountEnable();
setSYCLIntelFPGALoopCountValue(IntelFPGALoopCountAvg->getNTripCount()
->getIntegerConstantExpr(Ctx)
->getSExtValue());
const char *var = IntelFPGALoopCountAvg->isMax()
? "llvm.loop.intel.loopcount_max"
: IntelFPGALoopCountAvg->isMin()
? "llvm.loop.intel.loopcount_min"
: "llvm.loop.intel.loopcount_avg";
setSYCLIntelFPGALoopCountVariant(var);
}

if (const auto *IntelFPGALoopCoalesce =
dyn_cast<SYCLIntelFPGALoopCoalesceAttr>(A)) {
if (auto *LCE = IntelFPGALoopCoalesce->getNExpr())
Expand Down
25 changes: 25 additions & 0 deletions clang/lib/CodeGen/CGLoopInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define LLVM_CLANG_LIB_CODEGEN_CGLOOPINFO_H

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
Comment thread
AaronBallman marked this conversation as resolved.
Outdated
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Value.h"
Expand Down Expand Up @@ -117,6 +118,15 @@ struct LoopAttributes {
/// Value for llvm.loop.max_concurrency.count metadata.
unsigned SYCLMaxConcurrencyNThreads;

/// Flag for llvm.loop.intel.loopcount metadata.
bool SYCLIntelFPGALoopCountEnable;
Comment thread
AaronBallman marked this conversation as resolved.
Outdated

/// Value for llvm.loop.intel.loopcount value metadata.
llvm::SmallVector<unsigned int, 2> SYCLIntelFPGALoopCountValue;

/// Value for llvm.loop.intel.loopcount variant(min/max/avg) metadata.
llvm::SmallVector<const char *, 2> SYCLIntelFPGALoopCountVariant;

/// Flag for llvm.loop.coalesce metadata.
bool SYCLLoopCoalesceEnable;

Expand Down Expand Up @@ -404,6 +414,21 @@ class LoopInfoStack {
StagedAttrs.SYCLSpeculatedIterationsNIterations = C;
}

/// Set flag of loopcount for the next loop pushed.
void setSYCLIntelFPGALoopCountEnable() {
StagedAttrs.SYCLIntelFPGALoopCountEnable = true;
}

/// Set value of loopcount value for the next loop pushed.
void setSYCLIntelFPGALoopCountValue(unsigned C) {
StagedAttrs.SYCLIntelFPGALoopCountValue.push_back(C);
}

/// Set value of loopcount variant for the next loop pushed.
void setSYCLIntelFPGALoopCountVariant(const char *var) {
StagedAttrs.SYCLIntelFPGALoopCountVariant.push_back(var);
}

/// Set the unroll count for the next loop pushed.
void setUnrollCount(unsigned C) { StagedAttrs.UnrollCount = C; }

Expand Down
65 changes: 65 additions & 0 deletions clang/lib/Sema/SemaStmtAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,68 @@ static Attr *handleIntelFPGAIVDepAttr(Sema &S, Stmt *St, const ParsedAttr &A) {
NumArgs == 2 ? A.getArgAsExpr(1) : nullptr);
}

static void
CheckForDuplicateSYCLIntelLoopCountAttrs(Sema &S,
ArrayRef<const Attr *> Attrs) {
// Create a list of SYCLIntelFPGALoopCount attributes only.
SmallVector<const SYCLIntelFPGALoopCountAttr *, 8> OnlyLoopCountAttrs;
llvm::transform(
Attrs, std::back_inserter(OnlyLoopCountAttrs), [](const Attr *A) {
return dyn_cast_or_null<const SYCLIntelFPGALoopCountAttr>(A);
});
OnlyLoopCountAttrs.erase(
std::remove(OnlyLoopCountAttrs.begin(), OnlyLoopCountAttrs.end(),
static_cast<const SYCLIntelFPGALoopCountAttr *>(nullptr)),
OnlyLoopCountAttrs.end());
if (OnlyLoopCountAttrs.empty())
return;

unsigned int MinCount = 0;
unsigned int MaxCount = 0;
unsigned int AvgCount = 0;
for (const auto *A : OnlyLoopCountAttrs) {
const SYCLIntelFPGALoopCountAttr *At =
Comment thread
AaronBallman marked this conversation as resolved.
Outdated
dyn_cast<SYCLIntelFPGALoopCountAttr>(A);
switch (At->getCountKind()) {
Comment thread
AaronBallman marked this conversation as resolved.
Outdated
case SYCLIntelFPGALoopCountAttr::CountKind::loop_count_min:
MinCount++;
break;
case SYCLIntelFPGALoopCountAttr::CountKind::loop_count_max:
MaxCount++;
break;
case SYCLIntelFPGALoopCountAttr::CountKind::loop_count_avg:
AvgCount++;
break;
}
if (MinCount > 1 || MaxCount > 1 || AvgCount > 1)
S.Diag(A->getLocation(), diag::err_sycl_loop_attr_duplication) << 1 << A;
}
}

static SYCLIntelFPGALoopCountAttr *
handleIntelFPGALoopCountAttr(Sema &S, Stmt *St, const ParsedAttr &A) {
Expr *E = A.getArgAsExpr(0);
if (E && !E->isInstantiationDependent()) {
Optional<llvm::APSInt> ArgVal =
E->getIntegerConstantExpr(S.getASTContext());

if (!ArgVal) {
S.Diag(E->getExprLoc(), diag::err_attribute_argument_type)
<< A.getAttrName() << AANT_ArgumentIntegerConstant
Comment thread
AaronBallman marked this conversation as resolved.
Outdated
<< E->getSourceRange();
return nullptr;
}

if (ArgVal->getSExtValue() < 0) {
S.Diag(E->getExprLoc(), diag::err_attribute_requires_positive_integer)
<< A.getAttrName() << /* non-negative */ 1;
Comment thread
AaronBallman marked this conversation as resolved.
Outdated
return nullptr;
}
}
return new (S.Context)
SYCLIntelFPGALoopCountAttr(S.Context, A, A.getArgAsExpr(0));
}

static Attr *handleIntelFPGANofusionAttr(Sema &S, Stmt *St,
const ParsedAttr &A) {
return new (S.Context) SYCLIntelFPGANofusionAttr(S.Context, A);
Expand Down Expand Up @@ -558,6 +620,7 @@ static void CheckForIncompatibleSYCLLoopAttributes(
Attrs);
CheckForDuplicationSYCLLoopAttribute<SYCLIntelFPGASpeculatedIterationsAttr>(
S, Attrs);
CheckForDuplicateSYCLIntelLoopCountAttrs(S, Attrs);
CheckForDuplicationSYCLLoopAttribute<LoopUnrollHintAttr>(S, Attrs, false);
CheckRedundantSYCLIntelFPGAIVDepAttrs(S, Attrs);
CheckForDuplicationSYCLLoopAttribute<SYCLIntelFPGANofusionAttr>(S, Attrs);
Expand Down Expand Up @@ -687,6 +750,8 @@ static Attr *ProcessStmtAttribute(Sema &S, Stmt *St, const ParsedAttr &A,
case ParsedAttr::AT_SYCLIntelFPGASpeculatedIterations:
return handleIntelFPGALoopAttr<SYCLIntelFPGASpeculatedIterationsAttr>(S, St,
A);
case ParsedAttr::AT_SYCLIntelFPGALoopCount:
return handleIntelFPGALoopCountAttr(S, St, A);
case ParsedAttr::AT_OpenCLUnrollHint:
case ParsedAttr::AT_LoopUnrollHint:
return handleLoopUnrollHint(S, St, A, Range);
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/Sema/SemaTemplateInstantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,8 @@ namespace {
const SYCLIntelFPGASpeculatedIterationsAttr *
TransformSYCLIntelFPGASpeculatedIterationsAttr(
const SYCLIntelFPGASpeculatedIterationsAttr *SI);
const SYCLIntelFPGALoopCountAttr *
TransformSYCLIntelFPGALoopCountAttr(const SYCLIntelFPGALoopCountAttr *SI);

ExprResult TransformPredefinedExpr(PredefinedExpr *E);
ExprResult TransformDeclRefExpr(DeclRefExpr *E);
Expand Down Expand Up @@ -1618,6 +1620,15 @@ TemplateInstantiator::TransformSYCLIntelFPGASpeculatedIterationsAttr(
*SI, TransformedExpr);
}

const SYCLIntelFPGALoopCountAttr *
TemplateInstantiator::TransformSYCLIntelFPGALoopCountAttr(
const SYCLIntelFPGALoopCountAttr *LCA) {
Expr *TransformedExpr =
getDerived().TransformExpr(LCA->getNTripCount()).get();
return getSema().BuildSYCLIntelFPGALoopAttr<SYCLIntelFPGALoopCountAttr>(
*LCA, TransformedExpr);
}

const LoopUnrollHintAttr *TemplateInstantiator::TransformLoopUnrollHintAttr(
const LoopUnrollHintAttr *LU) {
Expr *TransformedExpr =
Expand Down
23 changes: 23 additions & 0 deletions clang/test/CodeGenSYCL/intel-fpga-loops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
// CHECK: br label %for.cond2, !llvm.loop ![[MD_MI_2:[0-9]+]]
// CHECK: br label %for.cond, !llvm.loop ![[MD_SI:[0-9]+]]
// CHECK: br label %for.cond2, !llvm.loop ![[MD_SI_2:[0-9]+]]
// CHECK: br label %for.cond, !llvm.loop ![[MD_LCA:[0-9]+]]
// CHECK: br label %for.cond2, !llvm.loop ![[MD_LCA_1:[0-9]+]]
// CHECK: br label %for.cond13, !llvm.loop ![[MD_LCA_2:[0-9]+]]

void disable_loop_pipelining() {
int a[10];
Expand Down Expand Up @@ -109,6 +112,25 @@ void speculated_iterations() {
a[i] = 0;
}

template <int A>
void loop_count_control() {
int a[10];
// CHECK: ![[MD_LCA]] = distinct !{![[MD_LCA]], ![[MP:[0-9]+]], ![[MD_loop_count_avg:[0-9]+]]}
// CHECK-NEXT: ![[MD_loop_count_avg]] = !{!"llvm.loop.intel.loopcount_avg", i32 12}
[[intel::loop_count_avg(A)]] for (int i = 0; i != 10; ++i)
a[i] = 0;
// CHECK: ![[MD_LCA_1]] = distinct !{![[MD_LCA_1]], ![[MP:[0-9]+]], ![[MD_loop_count_max:[0-9]+]]}
// CHECK-NEXT: ![[MD_loop_count_max]] = !{!"llvm.loop.intel.loopcount_max", i32 4}
[[intel::loop_count_max(4)]] for (int i = 0; i != 10; ++i)
a[i] = 0;
// CHECK: ![[MD_LCA_2]] = distinct !{![[MD_LCA_2]], ![[MP:[0-9]+]], ![[MD_loop_count_min:[0-9]+]], ![[MD_loop_count_max_1:[0-9]+]], ![[MD_loop_count_avg_1:[0-9]+]]}
// CHECK: ![[MD_loop_count_min]] = !{!"llvm.loop.intel.loopcount_min", i32 4}
// CHECK: ![[MD_loop_count_max_1]] = !{!"llvm.loop.intel.loopcount_max", i32 40}
// CHECK-NEXT: ![[MD_loop_count_avg_1]] = !{!"llvm.loop.intel.loopcount_avg", i32 21}
[[intel::loop_count_min(4)]] [[intel::loop_count_max(40)]] [[intel::loop_count_avg(21)]] for (int i = 0; i != 10; ++i)
a[i] = 0;
}

template <typename name, typename Func>
__attribute__((sycl_kernel)) void kernel_single_task(const Func &kernelFunc) {
kernelFunc();
Expand All @@ -123,6 +145,7 @@ int main() {
loop_coalesce<2>();
max_interleaving<3>();
speculated_iterations<4>();
loop_count_control<12>();
});
return 0;
}
Loading