[OPENMP50]Add if clause in target teams distribute parallel for simd directive.
authorAlexey Bataev <a.bataev@hotmail.com>
Mon, 16 Dec 2019 15:27:39 +0000 (10:27 -0500)
committerAlexey Bataev <a.bataev@hotmail.com>
Mon, 16 Dec 2019 15:33:56 +0000 (10:33 -0500)
According to OpenMP 5.0, if clause can be used in for simd directive. If
condition in the if clause if false, the non-vectorized version of the
loop must be executed.

clang/lib/Sema/SemaOpenMP.cpp
clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_codegen.cpp
clang/test/OpenMP/target_teams_distribute_parallel_for_simd_if_messages.cpp

index e02c1c5..9033997 100644 (file)
@@ -4778,6 +4778,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
     AllowedNameModifiers.push_back(OMPD_target);
     AllowedNameModifiers.push_back(OMPD_parallel);
+    if (LangOpts.OpenMP >= 50)
+      AllowedNameModifiers.push_back(OMPD_simd);
     break;
   case OMPD_target_teams_distribute_simd:
     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
@@ -10762,8 +10764,14 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
         CaptureRegion = OMPD_target;
       break;
-    case OMPD_target_teams_distribute_parallel_for:
     case OMPD_target_teams_distribute_parallel_for_simd:
+      if (OpenMPVersion >= 50 &&
+          (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
+        CaptureRegion = OMPD_parallel;
+        break;
+      }
+      LLVM_FALLTHROUGH;
+    case OMPD_target_teams_distribute_parallel_for:
       // If this clause applies to the nested 'parallel' region, capture within
       // the 'teams' region, otherwise do not capture.
       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
index 79ae4fe..8a8d64e 100644 (file)
@@ -1,10 +1,16 @@
-// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix OMP45
 // RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix OMP45
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s --check-prefix CHECK --check-prefix OMP50
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CHECK --check-prefix OMP50
 
 // RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s --check-prefix SIMD-ONLY
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
 // RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix SIMD-ONLY
+// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s --check-prefix SIMD-ONLY
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -DOMP5 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix SIMD-ONLY
 // SIMD-ONLY-NOT: {{__kmpc|__tgt}}
 
 // expected-no-diagnostics
@@ -28,7 +34,11 @@ void gtid_test() {
 // CHECK: call void @__kmpc_push_target_tripcount(i64 -1, i64 100)
 // CHECK: call i{{[0-9]+}} @__tgt_target_teams(
 // CHECK: call void [[OFFLOADING_FUN_1:@.+]](
+#ifdef OMP5
+#pragma omp target teams distribute parallel for simd if(simd: true)
+#else
 #pragma omp target teams distribute parallel for simd
+#endif // OMP5
   for(int i = 0 ; i < 100; i++) {}
   // CHECK: define internal void [[OFFLOADING_FUN_0]](
   // CHECK: call {{.*}}void {{.+}} @__kmpc_fork_teams({{.+}}, i32 0, {{.+}}* [[OMP_TEAMS_OUTLINED_0:@.+]] to {{.+}})
@@ -132,7 +142,8 @@ int main() {
     // CHECK: define{{.+}} void [[OMP_TEAMS_OUTLINED_2]](
 
     // CHECK: call void @__kmpc_for_static_init_4(
-    // CHECK: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_4:@.+]] to void
+    // OMP45: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 2, {{.+}}* [[OMP_OUTLINED_4:@.+]] to void
+    // OMP50: call void {{.+}} @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{.+}} 3, {{.+}}* [[OMP_OUTLINED_4:@.+]] to void
     // CHECK: call void @__kmpc_serialized_parallel(
     // CHECK: call void [[OMP_OUTLINED_4:@.+]](
     // CHECK: call void @__kmpc_end_serialized_parallel(
@@ -184,3 +195,8 @@ int main() {
 // CHECK: call void @__kmpc_for_static_fini(
 // CHECK: ret void
 #endif
+
+// OMP45-NOT: !{!"llvm.loop.vectorize.enable", i1 false}
+// CHECK-DAG: !{!"llvm.loop.vectorize.enable", i1 true}
+// OMP45-NOT: !{!"llvm.loop.vectorize.enable", i1 false}
+// OMP50-DAG: !{!"llvm.loop.vectorize.enable", i1 false}
index 259d92c..4701f5c 100644 (file)
@@ -1,6 +1,8 @@
-// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp -fopenmp-version=45 -ferror-limit 100 %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp -fopenmp-version=50 -ferror-limit 100 %s -Wuninitialized
 
-// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-simd -fopenmp-version=45 -ferror-limit 100 %s -Wuninitialized
+// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-simd -fopenmp-version=50 -ferror-limit 100 %s -Wuninitialized
 
 void foo() {
 }
@@ -60,15 +62,15 @@ int tmain(T argc, S **argv) {
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target teams distribute parallel for simd if(target: argc)
   for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target teams distribute parallel for simd'}}
+#pragma omp target teams distribute parallel for simd if(parallel : argc) if (simd:argc) // omp45-error {{directive name modifier 'simd' is not allowed for '#pragma omp target teams distribute parallel for simd'}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target teams distribute parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target teams distribute parallel for simd if(target: argc) if (target:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'if' clause with 'target' name modifier}}
   for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd if(parallel : argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected 'target' directive name modifier}}
+#pragma omp target teams distribute parallel for simd if(parallel : argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} omp45-error {{expected 'target' directive name modifier}} omp50-error {{expected one of 'target' or 'simd' directive name modifiers}}
   for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd if(target: argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected 'parallel' directive name modifier}}
+#pragma omp target teams distribute parallel for simd if(target: argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} omp45-error {{expected 'parallel' directive name modifier}} omp50-error {{expected one of 'parallel' or 'simd' directive name modifiers}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target teams distribute parallel for simd if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute parallel for simd'}}
   for (i = 0; i < argc; ++i) foo();
@@ -122,15 +124,15 @@ int main(int argc, char **argv) {
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target teams distribute parallel for simd if(target: argc)
   for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd if(parallel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp target teams distribute parallel for simd'}}
+#pragma omp target teams distribute parallel for simd if(parallel : argc) if (simd:argc) // omp45-error {{directive name modifier 'simd' is not allowed for '#pragma omp target teams distribute parallel for simd'}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target teams distribute parallel for simd if(parallel : argc) if (parallel:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'if' clause with 'parallel' name modifier}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target teams distribute parallel for simd if(target: argc) if (target:argc) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'if' clause with 'target' name modifier}}
   for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd if(parallel : argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected 'target' directive name modifier}}
+#pragma omp target teams distribute parallel for simd if(parallel : argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} omp45-error {{expected 'target' directive name modifier}} omp50-error {{expected one of 'target' or 'simd' directive name modifiers}}
   for (i = 0; i < argc; ++i) foo();
-#pragma omp target teams distribute parallel for simd if(target: argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{expected 'parallel' directive name modifier}}
+#pragma omp target teams distribute parallel for simd if(target: argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} omp45-error {{expected 'parallel' directive name modifier}} omp50-error {{expected one of 'parallel' or 'simd' directive name modifiers}}
   for (i = 0; i < argc; ++i) foo();
 #pragma omp target teams distribute parallel for simd if(distribute : argc) // expected-error {{directive name modifier 'distribute' is not allowed for '#pragma omp target teams distribute parallel for simd'}}
   for (i = 0; i < argc; ++i) foo();