Skip to content

Commit 30a469b

Browse files
committed
[SYCL][FPGA] Refactor statments attributes to align with community the way we handle conflicting vs duplicate values
This patch diagnose non-identical duplicates as a 'conflicting' loop attributes and suppress duplicate errors in cases where the two match for FPGA SYCL attributes: 'SYCLIntelMaxInterleavingAttr', 'SYCLIntelSpeculatedIterationsAttr', and 'SYCLIntelMaxReinvocationDelayAttr' to align with clang community change (Ref: llvm/llvm-project#70762). Signed-off-by: Soumi Manna <[email protected]>
1 parent e749f01 commit 30a469b

File tree

2 files changed

+71
-16
lines changed

2 files changed

+71
-16
lines changed

clang/lib/Sema/SemaStmtAttr.cpp

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,50 @@ CheckForDuplicationSYCLLoopAttribute(Sema &S,
964964
}
965965
}
966966

967+
// Diagnose non-identical duplicates as a 'conflicting' loop attributes
968+
// and suppress duplicate errors in cases where the two match for
969+
// FPGA attributes: 'SYCLIntelMaxInterleavingAttr',
970+
// 'SYCLIntelSpeculatedIterationsAttr', and
971+
// 'SYCLIntelMaxReinvocationDelayAttr'.
972+
template <typename LoopAttrT>
973+
static void CheckForDuplicateAttrs(Sema &S, ArrayRef<const Attr *> Attrs) {
974+
auto FindFunc = [](const Attr *A) { return isa<const LoopAttrT>(A); };
975+
const auto *FirstItr = std::find_if(Attrs.begin(), Attrs.end(), FindFunc);
976+
977+
if (FirstItr == Attrs.end()) // no attributes found
978+
return;
979+
980+
const auto *LastFoundItr = FirstItr;
981+
std::optional<llvm::APSInt> FirstValue;
982+
983+
const auto *CAFA =
984+
dyn_cast<ConstantExpr>(cast<LoopAttrT>(*FirstItr)->getNExpr());
985+
// Return early if first expression is dependent (since we don't
986+
// know what the effective size will be), and skip the loop entirely.
987+
if (!CAFA)
988+
return;
989+
990+
while (Attrs.end() != (LastFoundItr = std::find_if(LastFoundItr + 1,
991+
Attrs.end(), FindFunc))) {
992+
const auto *CASA = dyn_cast<ConstantExpr>(
993+
cast<LoopAttrT>(*LastFoundItr)->getNExpr());
994+
// If the value is dependent, we can not test anything.
995+
if (!CASA)
996+
return;
997+
// Test the attribute values.
998+
llvm::APSInt SecondValue = CASA->getResultAsAPSInt();
999+
if (!FirstValue)
1000+
FirstValue = CAFA->getResultAsAPSInt();
1001+
1002+
if (FirstValue != SecondValue) {
1003+
S.Diag((*LastFoundItr)->getLocation(), diag::err_loop_attr_conflict)
1004+
<< *FirstItr;
1005+
S.Diag((*FirstItr)->getLocation(), diag::note_previous_attribute);
1006+
}
1007+
return;
1008+
}
1009+
}
1010+
9671011
static void CheckForIncompatibleSYCLLoopAttributes(
9681012
Sema &S, const SmallVectorImpl<const Attr *> &Attrs) {
9691013
CheckForDuplicationSYCLLoopAttribute<SYCLIntelInitiationIntervalAttr>(
@@ -973,15 +1017,13 @@ static void CheckForIncompatibleSYCLLoopAttributes(
9731017
CheckForDuplicationSYCLLoopAttribute<SYCLIntelLoopCoalesceAttr>(S, Attrs);
9741018
CheckForDuplicationSYCLLoopAttribute<SYCLIntelDisableLoopPipeliningAttr>(
9751019
S, Attrs);
976-
CheckForDuplicationSYCLLoopAttribute<SYCLIntelMaxInterleavingAttr>(S,
977-
Attrs);
978-
CheckForDuplicationSYCLLoopAttribute<SYCLIntelSpeculatedIterationsAttr>(
979-
S, Attrs);
1020+
CheckForDuplicateAttrs<SYCLIntelMaxInterleavingAttr>(S, Attrs);
1021+
CheckForDuplicateAttrs<SYCLIntelSpeculatedIterationsAttr>(S, Attrs);
9801022
CheckForDuplicateSYCLIntelLoopCountAttrs(S, Attrs);
9811023
CheckForDuplicationSYCLLoopAttribute<LoopUnrollHintAttr>(S, Attrs, false);
9821024
CheckRedundantSYCLIntelIVDepAttrs(S, Attrs);
9831025
CheckForDuplicationSYCLLoopAttribute<SYCLIntelNofusionAttr>(S, Attrs);
984-
CheckForDuplicationSYCLLoopAttribute<SYCLIntelMaxReinvocationDelayAttr>(
1026+
CheckForDuplicateAttrs<SYCLIntelMaxReinvocationDelayAttr>(
9851027
S, Attrs);
9861028
CheckForDuplicationSYCLLoopAttribute<SYCLIntelEnableLoopPipeliningAttr>(
9871029
S, Attrs);
@@ -1165,6 +1207,9 @@ void Sema::ProcessStmtAttributes(Stmt *S, const ParsedAttributes &InAttrs,
11651207

11661208
bool Sema::CheckRebuiltAttributedStmtAttributes(ArrayRef<const Attr *> Attrs) {
11671209
CheckRedundantSYCLIntelIVDepAttrs(*this, Attrs);
1210+
CheckForDuplicateAttrs<SYCLIntelSpeculatedIterationsAttr>(*this, Attrs);
1211+
CheckForDuplicateAttrs<SYCLIntelMaxInterleavingAttr>(*this, Attrs);
1212+
CheckForDuplicateAttrs<SYCLIntelMaxReinvocationDelayAttr>(*this, Attrs);
11681213
return false;
11691214
}
11701215

clang/test/SemaSYCL/intel-fpga-loops.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -285,13 +285,13 @@ void zoo() {
285285
[[intel::max_interleaving(1)]]
286286
[[intel::loop_coalesce]] for (int i = 0; i != 10; ++i)
287287
a[i] = 0;
288-
[[intel::max_interleaving(1)]]
289-
// expected-error@+2 {{duplicate Intel FPGA loop attribute 'max_interleaving'}}
288+
[[intel::max_interleaving(1)]] // expected-note {{previous attribute is here}}
289+
// expected-error@+2 {{conflicting loop attribute 'max_interleaving'}}
290290
[[intel::speculated_iterations(1)]]
291291
[[intel::max_interleaving(0)]] for (int i = 0; i != 10; ++i)
292292
a[i] = 0;
293-
[[intel::speculated_iterations(1)]]
294-
// expected-error@+2 {{duplicate Intel FPGA loop attribute 'speculated_iterations'}}
293+
[[intel::speculated_iterations(1)]] // expected-note {{previous attribute is here}}
294+
// expected-error@+2 {{conflicting loop attribute 'speculated_iterations'}}
295295
[[intel::loop_coalesce]]
296296
[[intel::speculated_iterations(2)]] for (int i = 0; i != 10; ++i)
297297
a[i] = 0;
@@ -359,7 +359,6 @@ void zoo() {
359359
a[i] = 0;
360360

361361
[[intel::max_reinvocation_delay(1)]]
362-
// expected-error@+1{{duplicate Intel FPGA loop attribute 'max_reinvocation_delay'}}
363362
[[intel::max_reinvocation_delay(1)]] for (int i = 0; i != 10; ++i)
364363
a[i] = 0;
365364

@@ -501,11 +500,14 @@ void max_interleaving_dependent() {
501500
[[intel::max_interleaving(C)]] for (int i = 0; i != 10; ++i)
502501
a[i] = 0;
503502

504-
// expected-error@+2 {{duplicate Intel FPGA loop attribute 'max_interleaving'}}
505-
[[intel::max_interleaving(C)]]
503+
// expected-error@+2 {{conflicting loop attribute 'max_interleaving'}}
504+
[[intel::max_interleaving(C)]] // expected-note {{previous attribute is here}}
506505
[[intel::max_interleaving(D)]] for (int i = 0; i != 10; ++i)
507506
a[i] = 0;
508507

508+
[[intel::max_interleaving(D)]]
509+
[[intel::max_interleaving(D)]] for (int i = 0; i != 10; ++i)
510+
a[i] = 0;
509511
}
510512

511513
template <int A, int B, int C, int D>
@@ -515,14 +517,18 @@ void speculated_iterations_dependent() {
515517
[[intel::speculated_iterations(C)]] for (int i = 0; i != 10; ++i)
516518
a[i] = 0;
517519

518-
// expected-error@+2 {{duplicate Intel FPGA loop attribute 'speculated_iterations'}}
519-
[[intel::speculated_iterations(A)]]
520+
// expected-error@+2 {{conflicting loop attribute 'speculated_iterations'}}
521+
[[intel::speculated_iterations(A)]] // expected-note {{previous attribute is here}}
520522
[[intel::speculated_iterations(B)]] for (int i = 0; i != 10; ++i)
521523
a[i] = 0;
522524

523525
// speculated_iterations attribute accepts value 0.
524526
[[intel::speculated_iterations(D)]] for (int i = 0; i != 10; ++i)
525527
a[i] = 0;
528+
529+
[[intel::speculated_iterations(B)]]
530+
[[intel::speculated_iterations(B)]] for (int i = 0; i != 10; ++i)
531+
a[i] = 0;
526532
}
527533

528534
template <int A, int B, int C>
@@ -593,10 +599,14 @@ void max_reinvocation_delay_dependent() {
593599
[[intel::max_reinvocation_delay(C)]] for (int i = 0; i != 10; ++i)
594600
a[i] = 0;
595601

596-
// expected-error@+2 {{duplicate Intel FPGA loop attribute 'max_reinvocation_delay'}}
597-
[[intel::max_reinvocation_delay(A)]]
602+
// expected-error@+2 {{conflicting loop attribute 'max_reinvocation_delay'}}
603+
[[intel::max_reinvocation_delay(A)]] // expected-note {{previous attribute is here}}
598604
[[intel::max_reinvocation_delay(B)]] for (int i = 0; i != 10; ++i)
599605
a[i] = 0;
606+
607+
[[intel::max_reinvocation_delay(A)]]
608+
[[intel::max_reinvocation_delay(A)]] for (int i = 0; i != 10; ++i)
609+
a[i] = 0;
600610
}
601611

602612
void check_max_concurrency_expression() {

0 commit comments

Comments
 (0)