Commit 779a180d authored by Alexey Bataev's avatar Alexey Bataev
Browse files

[OPENMP50]Add if clause in distribute simd directive.

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.
parent 7b61ae68
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -872,6 +872,7 @@ OPENMP_DISTRIBUTE_SIMD_CLAUSE(safelen)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(simdlen)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(reduction)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(allocate)
OPENMP_DISTRIBUTE_SIMD_CLAUSE(if)

// Clauses allowed for OpenMP directive 'target parallel for simd'.
OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(if)
+2 −0
Original line number Diff line number Diff line
@@ -790,6 +790,8 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
    }
    break;
  case OMPD_distribute_simd:
    if (OpenMPVersion < 50 && CKind == OMPC_if)
      return false;
    switch (CKind) {
#define OPENMP_DISTRIBUTE_SIMD_CLAUSE(Name)                                    \
  case OMPC_##Name:                                                            \
+22 −14
Original line number Diff line number Diff line
@@ -3605,8 +3605,6 @@ void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
      if (RT.isStaticNonchunked(ScheduleKind,
                                /* Chunked */ Chunk != nullptr) ||
          StaticChunked) {
        if (isOpenMPSimdDirective(S.getDirectiveKind()))
          EmitOMPSimdInit(S, /*IsMonotonic=*/true);
        CGOpenMPRuntime::StaticRTInput StaticInit(
            IVSize, IVSigned, /* Ordered = */ false, IL.getAddress(*this),
            LB.getAddress(*this), UB.getAddress(*this), ST.getAddress(*this),
@@ -3656,7 +3654,16 @@ void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
        //   IV = LB;
        // }
        //
        EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), Cond, IncExpr,
        emitCommonSimdLoop(
            *this, S,
            [&S](CodeGenFunction &CGF, PrePostActionTy &) {
              if (isOpenMPSimdDirective(S.getDirectiveKind()))
                CGF.EmitOMPSimdInit(S, /*IsMonotonic=*/true);
            },
            [&S, &LoopScope, Cond, IncExpr, LoopExit, &CodeGenLoop,
             StaticChunked](CodeGenFunction &CGF, PrePostActionTy &) {
              CGF.EmitOMPInnerLoop(
                  S, LoopScope.requiresCleanups(), Cond, IncExpr,
                  [&S, LoopExit, &CodeGenLoop](CodeGenFunction &CGF) {
                    CodeGenLoop(CGF, S, LoopExit);
                  },
@@ -3668,6 +3675,7 @@ void CodeGenFunction::EmitOMPDistributeLoop(const OMPLoopDirective &S,
                      CGF.EmitIgnoredExpr(S.getCombinedInit());
                    }
                  });
            });
        EmitBlock(LoopExit.getBlock());
        // Tell the runtime we are done.
        RT.emitForStaticFinish(*this, S.getBeginLoc(), S.getDirectiveKind());
+3 −1
Original line number Diff line number Diff line
@@ -4709,6 +4709,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
  case OMPD_distribute_simd:
    Res = ActOnOpenMPDistributeSimdDirective(
        ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
    if (LangOpts.OpenMP >= 50)
      AllowedNameModifiers.push_back(OMPD_simd);
    break;
  case OMPD_target_parallel_for_simd:
    Res = ActOnOpenMPTargetParallelForSimdDirective(
@@ -10763,6 +10765,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
    case OMPD_target_data:
    case OMPD_simd:
    case OMPD_for_simd:
    case OMPD_distribute_simd:
      // Do not capture if-clause expressions.
      break;
    case OMPD_threadprivate:
@@ -10789,7 +10792,6 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
    case OMPD_distribute:
    case OMPD_ordered:
    case OMPD_atomic:
    case OMPD_distribute_simd:
    case OMPD_teams_distribute:
    case OMPD_teams_distribute_simd:
    case OMPD_requires:
+22 −6
Original line number Diff line number Diff line
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s -Wno-openmp-mapping | FileCheck %s
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s -Wno-openmp-mapping | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping | FileCheck %s
// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s -Wno-openmp-mapping -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP5
// RUN: %clang_cc1 -fopenmp -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50

// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s -Wno-openmp-mapping | FileCheck %s
// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s -Wno-openmp-mapping | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -emit-pch -o %t %s
// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping | FileCheck %s
// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s -Wno-openmp-mapping -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -x c++ -std=c++11 -emit-pch -o %t %s -DOMP5
// RUN: %clang_cc1 -fopenmp-simd -fopenmp-version=50 -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print -Wno-openmp-mapping -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
// expected-no-diagnostics

#ifndef HEADER
@@ -124,11 +130,16 @@ int main(int argc, char **argv) {

#pragma omp target
#pragma omp teams
#ifdef OMP5
#pragma omp distribute simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) reduction(+ : h) dist_schedule(static, b) if(simd:argc)
#else
#pragma omp distribute simd private(argc, b), firstprivate(argv, c), lastprivate(d, f) collapse(2) reduction(+ : h) dist_schedule(static, b)
#endif // OMP5
  for (int i = 0; i < 10; ++i)
    for (int j = 0; j < 10; ++j)
            a++;
// CHECK: #pragma omp distribute simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) reduction(+: h) dist_schedule(static, b)
// OMP45: #pragma omp distribute simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) reduction(+: h) dist_schedule(static, b)
// OMP50: #pragma omp distribute simd private(argc,b) firstprivate(argv,c) lastprivate(d,f) collapse(2) reduction(+: h) dist_schedule(static, b) if(simd: argc)
// CHECK-NEXT: for (int i = 0; i < 10; ++i)
// CHECK-NEXT: for (int j = 0; j < 10; ++j)
// CHECK-NEXT: a++;
@@ -136,11 +147,16 @@ int main(int argc, char **argv) {
  int i;
#pragma omp target
#pragma omp teams
#ifdef OMP5
#pragma omp distribute simd aligned(x:8) linear(i:2) safelen(8) simdlen(8) if(argc)
#else
#pragma omp distribute simd aligned(x:8) linear(i:2) safelen(8) simdlen(8)
#endif // OMP5
  for (i = 0; i < 100; i++)
    for (int j = 0; j < 200; j++)
      a += h + x[j];
// CHECK: #pragma omp distribute simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8)
// OMP45: #pragma omp distribute simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8)
// OMP50: #pragma omp distribute simd aligned(x: 8) linear(i: 2) safelen(8) simdlen(8) if(argc)
// CHECK-NEXT: for (i = 0; i < 100; i++)
// CHECK-NEXT: for (int j = 0; j < 200; j++)
// CHECK-NEXT: a += h + x[j];
Loading