From: Alexander Musman Date: Mon, 6 Oct 2014 11:16:29 +0000 (+0000) Subject: [OPENMP] Limit the loop counters to 64 bits for the worksharing loops X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0015bb4d111761cc57d3d4df4b0462593f38c2a1;p=clang [OPENMP] Limit the loop counters to 64 bits for the worksharing loops git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219113 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 7db98d5992..cb81078880 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -7238,6 +7238,9 @@ def err_omp_loop_cannot_use_stmt : Error< "'%0' statement cannot be used in OpenMP for loop">; def err_omp_simd_region_cannot_use_stmt : Error< "'%0' statement cannot be used in OpenMP simd region">; +def warn_omp_loop_64_bit_var : Warning< + "OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed">, + InGroup; def err_omp_unknown_reduction_identifier : Error< "incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'">; def err_omp_reduction_type_array : Error< diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index e70090d930..ff2b282609 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -1851,7 +1851,7 @@ public: /// \brief True if the step should be subtracted. bool ShouldSubtractStep() const { return SubtractStep; } /// \brief Build the expression to calculate the number of iterations. - Expr *BuildNumIterations(Scope *S) const; + Expr *BuildNumIterations(Scope *S, const bool LimitedType) const; /// \brief Build reference expression to the counter be used for codegen. Expr *BuildCounterVar() const; /// \brief Build initization of the counter be used for codegen. @@ -2183,7 +2183,9 @@ bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { } /// \brief Build the expression to calculate the number of iterations. -Expr *OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S) const { +Expr * +OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, + const bool LimitedType) const { ExprResult Diff; if (Var->getType()->isIntegerType() || Var->getType()->isPointerType() || SemaRef.getLangOpts().CPlusPlus) { @@ -2230,6 +2232,26 @@ Expr *OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S) const { if (!Diff.isUsable()) return nullptr; + // OpenMP runtime requires 32-bit or 64-bit loop variables. + if (LimitedType) { + auto &C = SemaRef.Context; + QualType Type = Diff.get()->getType(); + unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; + if (NewSize != C.getTypeSize(Type)) { + if (NewSize < C.getTypeSize(Type)) { + assert(NewSize == 64 && "incorrect loop var size"); + SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) + << InitSrcRange << ConditionSrcRange; + } + QualType NewType = C.getIntTypeForBitwidth( + NewSize, Type->hasSignedIntegerRepresentation()); + Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, + Sema::AA_Converting, true); + if (!Diff.isUsable()) + return nullptr; + } + } + return Diff.get(); } @@ -2418,7 +2440,8 @@ static bool CheckOpenMPIterationSpace( return HasErrors; // Build the loop's iteration space representation. - ResultIterSpace.NumIterations = ISC.BuildNumIterations(DSA.getCurScope()); + ResultIterSpace.NumIterations = ISC.BuildNumIterations( + DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind)); ResultIterSpace.CounterVar = ISC.BuildCounterVar(); ResultIterSpace.CounterInit = ISC.BuildCounterInit(); ResultIterSpace.CounterStep = ISC.BuildCounterStep(); diff --git a/test/OpenMP/for_misc_messages.c b/test/OpenMP/for_misc_messages.c index 99e6a2b7d5..ab40570e3e 100644 --- a/test/OpenMP/for_misc_messages.c +++ b/test/OpenMP/for_misc_messages.c @@ -369,5 +369,11 @@ void test_loop_messages() { for (double fi = 0; fi < 10.0; fi++) { c[(int)fi] = a[(int)fi] + b[(int)fi]; } + + // expected-warning@+2 {{OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed}} + #pragma omp for + for (__int128 ii = 0; ii < 10; ii++) { + c[ii] = a[ii] + b[ii]; + } }