summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Musman <alexander.musman@gmail.com>2014-10-06 11:16:29 +0000
committerAlexander Musman <alexander.musman@gmail.com>2014-10-06 11:16:29 +0000
commit174b3ca6820b66e475cf57d1c9d47f08267484e5 (patch)
treef2f8853cd35fee527048ef6f8bbc4c98758d6c8d
parent4ba642a2f7019bea00ba0d356749c23d269e982c (diff)
downloadbcm5719-llvm-174b3ca6820b66e475cf57d1c9d47f08267484e5.tar.gz
bcm5719-llvm-174b3ca6820b66e475cf57d1c9d47f08267484e5.zip
[OPENMP] Limit the loop counters to 64 bits for the worksharing loops
llvm-svn: 219113
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp29
-rw-r--r--clang/test/OpenMP/for_misc_messages.c6
3 files changed, 35 insertions, 3 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 7db98d59923..cb81078880d 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/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<OpenMPLoopForm>;
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/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index e70090d930e..ff2b2826092 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/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/clang/test/OpenMP/for_misc_messages.c b/clang/test/OpenMP/for_misc_messages.c
index 99e6a2b7d5f..ab40570e3ea 100644
--- a/clang/test/OpenMP/for_misc_messages.c
+++ b/clang/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];
+ }
}
OpenPOWER on IntegriCloud