From 1189bd020570f465c02176a609eb5109ab2fe0f8 Mon Sep 17 00:00:00 2001 From: Alexey Bataev Date: Tue, 26 Jan 2016 12:20:39 +0000 Subject: [PATCH] [OPENMP 4.5] Allow arrays in 'reduction' clause. OpenMP 4.5, alogn with array sections, allows to use variables of array type in reductions. llvm-svn: 258804 --- .../clang/Basic/DiagnosticSemaKinds.td | 2 - clang/lib/CodeGen/CGOpenMPRuntime.cpp | 65 ++---- clang/lib/CodeGen/CGStmtOpenMP.cpp | 104 ++++++++-- clang/lib/CodeGen/CodeGenFunction.h | 2 + clang/lib/Sema/SemaOpenMP.cpp | 24 +-- clang/test/OpenMP/for_reduction_codegen.cpp | 195 ++++++++++++++++++ clang/test/OpenMP/for_reduction_messages.cpp | 12 +- .../OpenMP/for_simd_reduction_messages.cpp | 12 +- .../parallel_for_reduction_messages.cpp | 12 +- .../parallel_for_simd_reduction_messages.cpp | 12 +- .../OpenMP/parallel_reduction_messages.cpp | 12 +- .../parallel_sections_reduction_messages.cpp | 12 +- .../OpenMP/sections_reduction_messages.cpp | 12 +- clang/test/OpenMP/simd_reduction_messages.cpp | 12 +- .../test/OpenMP/teams_reduction_messages.cpp | 12 +- 15 files changed, 363 insertions(+), 137 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index e39cf22bd59b..a71111ada64f 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -7847,8 +7847,6 @@ def warn_omp_loop_64_bit_var : Warning< InGroup; def err_omp_unknown_reduction_identifier : Error< "incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'">; -def err_omp_reduction_type_array : Error< - "a reduction list item with array type %0">; def err_omp_reduction_ref_type_arg : Error< "argument of OpenMP clause 'reduction' must reference the same object in all threads">; def err_omp_clause_not_arithmetic_type_arg : Error< diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 5cfacacbe01a..6aa2737cba3d 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -967,26 +967,6 @@ CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) { return RTLFn; } -static llvm::Value *getTypeSize(CodeGenFunction &CGF, QualType Ty) { - auto &C = CGF.getContext(); - llvm::Value *Size = nullptr; - auto SizeInChars = C.getTypeSizeInChars(Ty); - if (SizeInChars.isZero()) { - // getTypeSizeInChars() returns 0 for a VLA. - while (auto *VAT = C.getAsVariableArrayType(Ty)) { - llvm::Value *ArraySize; - std::tie(ArraySize, Ty) = CGF.getVLASize(VAT); - Size = Size ? CGF.Builder.CreateNUWMul(Size, ArraySize) : ArraySize; - } - SizeInChars = C.getTypeSizeInChars(Ty); - assert(!SizeInChars.isZero()); - Size = CGF.Builder.CreateNUWMul( - Size, llvm::ConstantInt::get(CGF.SizeTy, SizeInChars.getQuantity())); - } else - Size = llvm::ConstantInt::get(CGF.SizeTy, SizeInChars.getQuantity()); - return Size; -} - llvm::Constant *CGOpenMPRuntime::createForStaticInitFunction(unsigned IVSize, bool IVSigned) { assert((IVSize == 32 || IVSize == 64) && @@ -1655,7 +1635,7 @@ void CGOpenMPRuntime::emitSingleRegion(CodeGenFunction &CGF, auto *CpyFn = emitCopyprivateCopyFunction( CGM, CGF.ConvertTypeForMem(CopyprivateArrayTy)->getPointerTo(), CopyprivateVars, SrcExprs, DstExprs, AssignmentOps); - auto *BufSize = getTypeSize(CGF, CopyprivateArrayTy); + auto *BufSize = CGF.getTypeSize(CopyprivateArrayTy); Address CL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(CopyprivateList, CGF.VoidPtrTy); @@ -2806,7 +2786,7 @@ void CGOpenMPRuntime::emitTaskCall( C.getPointerType(KmpTaskTWithPrivatesQTy); auto *KmpTaskTWithPrivatesTy = CGF.ConvertType(KmpTaskTWithPrivatesQTy); auto *KmpTaskTWithPrivatesPtrTy = KmpTaskTWithPrivatesTy->getPointerTo(); - auto *KmpTaskTWithPrivatesTySize = getTypeSize(CGF, KmpTaskTWithPrivatesQTy); + auto *KmpTaskTWithPrivatesTySize = CGF.getTypeSize(KmpTaskTWithPrivatesQTy); QualType SharedsPtrTy = C.getPointerType(SharedsTy); // Emit initial values for private copies (if any). @@ -3006,7 +2986,7 @@ void CGOpenMPRuntime::emitTaskCall( llvm::Value *UpIntPtr = CGF.Builder.CreatePtrToInt(UpAddr, CGM.SizeTy); Size = CGF.Builder.CreateNUWSub(UpIntPtr, LowIntPtr); } else - Size = getTypeSize(CGF, Ty); + Size = CGF.getTypeSize(Ty); auto Base = CGF.MakeAddrLValue( CGF.Builder.CreateConstArrayGEP(DependenciesArray, i, DependencySize), KmpDependInfoTy); @@ -3255,17 +3235,16 @@ static llvm::Value *emitReductionFunction(CodeGenModule &CGM, return emitAddrOfVarFromArray(CGF, LHS, Idx, LHSVar); }); QualType PrivTy = (*IPriv)->getType(); - if (PrivTy->isArrayType()) { + if (PrivTy->isVariablyModifiedType()) { // Get array size and emit VLA type. ++Idx; Address Elem = CGF.Builder.CreateConstArrayGEP(LHS, Idx, CGF.getPointerSize()); llvm::Value *Ptr = CGF.Builder.CreateLoad(Elem); + auto *VLA = CGF.getContext().getAsVariableArrayType(PrivTy); + auto *OVE = cast(VLA->getSizeExpr()); CodeGenFunction::OpaqueValueMapping OpaqueMap( - CGF, - cast( - CGF.getContext().getAsVariableArrayType(PrivTy)->getSizeExpr()), - RValue::get(CGF.Builder.CreatePtrToInt(Ptr, CGF.SizeTy))); + CGF, OVE, RValue::get(CGF.Builder.CreatePtrToInt(Ptr, CGF.SizeTy))); CGF.EmitVariablyModifiedType(PrivTy); } } @@ -3361,7 +3340,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc, // void *RedList[] = {[0], ..., [-1]}; auto Size = RHSExprs.size(); for (auto *E : Privates) { - if (E->getType()->isArrayType()) + if (E->getType()->isVariablyModifiedType()) // Reserve place for array size. ++Size; } @@ -3380,20 +3359,18 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc, CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( CGF.EmitLValue(RHSExprs[I]).getPointer(), CGF.VoidPtrTy), Elem); - if ((*IPriv)->getType()->isArrayType()) { + if ((*IPriv)->getType()->isVariablyModifiedType()) { // Store array size. ++Idx; Elem = CGF.Builder.CreateConstArrayGEP(ReductionList, Idx, CGF.getPointerSize()); - CGF.Builder.CreateStore( - CGF.Builder.CreateIntToPtr( - CGF.Builder.CreateIntCast( - CGF.getVLASize(CGF.getContext().getAsVariableArrayType( - (*IPriv)->getType())) - .first, - CGF.SizeTy, /*isSigned=*/false), - CGF.VoidPtrTy), - Elem); + llvm::Value *Size = CGF.Builder.CreateIntCast( + CGF.getVLASize( + CGF.getContext().getAsVariableArrayType((*IPriv)->getType())) + .first, + CGF.SizeTy, /*isSigned=*/false); + CGF.Builder.CreateStore(CGF.Builder.CreateIntToPtr(Size, CGF.VoidPtrTy), + Elem); } } @@ -3411,7 +3388,7 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc, CGF, Loc, static_cast(OMP_IDENT_KMPC | OMP_ATOMIC_REDUCE)); auto *ThreadId = getThreadID(CGF, Loc); - auto *ReductionArrayTySize = getTypeSize(CGF, ReductionArrayTy); + auto *ReductionArrayTySize = CGF.getTypeSize(ReductionArrayTy); auto *RL = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(ReductionList.getPointer(), CGF.VoidPtrTy); @@ -3873,14 +3850,14 @@ void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF, // VLA sizes are passed to the outlined region by copy. if (CI->capturesVariableArrayType()) { BasePointer = Pointer = *CV; - Size = getTypeSize(CGF, RI->getType()); + Size = CGF.getTypeSize(RI->getType()); // Copy to the device as an argument. No need to retrieve it. MapType = OMP_MAP_BYCOPY; hasVLACaptures = true; } else if (CI->capturesThis()) { BasePointer = Pointer = *CV; const PointerType *PtrTy = cast(RI->getType().getTypePtr()); - Size = getTypeSize(CGF, PtrTy->getPointeeType()); + Size = CGF.getTypeSize(PtrTy->getPointeeType()); // Default map type. MapType = OMP_MAP_TO | OMP_MAP_FROM; } else if (CI->capturesVariableByCopy()) { @@ -3909,7 +3886,7 @@ void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF, MapType |= OMP_MAP_PTR; BasePointer = Pointer = *CV; } - Size = getTypeSize(CGF, RI->getType()); + Size = CGF.getTypeSize(RI->getType()); } else { assert(CI->capturesVariable() && "Expected captured reference."); BasePointer = Pointer = *CV; @@ -3917,7 +3894,7 @@ void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF, const ReferenceType *PtrTy = cast(RI->getType().getTypePtr()); QualType ElementType = PtrTy->getPointeeType(); - Size = getTypeSize(CGF, ElementType); + Size = CGF.getTypeSize(ElementType); // The default map type for a scalar/complex type is 'to' because by // default the value doesn't have to be retrieved. For an aggregate type, // the default is 'tofrom'. diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 42899fcb811e..a6abbba93409 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -20,6 +20,26 @@ using namespace clang; using namespace CodeGen; +llvm::Value *CodeGenFunction::getTypeSize(QualType Ty) { + auto &C = getContext(); + llvm::Value *Size = nullptr; + auto SizeInChars = C.getTypeSizeInChars(Ty); + if (SizeInChars.isZero()) { + // getTypeSizeInChars() returns 0 for a VLA. + while (auto *VAT = C.getAsVariableArrayType(Ty)) { + llvm::Value *ArraySize; + std::tie(ArraySize, Ty) = getVLASize(VAT); + Size = Size ? Builder.CreateNUWMul(Size, ArraySize) : ArraySize; + } + SizeInChars = C.getTypeSizeInChars(Ty); + if (SizeInChars.isZero()) + return llvm::ConstantInt::get(SizeTy, /*V=*/0); + Size = Builder.CreateNUWMul(Size, CGM.getSize(SizeInChars)); + } else + Size = CGM.getSize(SizeInChars); + return Size; +} + void CodeGenFunction::GenerateOpenMPCapturedVars( const CapturedStmt &S, SmallVectorImpl &CapturedVars) { const RecordDecl *RD = S.getCapturedRecordDecl(); @@ -779,32 +799,76 @@ void CodeGenFunction::EmitOMPReductionClauseInit( assert(IsRegistered && "private var already registered as private"); // Silence the warning about unused variable. (void)IsRegistered; - PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address { - return GetAddrOfLocalVar(PrivateVD); + PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address { + return Builder.CreateElementBitCast( + GetAddrOfLocalVar(PrivateVD), ConvertTypeForMem(RHSVD->getType()), + "rhs.begin"); }); } else { auto *OrigVD = cast(cast(IRef)->getDecl()); - // Store the address of the original variable associated with the LHS - // implicit variable. - PrivateScope.addPrivate(LHSVD, [this, OrigVD, IRef]() -> Address { + QualType Type = PrivateVD->getType(); + if (getContext().getAsArrayType(Type)) { + // Store the address of the original variable associated with the LHS + // implicit variable. DeclRefExpr DRE(const_cast(OrigVD), CapturedStmtInfo->lookup(OrigVD) != nullptr, IRef->getType(), VK_LValue, IRef->getExprLoc()); - return EmitLValue(&DRE).getAddress(); - }); - // Emit reduction copy. - bool IsRegistered = - PrivateScope.addPrivate(OrigVD, [this, PrivateVD]() -> Address { - // Emit private VarDecl with reduction init. - EmitDecl(*PrivateVD); - return GetAddrOfLocalVar(PrivateVD); - }); - assert(IsRegistered && "private var already registered as private"); - // Silence the warning about unused variable. - (void)IsRegistered; - PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address { - return GetAddrOfLocalVar(PrivateVD); - }); + Address OriginalAddr = EmitLValue(&DRE).getAddress(); + PrivateScope.addPrivate(LHSVD, [this, OriginalAddr, + LHSVD]() -> Address { + return Builder.CreateElementBitCast( + OriginalAddr, ConvertTypeForMem(LHSVD->getType()), + "lhs.begin"); + }); + bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address { + if (Type->isVariablyModifiedType()) { + CodeGenFunction::OpaqueValueMapping OpaqueMap( + *this, cast( + getContext() + .getAsVariableArrayType(PrivateVD->getType()) + ->getSizeExpr()), + RValue::get( + getTypeSize(OrigVD->getType().getNonReferenceType()))); + EmitVariablyModifiedType(Type); + } + auto Emission = EmitAutoVarAlloca(*PrivateVD); + auto Addr = Emission.getAllocatedAddress(); + auto *Init = PrivateVD->getInit(); + EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(), Init); + EmitAutoVarCleanups(Emission); + return Emission.getAllocatedAddress(); + }); + assert(IsRegistered && "private var already registered as private"); + // Silence the warning about unused variable. + (void)IsRegistered; + PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address { + return Builder.CreateElementBitCast( + GetAddrOfLocalVar(PrivateVD), + ConvertTypeForMem(RHSVD->getType()), "rhs.begin"); + }); + } else { + // Store the address of the original variable associated with the LHS + // implicit variable. + PrivateScope.addPrivate(LHSVD, [this, OrigVD, IRef]() -> Address { + DeclRefExpr DRE(const_cast(OrigVD), + CapturedStmtInfo->lookup(OrigVD) != nullptr, + IRef->getType(), VK_LValue, IRef->getExprLoc()); + return EmitLValue(&DRE).getAddress(); + }); + // Emit reduction copy. + bool IsRegistered = + PrivateScope.addPrivate(OrigVD, [this, PrivateVD]() -> Address { + // Emit private VarDecl with reduction init. + EmitDecl(*PrivateVD); + return GetAddrOfLocalVar(PrivateVD); + }); + assert(IsRegistered && "private var already registered as private"); + // Silence the warning about unused variable. + (void)IsRegistered; + PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address { + return GetAddrOfLocalVar(PrivateVD); + }); + } } ++ILHS, ++IRHS, ++IPriv; } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index bbfe82d5b509..10bec3910e39 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2206,6 +2206,8 @@ public: void EmitCXXForRangeStmt(const CXXForRangeStmt &S, ArrayRef Attrs = None); + /// Returns calculated size of the specified type. + llvm::Value *getTypeSize(QualType Ty); LValue InitCapturedStruct(const CapturedStmt &S); llvm::Function *EmitCapturedStmt(const CapturedStmt &S, CapturedRegionKind K); llvm::Function *GenerateCapturedStmtFunction(const CapturedStmt &S); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 6272a6284e60..d9ea8fb0ccaf 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -7469,7 +7469,7 @@ OMPClause *Sema::ActOnOpenMPReductionClause( if (DE) { auto D = DE->getDecl(); VD = cast(D); - Type = VD->getType(); + Type = Context.getBaseElementType(VD->getType()); } else if (ASE) { Type = ASE->getType(); auto *Base = ASE->getBase()->IgnoreParenImpCasts(); @@ -7511,19 +7511,6 @@ OMPClause *Sema::ActOnOpenMPReductionClause( diag::err_omp_reduction_incomplete_type)) continue; // OpenMP [2.14.3.6, reduction clause, Restrictions] - // Arrays may not appear in a reduction clause. - if (Type.getNonReferenceType()->isArrayType()) { - Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange; - if (!ASE && !OASE) { - bool IsDecl = VD->isThisDeclarationADefinition(Context) == - VarDecl::DeclarationOnly; - Diag(VD->getLocation(), - IsDecl ? diag::note_previous_decl : diag::note_defined_here) - << VD; - } - continue; - } - // OpenMP [2.14.3.6, reduction clause, Restrictions] // A list item that appears in a reduction clause must not be // const-qualified. if (Type.getNonReferenceType().isConstant(Context)) { @@ -7636,8 +7623,9 @@ OMPClause *Sema::ActOnOpenMPReductionClause( auto *RHSVD = buildVarDecl(*this, ELoc, Type, VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); auto PrivateTy = Type; - if (OASE) { - // For array sections only: + if (OASE || + (DE && VD->getType().getNonReferenceType()->isVariablyModifiedType())) { + // For arays/array sections only: // Create pseudo array type for private copy. The size for this array will // be generated during codegen. // For array subscripts or single variables Private Ty is the same as Type @@ -7646,7 +7634,9 @@ OMPClause *Sema::ActOnOpenMPReductionClause( Type, new (Context) OpaqueValueExpr(SourceLocation(), Context.getSizeType(), VK_RValue), ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); - } + } else if (DE && + Context.getAsArrayType(VD->getType().getNonReferenceType())) + PrivateTy = VD->getType().getNonReferenceType(); // Private copy. auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); diff --git a/clang/test/OpenMP/for_reduction_codegen.cpp b/clang/test/OpenMP/for_reduction_codegen.cpp index 423ab3ce76d0..e6c44b7a3453 100644 --- a/clang/test/OpenMP/for_reduction_codegen.cpp +++ b/clang/test/OpenMP/for_reduction_codegen.cpp @@ -192,6 +192,10 @@ int main() { #pragma omp parallel for reduction(+:arr[1][:vec[1]]) reduction(&:arrs[1:vec[1]][1:2]) for (int i = 0; i < 10; ++i) ++arr[1][i]; +#pragma omp parallel +#pragma omp for reduction(+:arr) reduction(&:arrs) + for (int i = 0; i < 10; ++i) + ++arr[1][i]; return tmain(); #endif } @@ -201,6 +205,7 @@ int main() { // CHECK: call {{.*}} [[S_FLOAT_TY_CONSTR:@.+]]([[S_FLOAT_TY]]* [[TEST]]) // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [2 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [2 x i32]*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK1:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK2:@.+]] to void // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT:@.+]]() // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret @@ -666,6 +671,196 @@ int main() { // CHECK: ret void +// CHECK: define internal void [[MAIN_MICROTASK2]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i64 %{{.+}}, i64 %{{.+}}, i32* nonnull %{{.+}}, [10 x [4 x [[S_FLOAT_TY]]]]* dereferenceable(160) %{{.+}}) + +// CHECK: [[ARRS_PRIV:%.+]] = alloca [10 x [4 x [[S_FLOAT_TY]]]], + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [3 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], + +// CHECK: [[ARR_SIZE:%.+]] = mul nuw i64 %{{.+}}, 4 +// CHECK: call i8* @llvm.stacksave() +// CHECK: [[ARR_PRIV:%.+]] = alloca i32, i64 [[ARR_SIZE]], + +// Check initialization of private copy. +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_PRIV]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_PRIV]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: store i32 0, i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// Check initialization of private copy. +// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]* +// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0 +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[BEGIN]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_ZN1SIfEC1Ev([[S_FLOAT_TY]]* % +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], +// CHECK: [[ARRS_PRIV_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]] to [[S_FLOAT_TY]]* + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: call void @__kmpc_for_static_init_4( +// Skip checks for internal operations. +// CHECK: call void @__kmpc_for_static_fini( + +// void *RedList[] = {[0], ..., [-1]}; + +// CHECK: [[ARR_PRIV_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 0 +// CHECK: [[BITCAST:%.+]] = bitcast i32* [[ARR_PRIV]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARR_PRIV_REF]], +// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 1 +// CHECK: [[BITCAST:%.+]] = inttoptr i64 [[ARR_SIZE]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARR_SIZE_REF]], +// CHECK: [[ARRS_PRIV_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST]], i64 0, i64 2 +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[ARRS_PRIV_BEGIN]] to i8* +// CHECK: store i8* [[BITCAST]], i8** [[ARRS_PRIV_REF]], + +// res = __kmpc_reduce(, , , sizeof(RedList), RedList, reduce_func, &); + +// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]] +// CHECK: [[GTID:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[GTID_REF]] +// CHECK: [[BITCAST:%.+]] = bitcast [3 x i8*]* [[RED_LIST]] to i8* +// CHECK: [[RES:%.+]] = call i32 @__kmpc_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], i32 2, i64 24, i8* [[BITCAST]], void (i8*, i8*)* [[REDUCTION_FUNC:@.+]], [8 x i32]* [[REDUCTION_LOCK]]) + +// switch(res) +// CHECK: switch i32 [[RES]], label %[[RED_DONE:.+]] [ +// CHECK: i32 1, label %[[CASE1:.+]] +// CHECK: i32 2, label %[[CASE2:.+]] +// CHECK: ] + +// case 1: +// CHECK: [[CASE1]] + +// arr[:] += arr_reduction[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0:%.+]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: [[ADD:%.+]] = add nsw i32 % +// CHECK: store i32 [[ADD]], i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs[:] = var.operator &(arrs_reduction[:]); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LHS_BEGIN]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[LHS_BEGIN]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: [[AND:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @_ZN1SIfEanERKS0_([[S_FLOAT_TY]]* %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}) +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[AND]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* [[BITCAST]], i64 4, i32 4, i1 false) +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// __kmpc_end_reduce(, , &); +// CHECK: call void @__kmpc_end_reduce(%{{.+}}* [[REDUCTION_LOC]], i32 [[GTID]], [8 x i32]* [[REDUCTION_LOCK]]) + +// break; +// CHECK: br label %[[RED_DONE]] + +// case 2: +// CHECK: [[CASE2]] + +// arr[:] += arr_reduction[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[LB1_0]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[LB1_0]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: atomicrmw add i32* %{{.+}}, i32 %{{.+}} monotonic +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs[:] = var.operator &(arrs_reduction[:]); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[LHS_BEGIN]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[LHS_BEGIN]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @__kmpc_critical( +// CHECK: [[AND:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @_ZN1SIfEanERKS0_([[S_FLOAT_TY]]* %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}) +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[AND]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* [[BITCAST]], i64 4, i32 4, i1 false) +// CHECK: call void @__kmpc_end_critical( +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// break; +// CHECK: br label %[[RED_DONE]] +// CHECK: [[RED_DONE]] + +// Check destruction of private copy. +// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0 +// CHECK: [[END:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40 +// CHECK: br +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: call void @_ZN1SIfED1Ev([[S_FLOAT_TY]]* % +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[BEGIN]] +// CHECK: br i1 [[DONE]], +// CHECK: call void @llvm.stackrestore(i8* +// CHECK: call void @__kmpc_barrier( + +// CHECK: ret void + +// void reduce_func(void *lhs[], void *rhs[]) { +// *(Type0*)lhs[0] = ReductionOperation0(*(Type0*)lhs[0], *(Type0*)rhs[0]); +// ... +// *(Type-1*)lhs[-1] = ReductionOperation-1(*(Type-1*)lhs[-1], +// *(Type-1*)rhs[-1]); +// } +// CHECK: define internal void [[REDUCTION_FUNC]](i8*, i8*) +// arr_rhs = (int*)rhs[0]; +// CHECK: [[ARR_RHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_RHS:%.+]], i64 0, i64 0 +// CHECK: [[ARR_RHS_VOID:%.+]] = load i8*, i8** [[ARR_RHS_REF]], +// CHECK: [[ARR_RHS:%.+]] = bitcast i8* [[ARR_RHS_VOID]] to i32* +// arr_lhs = (int*)lhs[0]; +// CHECK: [[ARR_LHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS:%.+]], i64 0, i64 0 +// CHECK: [[ARR_LHS_VOID:%.+]] = load i8*, i8** [[ARR_LHS_REF]], +// CHECK: [[ARR_LHS:%.+]] = bitcast i8* [[ARR_LHS_VOID]] to i32* + +// arr_size = (size_t)lhs[1]; +// CHECK: [[ARR_SIZE_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS]], i64 0, i64 1 +// CHECK: [[ARR_SIZE_VOID:%.+]] = load i8*, i8** [[ARR_SIZE_REF]], +// CHECK: [[ARR_SIZE:%.+]] = ptrtoint i8* [[ARR_SIZE_VOID]] to i64 + +// arrs_rhs = (S*)rhs[2]; +// CHECK: [[ARRS_RHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_RHS]], i64 0, i64 2 +// CHECK: [[ARRS_RHS_VOID:%.+]] = load i8*, i8** [[ARRS_RHS_REF]], +// CHECK: [[ARRS_RHS:%.+]] = bitcast i8* [[ARRS_RHS_VOID]] to [[S_FLOAT_TY]]* +// arrs_lhs = (S*)lhs[2]; +// CHECK: [[ARRS_LHS_REF:%.+]] = getelementptr inbounds [3 x i8*], [3 x i8*]* [[RED_LIST_LHS]], i64 0, i64 2 +// CHECK: [[ARRS_LHS_VOID:%.+]] = load i8*, i8** [[ARRS_LHS_REF]], +// CHECK: [[ARRS_LHS:%.+]] = bitcast i8* [[ARRS_LHS_VOID]] to [[S_FLOAT_TY]]* + +// arr_lhs[:] += arr_rhs[:]; +// CHECK: [[END:%.+]] = getelementptr i32, i32* [[ARR_LHS]], i64 [[ARR_SIZE]] +// CHECK: [[ISEMPTY:%.+]] = icmp eq i32* [[ARR_LHS]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi i32* +// CHECK: [[ADD:%.+]] = add nsw i32 % +// CHECK: store i32 [[ADD]], i32* % +// CHECK: [[DONE:%.+]] = icmp eq i32* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// arrs_lhs = arrs_lhs.operator &(arrs_rhs); +// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[ARRS_LB:%.+]], i64 40 +// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[ARRS_LB]], [[END]] +// CHECK: br i1 [[ISEMPTY]], +// CHECK: phi [[S_FLOAT_TY]]* +// CHECK: [[AND:%.+]] = call dereferenceable(4) [[S_FLOAT_TY]]* @_ZN1SIfEanERKS0_([[S_FLOAT_TY]]* %{{.+}}, [[S_FLOAT_TY]]* dereferenceable(4) %{{.+}}) +// CHECK: [[BITCAST:%.+]] = bitcast [[S_FLOAT_TY]]* [[AND]] to i8* +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.+}}, i8* [[BITCAST]], i64 4, i32 4, i1 false) +// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]] +// CHECK: br i1 [[DONE]], + +// CHECK: ret void + // CHECK: define {{.*}} i{{[0-9]+}} [[TMAIN_INT]]() // CHECK: [[TEST:%.+]] = alloca [[S_INT_TY]], // CHECK: call {{.*}} [[S_INT_TY_CONSTR:@.+]]([[S_INT_TY]]* [[TEST]]) diff --git a/clang/test/OpenMP/for_reduction_messages.cpp b/clang/test/OpenMP/for_reduction_messages.cpp index 317f88ce11ba..2e1b6ed44471 100644 --- a/clang/test/OpenMP/for_reduction_messages.cpp +++ b/clang/test/OpenMP/for_reduction_messages.cpp @@ -147,15 +147,15 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -304,15 +304,15 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel diff --git a/clang/test/OpenMP/for_simd_reduction_messages.cpp b/clang/test/OpenMP/for_simd_reduction_messages.cpp index 000960fb55b5..0fef5d1d10fb 100644 --- a/clang/test/OpenMP/for_simd_reduction_messages.cpp +++ b/clang/test/OpenMP/for_simd_reduction_messages.cpp @@ -146,15 +146,15 @@ T tmain(T argc) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel @@ -295,15 +295,15 @@ int main(int argc, char **argv) { for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel -#pragma omp for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel diff --git a/clang/test/OpenMP/parallel_for_reduction_messages.cpp b/clang/test/OpenMP/parallel_for_reduction_messages.cpp index 22251b446300..458416717378 100644 --- a/clang/test/OpenMP/parallel_for_reduction_messages.cpp +++ b/clang/test/OpenMP/parallel_for_reduction_messages.cpp @@ -129,13 +129,13 @@ T tmain(T argc) { #pragma omp parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -251,13 +251,13 @@ int main(int argc, char **argv) { #pragma omp parallel for reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel for reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel for reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp parallel for reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} diff --git a/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp b/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp index e2e9e1bca38b..48446e43d42c 100644 --- a/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp +++ b/clang/test/OpenMP/parallel_for_simd_reduction_messages.cpp @@ -129,13 +129,13 @@ T tmain(T argc) { #pragma omp parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -251,13 +251,13 @@ int main(int argc, char **argv) { #pragma omp parallel for simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel for simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel for simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp parallel for simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp parallel for simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp parallel for simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} diff --git a/clang/test/OpenMP/parallel_reduction_messages.cpp b/clang/test/OpenMP/parallel_reduction_messages.cpp index b29f7c98a574..4365a0f43825 100644 --- a/clang/test/OpenMP/parallel_reduction_messages.cpp +++ b/clang/test/OpenMP/parallel_reduction_messages.cpp @@ -113,11 +113,11 @@ T tmain(T argc) { foo(); #pragma omp parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); -#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} foo(); -#pragma omp parallel reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} foo(); -#pragma omp parallel reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); @@ -208,11 +208,11 @@ int main(int argc, char **argv) { foo(); #pragma omp parallel reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); -#pragma omp parallel reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} foo(); -#pragma omp parallel reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} foo(); -#pragma omp parallel reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp parallel reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp parallel reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} foo(); diff --git a/clang/test/OpenMP/parallel_sections_reduction_messages.cpp b/clang/test/OpenMP/parallel_sections_reduction_messages.cpp index eff1849d7132..50f46254d6c8 100644 --- a/clang/test/OpenMP/parallel_sections_reduction_messages.cpp +++ b/clang/test/OpenMP/parallel_sections_reduction_messages.cpp @@ -145,15 +145,15 @@ T tmain(T argc) { { foo(); } -#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp parallel sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -298,15 +298,15 @@ int main(int argc, char **argv) { { foo(); } -#pragma omp parallel sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp parallel sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp parallel sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } -#pragma omp parallel sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp parallel sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } diff --git a/clang/test/OpenMP/sections_reduction_messages.cpp b/clang/test/OpenMP/sections_reduction_messages.cpp index 79473d4e5d28..b724965e2569 100644 --- a/clang/test/OpenMP/sections_reduction_messages.cpp +++ b/clang/test/OpenMP/sections_reduction_messages.cpp @@ -162,17 +162,17 @@ T tmain(T argc) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} { foo(); } @@ -342,17 +342,17 @@ int main(int argc, char **argv) { foo(); } #pragma omp parallel -#pragma omp sections reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp sections reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp sections reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } #pragma omp parallel -#pragma omp sections reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp sections reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} { foo(); } diff --git a/clang/test/OpenMP/simd_reduction_messages.cpp b/clang/test/OpenMP/simd_reduction_messages.cpp index e082921cf383..41e53189fc1e 100644 --- a/clang/test/OpenMP/simd_reduction_messages.cpp +++ b/clang/test/OpenMP/simd_reduction_messages.cpp @@ -129,13 +129,13 @@ T tmain(T argc) { #pragma omp simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -254,13 +254,13 @@ int main(int argc, char **argv) { #pragma omp simd reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp simd reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp simd reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); -#pragma omp simd reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp simd reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} for (int i = 0; i < 10; ++i) foo(); #pragma omp simd reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} diff --git a/clang/test/OpenMP/teams_reduction_messages.cpp b/clang/test/OpenMP/teams_reduction_messages.cpp index 87d03485c17b..c9790e3b6a7e 100644 --- a/clang/test/OpenMP/teams_reduction_messages.cpp +++ b/clang/test/OpenMP/teams_reduction_messages.cpp @@ -130,13 +130,13 @@ T tmain(T argc) { #pragma omp teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp target -#pragma omp teams reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} expected-error {{a reduction list item with array type 'const float [5]'}} +#pragma omp teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target #pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}} @@ -258,13 +258,13 @@ int main(int argc, char **argv) { #pragma omp teams reduction(max : h.b) // expected-error {{expected variable name, array element or array section}} foo(); #pragma omp target -#pragma omp teams reduction(+ : ba) // expected-error {{a reduction list item with array type 'const S2 [5]'}} +#pragma omp teams reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(* : ca) // expected-error {{a reduction list item with array type 'const S3 [5]'}} +#pragma omp teams reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target -#pragma omp teams reduction(- : da) // expected-error {{a reduction list item with array type 'const int [5]'}} +#pragma omp teams reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} foo(); #pragma omp target #pragma omp teams reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}