]> granicus.if.org Git - clang/commitdiff
[OPENMP] Limit the loop counters to 64 bits for the worksharing loops
authorAlexander Musman <alexander.musman@gmail.com>
Mon, 6 Oct 2014 11:16:29 +0000 (11:16 +0000)
committerAlexander Musman <alexander.musman@gmail.com>
Mon, 6 Oct 2014 11:16:29 +0000 (11:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@219113 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaOpenMP.cpp
test/OpenMP/for_misc_messages.c

index 7db98d59923a286987928cf664a5f7d49f0608c0..cb81078880d3084a8ea53e8d9e2af13ee93056dc 100644 (file)
@@ -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<
index e70090d930e7a646bf3c901f3f2bc7cd119ec28f..ff2b2826092f29ca6d069b3509ec7a841dc3aee6 100644 (file)
@@ -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();
index 99e6a2b7d5fd6a89aa85043600c8f373a9ca6774..ab40570e3ea36c5cfa78cedfffef57041fa1f627 100644 (file)
@@ -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];
+  }
 }