forked from OSchip/llvm-project
[OPENMP50]Add if clause in simd directive.
According to OpenMP 5.0, if clause can be used in simd directive. If condition in the if clause if false, the non-vectorized version of the loop must be executed.
This commit is contained in:
parent
0d4211f4e7
commit
d08c056695
|
@ -6781,7 +6781,9 @@ AST_MATCHER(OMPDefaultClause, isSharedKind) {
|
|||
/// ``isAllowedToContainClauseKind("OMPC_default").``
|
||||
AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind,
|
||||
OpenMPClauseKind, CKind) {
|
||||
return isAllowedClauseForDirective(Node.getDirectiveKind(), CKind);
|
||||
return isAllowedClauseForDirective(
|
||||
Node.getDirectiveKind(), CKind,
|
||||
Finder->getASTContext().getLangOpts().OpenMP);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
|
|
@ -366,6 +366,7 @@ OPENMP_SIMD_CLAUSE(simdlen)
|
|||
OPENMP_SIMD_CLAUSE(collapse)
|
||||
OPENMP_SIMD_CLAUSE(reduction)
|
||||
OPENMP_SIMD_CLAUSE(allocate)
|
||||
OPENMP_SIMD_CLAUSE(if)
|
||||
|
||||
// Clauses allowed for directive 'omp for'.
|
||||
OPENMP_FOR_CLAUSE(private)
|
||||
|
|
|
@ -219,7 +219,8 @@ unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str);
|
|||
const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type);
|
||||
|
||||
bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
|
||||
OpenMPClauseKind CKind);
|
||||
OpenMPClauseKind CKind,
|
||||
unsigned OpenMPVersion);
|
||||
|
||||
/// Checks if the specified directive is a directive with an associated
|
||||
/// loop construct.
|
||||
|
|
|
@ -447,7 +447,8 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
|||
}
|
||||
|
||||
bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
|
||||
OpenMPClauseKind CKind) {
|
||||
OpenMPClauseKind CKind,
|
||||
unsigned OpenMPVersion) {
|
||||
assert(DKind <= OMPD_unknown);
|
||||
assert(CKind <= OMPC_unknown);
|
||||
switch (DKind) {
|
||||
|
@ -462,6 +463,8 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
|
|||
}
|
||||
break;
|
||||
case OMPD_simd:
|
||||
if (OpenMPVersion < 50 && CKind == OMPC_if)
|
||||
return false;
|
||||
switch (CKind) {
|
||||
#define OPENMP_SIMD_CLAUSE(Name) \
|
||||
case OMPC_##Name: \
|
||||
|
|
|
@ -241,17 +241,6 @@ protected:
|
|||
bool IsOffloadEntry,
|
||||
const RegionCodeGenTy &CodeGen);
|
||||
|
||||
/// Emits code for OpenMP 'if' clause using specified \a CodeGen
|
||||
/// function. Here is the logic:
|
||||
/// if (Cond) {
|
||||
/// ThenGen();
|
||||
/// } else {
|
||||
/// ElseGen();
|
||||
/// }
|
||||
void emitIfClause(CodeGenFunction &CGF, const Expr *Cond,
|
||||
const RegionCodeGenTy &ThenGen,
|
||||
const RegionCodeGenTy &ElseGen);
|
||||
|
||||
/// Emits object of ident_t type with info for source location.
|
||||
/// \param Flags Flags for OpenMP location.
|
||||
///
|
||||
|
@ -819,6 +808,17 @@ public:
|
|||
virtual ~CGOpenMPRuntime() {}
|
||||
virtual void clear();
|
||||
|
||||
/// Emits code for OpenMP 'if' clause using specified \a CodeGen
|
||||
/// function. Here is the logic:
|
||||
/// if (Cond) {
|
||||
/// ThenGen();
|
||||
/// } else {
|
||||
/// ElseGen();
|
||||
/// }
|
||||
void emitIfClause(CodeGenFunction &CGF, const Expr *Cond,
|
||||
const RegionCodeGenTy &ThenGen,
|
||||
const RegionCodeGenTy &ElseGen);
|
||||
|
||||
/// Checks if the \p Body is the \a CompoundStmt and returns its child
|
||||
/// statement iff there is only one that is not evaluatable at the compile
|
||||
/// time.
|
||||
|
|
|
@ -1846,8 +1846,6 @@ static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
|
|||
CGF.EmitIgnoredExpr(S.getCalcLastIteration());
|
||||
}
|
||||
|
||||
CGF.EmitOMPSimdInit(S);
|
||||
|
||||
emitAlignedClause(CGF, S);
|
||||
(void)CGF.EmitOMPLinearClauseInit(S);
|
||||
{
|
||||
|
@ -1860,13 +1858,46 @@ static void emitOMPSimdRegion(CodeGenFunction &CGF, const OMPLoopDirective &S,
|
|||
(void)LoopScope.Privatize();
|
||||
if (isOpenMPTargetExecutionDirective(S.getDirectiveKind()))
|
||||
CGF.CGM.getOpenMPRuntime().adjustTargetSpecificDataForLambdas(CGF, S);
|
||||
CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(), S.getCond(),
|
||||
S.getInc(),
|
||||
[&S](CodeGenFunction &CGF) {
|
||||
CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest());
|
||||
CGF.EmitStopPoint(&S);
|
||||
},
|
||||
[](CodeGenFunction &) {});
|
||||
|
||||
auto &&ThenGen = [&S, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
|
||||
CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
|
||||
CGF.EmitOMPSimdInit(S);
|
||||
|
||||
CGF.EmitOMPInnerLoop(
|
||||
S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
|
||||
[&S](CodeGenFunction &CGF) {
|
||||
CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest());
|
||||
CGF.EmitStopPoint(&S);
|
||||
},
|
||||
[](CodeGenFunction &) {});
|
||||
};
|
||||
auto &&ElseGen = [&S, &LoopScope](CodeGenFunction &CGF, PrePostActionTy &) {
|
||||
CodeGenFunction::OMPLocalDeclMapRAII Scope(CGF);
|
||||
CGF.LoopStack.setVectorizeEnable(/*Enable=*/false);
|
||||
|
||||
CGF.EmitOMPInnerLoop(
|
||||
S, LoopScope.requiresCleanups(), S.getCond(), S.getInc(),
|
||||
[&S](CodeGenFunction &CGF) {
|
||||
CGF.EmitOMPLoopBody(S, CodeGenFunction::JumpDest());
|
||||
CGF.EmitStopPoint(&S);
|
||||
},
|
||||
[](CodeGenFunction &) {});
|
||||
};
|
||||
const Expr *IfCond = nullptr;
|
||||
for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
|
||||
if (CGF.getLangOpts().OpenMP >= 50 &&
|
||||
(C->getNameModifier() == OMPD_unknown ||
|
||||
C->getNameModifier() == OMPD_simd)) {
|
||||
IfCond = C->getCondition();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (IfCond) {
|
||||
CGF.CGM.getOpenMPRuntime().emitIfClause(CGF, IfCond, ThenGen, ElseGen);
|
||||
} else {
|
||||
RegionCodeGenTy ThenRCG(ThenGen);
|
||||
ThenRCG(CGF);
|
||||
}
|
||||
CGF.EmitOMPSimdFinal(S, [](CodeGenFunction &) { return nullptr; });
|
||||
// Emit final copy of the lastprivate variables at the end of loops.
|
||||
if (HasLastprivateClause)
|
||||
|
|
|
@ -947,6 +947,19 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// Save/restore original map of previously emitted local vars in case when we
|
||||
/// need to duplicate emission of the same code several times in the same
|
||||
/// function for OpenMP code.
|
||||
class OMPLocalDeclMapRAII {
|
||||
CodeGenFunction &CGF;
|
||||
DeclMapTy SavedMap;
|
||||
|
||||
public:
|
||||
OMPLocalDeclMapRAII(CodeGenFunction &CGF)
|
||||
: CGF(CGF), SavedMap(CGF.LocalDeclMap) {}
|
||||
~OMPLocalDeclMapRAII() { SavedMap.swap(CGF.LocalDeclMap); }
|
||||
};
|
||||
|
||||
/// Takes the old cleanup stack size and emits the cleanup blocks
|
||||
/// that have been added.
|
||||
void
|
||||
|
|
|
@ -1939,7 +1939,8 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
bool ErrorFound = false;
|
||||
bool WrongDirective = false;
|
||||
// Check if clause is allowed for the given directive.
|
||||
if (CKind != OMPC_unknown && !isAllowedClauseForDirective(DKind, CKind)) {
|
||||
if (CKind != OMPC_unknown &&
|
||||
!isAllowedClauseForDirective(DKind, CKind, getLangOpts().OpenMP)) {
|
||||
Diag(Tok, diag::err_omp_unexpected_clause) << getOpenMPClauseName(CKind)
|
||||
<< getOpenMPDirectiveName(DKind);
|
||||
ErrorFound = true;
|
||||
|
|
|
@ -4488,6 +4488,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
|||
case OMPD_simd:
|
||||
Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
|
||||
VarsWithInheritedDSA);
|
||||
if (LangOpts.OpenMP >= 50)
|
||||
AllowedNameModifiers.push_back(OMPD_simd);
|
||||
break;
|
||||
case OMPD_for:
|
||||
Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
|
||||
|
@ -10667,6 +10669,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPD_master_taskloop:
|
||||
case OMPD_master_taskloop_simd:
|
||||
case OMPD_target_data:
|
||||
case OMPD_simd:
|
||||
// Do not capture if-clause expressions.
|
||||
break;
|
||||
case OMPD_threadprivate:
|
||||
|
@ -10683,7 +10686,6 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
|
|||
case OMPD_declare_target:
|
||||
case OMPD_end_declare_target:
|
||||
case OMPD_teams:
|
||||
case OMPD_simd:
|
||||
case OMPD_for:
|
||||
case OMPD_for_simd:
|
||||
case OMPD_sections:
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | 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 | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
|
||||
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 -ast-print %s -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 -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
|
||||
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -ast-print %s | 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 | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s --check-prefix=CHECK --check-prefix=OMP45
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 -ast-print %s -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 -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
|
@ -157,10 +163,15 @@ int main (int argc, char **argv) {
|
|||
for (int i=0; i < 2; ++i)*a=2;
|
||||
// CHECK-NEXT: for (int i = 0; i < 2; ++i)
|
||||
// CHECK-NEXT: *a = 2;
|
||||
#ifdef OMP5
|
||||
#pragma omp simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4) if(simd:a)
|
||||
// OMP50-NEXT: #pragma omp simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4) if(simd: a)
|
||||
#else
|
||||
#pragma omp simd private(argc, b),lastprivate(d,f) collapse(2) aligned(a : 4)
|
||||
// OMP45-NEXT: #pragma omp simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4)
|
||||
#endif // OMP5
|
||||
for (int i = 0; i < 10; ++i)
|
||||
for (int j = 0; j < 10; ++j) {foo(); k1 += 8; k2 += 8;}
|
||||
// CHECK-NEXT: #pragma omp simd private(argc,b) lastprivate(d,f) collapse(2) aligned(a: 4)
|
||||
// CHECK-NEXT: for (int i = 0; i < 10; ++i)
|
||||
// CHECK-NEXT: for (int j = 0; j < 10; ++j) {
|
||||
// CHECK-NEXT: foo();
|
||||
|
@ -172,8 +183,13 @@ int main (int argc, char **argv) {
|
|||
// CHECK-NEXT: foo();
|
||||
const int CLEN = 4;
|
||||
// CHECK-NEXT: const int CLEN = 4;
|
||||
#ifdef OMP5
|
||||
#pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) linear(val(ref): CLEN) if(a)
|
||||
// OMP50-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) linear(val(ref): CLEN) if(a)
|
||||
#else
|
||||
#pragma omp simd aligned(a:CLEN) linear(a:CLEN) safelen(CLEN) collapse( 1 ) simdlen(CLEN) linear(val(ref): CLEN)
|
||||
// CHECK-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) linear(val(ref): CLEN)
|
||||
// OMP45-NEXT: #pragma omp simd aligned(a: CLEN) linear(a: CLEN) safelen(CLEN) collapse(1) simdlen(CLEN) linear(val(ref): CLEN)
|
||||
#endif // OMP5
|
||||
for (int i = 0; i < 10; ++i)foo();
|
||||
// CHECK-NEXT: for (int i = 0; i < 10; ++i)
|
||||
// CHECK-NEXT: foo();
|
||||
|
|
|
@ -2,11 +2,17 @@
|
|||
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
|
||||
// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fopenmp-version=50 -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
|
||||
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -fopenmp-version=50 -DOMP5
|
||||
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
|
||||
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp-simd -fexceptions -fcxx-exceptions -debug-info-kind=line-tables-only -x c++ -emit-llvm %s -o - | FileCheck --check-prefix=TERM_DEBUG %s
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - -fopenmp-version=50 -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
|
||||
// RUN: %clang_cc1 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s -fopenmp-version=50 -DOMP5
|
||||
// RUN: %clang_cc1 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -debug-info-kind=limited -std=c++11 -include-pch %t -verify %s -emit-llvm -o - -fopenmp-version=50 -DOMP5 | FileCheck %s --check-prefix=CHECK --check-prefix=OMP50
|
||||
// expected-no-diagnostics
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
@ -18,8 +24,12 @@ double *g_ptr;
|
|||
|
||||
// CHECK-LABEL: define {{.*void}} @{{.*}}simple{{.*}}(float* {{.+}}, float* {{.+}}, float* {{.+}}, float* {{.+}})
|
||||
void simple(float *a, float *b, float *c, float *d) {
|
||||
#ifdef OMP5
|
||||
#pragma omp simd if (simd: true)
|
||||
#else
|
||||
#pragma omp simd
|
||||
// CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]]
|
||||
#endif
|
||||
// CHECK: store i32 0, i32* [[OMP_IV:%[^,]+]]
|
||||
|
||||
// CHECK: [[IV:%.+]] = load i32, i32* [[OMP_IV]]{{.*}}!llvm.access.group
|
||||
// CHECK-NEXT: [[CMP:%.+]] = icmp slt i32 [[IV]], 6
|
||||
|
@ -221,7 +231,16 @@ void simple(float *a, float *b, float *c, float *d) {
|
|||
R = -1;
|
||||
// CHECK: store i64 0, i64* [[OMP_IV8:%[^,]+]],
|
||||
// CHECK: store i32 1, i32* [[R_PRIV:%[^,]+]],
|
||||
#ifdef OMP5
|
||||
#pragma omp simd reduction(*:R) if(A)
|
||||
#else
|
||||
#pragma omp simd reduction(*:R)
|
||||
#endif
|
||||
// OMP50: [[A_VAL:%.+]] = load i32, i32* [[A]],
|
||||
// OMP50-NEXT: [[COND:%.+]] = icmp ne i32 [[A_VAL]], 0
|
||||
// OMP50-NEXT: br i1 [[COND]], label {{%?}}[[THEN:[^,]+]], label {{%?}}[[ELSE:[^,]+]]
|
||||
// OMP50: [[THEN]]:
|
||||
|
||||
// CHECK: br label %[[SIMD_LOOP8_COND:[^,]+]]
|
||||
// CHECK: [[SIMD_LOOP8_COND]]:
|
||||
// CHECK-NEXT: [[IV8:%.+]] = load i64, i64* [[OMP_IV8]]{{.*}}!llvm.access.group
|
||||
|
@ -242,6 +261,28 @@ void simple(float *a, float *b, float *c, float *d) {
|
|||
// CHECK-NEXT: store i64 [[ADD8_2]], i64* [[OMP_IV8]]{{.*}}!llvm.access.group
|
||||
}
|
||||
// CHECK: [[SIMPLE_LOOP8_END]]:
|
||||
// OMP50: br label {{%?}}[[EXIT:[^,]+]]
|
||||
// OMP50: br label %[[SIMD_LOOP8_COND:[^,]+]]
|
||||
// OMP50: [[SIMD_LOOP8_COND]]:
|
||||
// OMP50-NEXT: [[IV8:%.+]] = load i64, i64* [[OMP_IV8]],{{[^!]*}}
|
||||
// OMP50-NEXT: [[CMP8:%.+]] = icmp slt i64 [[IV8]], 7
|
||||
// OMP50-NEXT: br i1 [[CMP8]], label %[[SIMPLE_LOOP8_BODY:.+]], label %[[SIMPLE_LOOP8_END:[^,]+]]
|
||||
// OMP50: [[SIMPLE_LOOP8_BODY]]:
|
||||
// Start of body: calculate i from IV:
|
||||
// OMP50: [[IV8_0:%.+]] = load i64, i64* [[OMP_IV8]],{{[^!]*}}
|
||||
// OMP50-NEXT: [[LC_IT_1:%.+]] = mul nsw i64 [[IV8_0]], 3
|
||||
// OMP50-NEXT: [[LC_IT_2:%.+]] = add nsw i64 -10, [[LC_IT_1]]
|
||||
// OMP50-NEXT: store i64 [[LC_IT_2]], i64* [[LC:%[^,]+]],{{[^!]*}}
|
||||
// OMP50-NEXT: [[LC_VAL:%.+]] = load i64, i64* [[LC]],{{[^!]*}}
|
||||
// OMP50: store i32 %{{.+}}, i32* [[R_PRIV]],{{[^!]*}}
|
||||
// OMP50: [[IV8_2:%.+]] = load i64, i64* [[OMP_IV8]],{{[^!]*}}
|
||||
// OMP50-NEXT: [[ADD8_2:%.+]] = add nsw i64 [[IV8_2]], 1
|
||||
// OMP50-NEXT: store i64 [[ADD8_2]], i64* [[OMP_IV8]],{{[^!]*}}
|
||||
// OMP50: br label {{%?}}[[SIMD_LOOP8_COND]], {{.*}}!llvm.loop ![[DISABLE_VECT:.+]]
|
||||
// OMP50: [[SIMPLE_LOOP8_END]]:
|
||||
// OMP50: br label {{%?}}[[EXIT]]
|
||||
// OMP50: [[EXIT]]:
|
||||
|
||||
// CHECK-DAG: [[R_VAL:%.+]] = load i32, i32* [[R]],
|
||||
// CHECK-DAG: [[R_PRIV_VAL:%.+]] = load i32, i32* [[R_PRIV]],
|
||||
// CHECK: [[RED:%.+]] = mul nsw i32 [[R_VAL]], [[R_PRIV_VAL]]
|
||||
|
@ -761,6 +802,7 @@ S8 s8(0);
|
|||
|
||||
// TERM_DEBUG-NOT: line: 0,
|
||||
// TERM_DEBUG: distinct !DISubprogram(linkageName: "_GLOBAL__sub_I_simd_codegen.cpp",
|
||||
|
||||
// OMP50-DAG: ![[NOVECT:.+]] = !{!"llvm.loop.vectorize.enable", i1 false}
|
||||
// OMP50-DAG: ![[DISABLE_VECT]] = distinct !{{.*}}![[NOVECT]]{{[,}]}}
|
||||
#endif // HEADER
|
||||
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=50 %s -Wuninitialized
|
||||
|
||||
// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=50 %s -Wuninitialized
|
||||
|
||||
void foo() {
|
||||
}
|
||||
|
||||
bool foobool(int argc) {
|
||||
return argc;
|
||||
}
|
||||
|
||||
void xxx(int argc) {
|
||||
int cond; // expected-note {{initialize the variable 'cond' to silence this warning}}
|
||||
#pragma omp simd if(cond) // expected-warning {{variable 'cond' is uninitialized when used here}}
|
||||
for (int i = 0; i < 10; ++i)
|
||||
;
|
||||
}
|
||||
|
||||
struct S1; // expected-note {{declared here}}
|
||||
|
||||
template <class T, class S> // expected-note {{declared here}}
|
||||
int tmain(T argc, S **argv) {
|
||||
T z;
|
||||
int i;
|
||||
#pragma omp simd if // expected-error {{expected '(' after 'if'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if () // expected-error {{expected expression}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (argc > 0 ? argv[1] : argv[2])
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp simd' cannot contain more than one 'if' clause}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (S) // expected-error {{'S' does not refer to a value}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(argc + z)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(simd : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(simd : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(simd : argc)
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(target : argc) // expected-error {{directive name modifier 'target' is not allowed for '#pragma omp simd'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(simd : argc) if (simd :argc) // expected-error {{directive '#pragma omp simd' cannot contain more than one 'if' clause with 'simd' name modifier}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(simd : argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{no more 'if' clause is allowed}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int i, z;
|
||||
#pragma omp simd if // expected-error {{expected '(' after 'if'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if () // expected-error {{expected expression}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp simd' are ignored}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (argc > 0 ? argv[1] : argv[2])
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp simd' cannot contain more than one 'if' clause}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (S1) // expected-error {{'S1' does not refer to a value}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(simd : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(simd : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(simd : argc + z) if (target:argc) // expected-error {{directive name modifier 'target' is not allowed for '#pragma omp simd'}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(simd : argc) if (simd :argc) // expected-error {{directive '#pragma omp simd' cannot contain more than one 'if' clause with 'simd' name modifier}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
#pragma omp simd if(simd : argc) if (argc) // expected-note {{previous clause with directive name modifier specified here}} expected-error {{no more 'if' clause is allowed}}
|
||||
for (i = 0; i < argc; ++i) foo();
|
||||
|
||||
return tmain(argc, argv);
|
||||
}
|
Loading…
Reference in New Issue