"expected a reference to an integer-typed parameter">;
def err_omp_at_least_one_motion_clause_required : Error<
"expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'">;
+def warn_omp_nesting_simd : Warning<
+ "OpenMP only allows an ordered construct with the simd clause nested in a simd construct">,
+ InGroup<SourceUsesOpenMP>;
} // end of OpenMP category
let CategoryName = "Related Result Type Issue" in {
ShouldBeInTargetRegion,
ShouldBeInTeamsRegion
} Recommend = NoRecommend;
- if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered &&
- CurrentRegion != OMPD_simd) {
+ if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
// OpenMP [2.16, Nesting of Regions]
// OpenMP constructs may not be nested inside a simd region.
// OpenMP [2.8.1,simd Construct, Restrictions]
- // An ordered construct with the simd clause is the only OpenMP construct
- // that can appear in the simd region.
- SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);
- return true;
+ // An ordered construct with the simd clause is the only OpenMP
+ // construct that can appear in the simd region.
+ // Allowing a SIMD consruct nested in another SIMD construct is an
+ // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
+ // message.
+ SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
+ ? diag::err_omp_prohibited_region_simd
+ : diag::warn_omp_nesting_simd);
+ return CurrentRegion != OMPD_simd;
}
if (ParentRegion == OMPD_atomic) {
// OpenMP [2.16, Nesting of Regions]
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
+#pragma omp ordered simd // OK
+ bar();
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
}
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
}
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
+#pragma omp ordered simd // OK
+ bar();
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
+#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
+ bar();
+ }
+#pragma omp for simd
+ for (int i = 0; i < 10; ++i) {
#pragma omp atomic // expected-error {{OpenMP constructs may not be nested inside a simd region}}
++a;
}
}
#pragma omp parallel for simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
}
#pragma omp simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
}
#pragma omp for simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}
}
#pragma omp parallel for simd
for (int i = 0; i < 10; ++i) {
-#pragma omp simd
+#pragma omp simd // expected-warning {{OpenMP only allows an ordered construct with the simd clause nested in a simd construct}}
for (int i = 0; i < 10; ++i)
;
}