Skip to content

Commit e29237e

Browse files
authored
[SYCL][FPGA] Refactor statments attributes to align with community the way we handle conflicting vs duplicate values (#12243)
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 1261e05 commit e29237e

File tree

2 files changed

+84
-17
lines changed

2 files changed

+84
-17
lines changed

clang/lib/Sema/SemaStmtAttr.cpp

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,50 @@ CheckForDuplicationSYCLLoopAttribute(Sema &S,
968968
}
969969
}
970970

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

11701211
bool Sema::CheckRebuiltAttributedStmtAttributes(ArrayRef<const Attr *> Attrs) {
11711212
CheckRedundantSYCLIntelIVDepAttrs(*this, Attrs);
1213+
CheckForDuplicateAttrs<SYCLIntelSpeculatedIterationsAttr>(*this, Attrs);
1214+
CheckForDuplicateAttrs<SYCLIntelMaxInterleavingAttr>(*this, Attrs);
1215+
CheckForDuplicateAttrs<SYCLIntelMaxReinvocationDelayAttr>(*this, Attrs);
11721216
return false;
11731217
}
11741218

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

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -285,17 +285,24 @@ 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+
[[intel::max_interleaving(1)]] // OK.
290+
// expected-error@+2 {{conflicting loop attribute 'max_interleaving'}}
290291
[[intel::speculated_iterations(1)]]
291292
[[intel::max_interleaving(0)]] for (int i = 0; i != 10; ++i)
292293
a[i] = 0;
293-
[[intel::speculated_iterations(1)]]
294-
// expected-error@+2 {{duplicate Intel FPGA loop attribute 'speculated_iterations'}}
294+
[[intel::speculated_iterations(1)]] // expected-note {{previous attribute is here}}
295+
// expected-error@+2 {{conflicting loop attribute 'speculated_iterations'}}
295296
[[intel::loop_coalesce]]
296297
[[intel::speculated_iterations(2)]] for (int i = 0; i != 10; ++i)
297298
a[i] = 0;
298299

300+
[[intel::speculated_iterations(1)]] // expected-note {{previous attribute is here}}
301+
[[intel::speculated_iterations(1)]] // OK
302+
// expected-error@+1 {{conflicting loop attribute 'speculated_iterations'}}
303+
[[intel::speculated_iterations(2)]] for (int i = 0; i != 10; ++i)
304+
a[i] = 0;
305+
299306
[[intel::ivdep]]
300307
// expected-warning@+2 {{ignoring redundant Intel FPGA loop attribute 'ivdep': safelen INF >= safelen INF}}
301308
// expected-note@-2 {{previous attribute is here}}
@@ -359,10 +366,15 @@ void zoo() {
359366
a[i] = 0;
360367

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

372+
[[intel::max_reinvocation_delay(10)]] // expected-note {{previous attribute is here}}
373+
[[intel::max_reinvocation_delay(10)]] // OK
374+
// expected-error@+1 {{conflicting loop attribute 'max_reinvocation_delay'}}
375+
[[intel::max_reinvocation_delay(20)]] for (int i = 0; i != 10; ++i)
376+
a[i] = 0;
377+
366378
[[intel::enable_loop_pipelining]]
367379
// expected-error@+1 {{duplicate Intel FPGA loop attribute 'enable_loop_pipelining'}}
368380
[[intel::enable_loop_pipelining]] for (int i = 0; i != 10; ++i)
@@ -501,11 +513,14 @@ void max_interleaving_dependent() {
501513
[[intel::max_interleaving(C)]] for (int i = 0; i != 10; ++i)
502514
a[i] = 0;
503515

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

521+
[[intel::max_interleaving(D)]]
522+
[[intel::max_interleaving(D)]] for (int i = 0; i != 10; ++i)
523+
a[i] = 0;
509524
}
510525

511526
template <int A, int B, int C, int D>
@@ -515,14 +530,18 @@ void speculated_iterations_dependent() {
515530
[[intel::speculated_iterations(C)]] for (int i = 0; i != 10; ++i)
516531
a[i] = 0;
517532

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

523538
// speculated_iterations attribute accepts value 0.
524539
[[intel::speculated_iterations(D)]] for (int i = 0; i != 10; ++i)
525540
a[i] = 0;
541+
542+
[[intel::speculated_iterations(B)]]
543+
[[intel::speculated_iterations(B)]] for (int i = 0; i != 10; ++i)
544+
a[i] = 0;
526545
}
527546

528547
template <int A, int B, int C>
@@ -593,10 +612,14 @@ void max_reinvocation_delay_dependent() {
593612
[[intel::max_reinvocation_delay(C)]] for (int i = 0; i != 10; ++i)
594613
a[i] = 0;
595614

596-
// expected-error@+2 {{duplicate Intel FPGA loop attribute 'max_reinvocation_delay'}}
597-
[[intel::max_reinvocation_delay(A)]]
615+
// expected-error@+2 {{conflicting loop attribute 'max_reinvocation_delay'}}
616+
[[intel::max_reinvocation_delay(A)]] // expected-note {{previous attribute is here}}
598617
[[intel::max_reinvocation_delay(B)]] for (int i = 0; i != 10; ++i)
599618
a[i] = 0;
619+
620+
[[intel::max_reinvocation_delay(A)]]
621+
[[intel::max_reinvocation_delay(A)]] for (int i = 0; i != 10; ++i)
622+
a[i] = 0;
600623
}
601624

602625
void check_max_concurrency_expression() {

0 commit comments

Comments
 (0)