@@ -964,6 +964,50 @@ CheckForDuplicationSYCLLoopAttribute(Sema &S,
964
964
}
965
965
}
966
966
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
+
967
1011
static void CheckForIncompatibleSYCLLoopAttributes (
968
1012
Sema &S, const SmallVectorImpl<const Attr *> &Attrs) {
969
1013
CheckForDuplicationSYCLLoopAttribute<SYCLIntelInitiationIntervalAttr>(
@@ -973,15 +1017,13 @@ static void CheckForIncompatibleSYCLLoopAttributes(
973
1017
CheckForDuplicationSYCLLoopAttribute<SYCLIntelLoopCoalesceAttr>(S, Attrs);
974
1018
CheckForDuplicationSYCLLoopAttribute<SYCLIntelDisableLoopPipeliningAttr>(
975
1019
S, Attrs);
976
- CheckForDuplicationSYCLLoopAttribute<SYCLIntelMaxInterleavingAttr>(S,
977
- Attrs);
978
- CheckForDuplicationSYCLLoopAttribute<SYCLIntelSpeculatedIterationsAttr>(
979
- S, Attrs);
1020
+ CheckForDuplicateAttrs<SYCLIntelMaxInterleavingAttr>(S, Attrs);
1021
+ CheckForDuplicateAttrs<SYCLIntelSpeculatedIterationsAttr>(S, Attrs);
980
1022
CheckForDuplicateSYCLIntelLoopCountAttrs (S, Attrs);
981
1023
CheckForDuplicationSYCLLoopAttribute<LoopUnrollHintAttr>(S, Attrs, false );
982
1024
CheckRedundantSYCLIntelIVDepAttrs (S, Attrs);
983
1025
CheckForDuplicationSYCLLoopAttribute<SYCLIntelNofusionAttr>(S, Attrs);
984
- CheckForDuplicationSYCLLoopAttribute <SYCLIntelMaxReinvocationDelayAttr>(
1026
+ CheckForDuplicateAttrs <SYCLIntelMaxReinvocationDelayAttr>(
985
1027
S, Attrs);
986
1028
CheckForDuplicationSYCLLoopAttribute<SYCLIntelEnableLoopPipeliningAttr>(
987
1029
S, Attrs);
@@ -1165,6 +1207,9 @@ void Sema::ProcessStmtAttributes(Stmt *S, const ParsedAttributes &InAttrs,
1165
1207
1166
1208
bool Sema::CheckRebuiltAttributedStmtAttributes (ArrayRef<const Attr *> Attrs) {
1167
1209
CheckRedundantSYCLIntelIVDepAttrs (*this , Attrs);
1210
+ CheckForDuplicateAttrs<SYCLIntelSpeculatedIterationsAttr>(*this , Attrs);
1211
+ CheckForDuplicateAttrs<SYCLIntelMaxInterleavingAttr>(*this , Attrs);
1212
+ CheckForDuplicateAttrs<SYCLIntelMaxReinvocationDelayAttr>(*this , Attrs);
1168
1213
return false ;
1169
1214
}
1170
1215
0 commit comments