[flang-commits] [flang] [flang][OpenMp] Fix LINEAR steps and ALLOCATABLE loop iteration variables (PR #234112)

Aditya Trivedi via flang-commits flang-commits at lists.llvm.org
Wed Oct 21 07:48:34 PDT 2026


https://github.com/adit4443ya updated https://github.com/llvm/llvm-project/pull/234112

>From 30dbb8d2a09a7b31c2f675b379f079eb8f1f1428 Mon Sep 17 00:00:00 2001
From: Aditya Trivedi <adit4443ya at gmail.com>
Date: Wed, 21 Oct 2026 14:08:52 +0530
Subject: [PATCH 1/3] [flang][OpenMP] Use one step per list item in LINEAR

processLinear added the step objects.size() times for every list item, so
items after a multi-item LINEAR clause were paired with the wrong step.
---
 flang/lib/Lower/OpenMP/ClauseProcessor.cpp |  4 ++--
 flang/test/Lower/OpenMP/simd-linear.f90    | 27 ++++++++++++++++++++++
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 34961d3d44ba2f..43fa51dfd98325 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1787,7 +1787,7 @@ bool ClauseProcessor::processLinear(
                   clause.t)) {
         mlir::Value operand =
             fir::getBase(converter.genExprValue(toEvExpr(*mod), stmtCtx));
-        result.linearStepVars.append(objects.size(), operand);
+        result.linearStepVars.push_back(operand);
       } else {
         // If nothing is present, add the default step of 1.
         fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
@@ -1795,7 +1795,7 @@ bool ClauseProcessor::processLinear(
         mlir::Type integerTy = ty.isInteger() ? ty : firOpBuilder.getI32Type();
         mlir::Value operand =
             firOpBuilder.createIntegerConstant(currentLocation, integerTy, 1);
-        result.linearStepVars.append(objects.size(), operand);
+        result.linearStepVars.push_back(operand);
       }
 
       // Determine the linear modifier:
diff --git a/flang/test/Lower/OpenMP/simd-linear.f90 b/flang/test/Lower/OpenMP/simd-linear.f90
index ef2fcafff39bf3..8f30e404d76c35 100644
--- a/flang/test/Lower/OpenMP/simd-linear.f90
+++ b/flang/test/Lower/OpenMP/simd-linear.f90
@@ -105,3 +105,30 @@ subroutine non_i32_type
     !CHECK: }
     !IMPLICIT: }
 end subroutine
+
+!CHECK-LABEL: func.func @_QPmultiple_items
+!CHECK: %[[A:.*]]:2 = hlfir.declare {{.*}} uniq_name("_QFmultiple_itemsEa")
+!CHECK: %[[B:.*]]:2 = hlfir.declare {{.*}} uniq_name("_QFmultiple_itemsEb")
+!CHECK: %[[C:.*]]:2 = hlfir.declare {{.*}} uniq_name("_QFmultiple_itemsEc")
+!CHECK: %[[TWO_A:.*]] = arith.constant 2 : i32
+!CHECK: %[[TWO_B:.*]] = arith.constant 2 : i32
+!CHECK: %[[THREE:.*]] = arith.constant 3 : i32
+!CHECK: omp.simd linear(val(@{{[^ ]+}} %[[A]]#0 -> %{{[^ ]+}} : !fir.ref<i32> = %[[TWO_A]] : i32), val(@{{[^ ]+}} %[[B]]#0 -> %{{[^ ]+}} : !fir.ref<i32> = %[[TWO_B]] : i32), val(@{{[^ ]+}} %[[C]]#0 -> %{{[^ ]+}} : !fir.ref<i32> = %[[THREE]] : i32)) linear_var_types([i32, i32, i32])
+
+!IMPLICIT-LABEL: func.func @_QPmultiple_items
+!IMPLICIT: %[[I:.*]]:2 = hlfir.declare {{.*}} uniq_name("_QFmultiple_itemsEi")
+!IMPLICIT: %[[TWO_A:.*]] = arith.constant 2 : i32
+!IMPLICIT: %[[TWO_B:.*]] = arith.constant 2 : i32
+!IMPLICIT: %[[THREE:.*]] = arith.constant 3 : i32
+!IMPLICIT: %{{.*}} = arith.constant 1 : i32
+!IMPLICIT: %{{.*}} = arith.constant 4 : i32
+!IMPLICIT: %[[STEP:.*]] = arith.constant 1 : i32
+!IMPLICIT: omp.simd linear({{.*}} = %[[TWO_A]] : i32, {{.*}} = %[[TWO_B]] : i32, {{.*}} = %[[THREE]] : i32, @{{[^ ]+}} %[[I]]#0 -> %{{[^ ]+}} : !fir.ref<i32> = %[[STEP]] : i32)
+subroutine multiple_items
+    implicit none
+    integer :: a, b, c, i
+    !$omp simd linear(a,b:2) linear(c:3)
+    do i = 1, 4
+    end do
+    !$omp end simd
+end subroutine

>From 267073a5db87ec1e86048c67b019e953fa156adc Mon Sep 17 00:00:00 2001
From: Aditya Trivedi <adit4443ya at gmail.com>
Date: Wed, 21 Oct 2026 14:08:52 +0530
Subject: [PATCH 2/3] [flang][OpenMP] Fix ALLOCATABLE loop iteration variables

Make an ALLOCATABLE SIMD loop variable implicitly linear, now that linear
privatizers support ALLOCATABLE, so it has the right value after the loop.

Size loop variables from the declared kind for ALLOCATABLE and POINTER
instead of the descriptor, which gave a spurious "narrowed into 64 bits"
warning and an i64 loop index.
---
 flang/lib/Lower/OpenMP/OpenMP.cpp             | 13 ++++--------
 flang/lib/Lower/OpenMP/Utils.cpp              | 16 +++++++++++++--
 flang/lib/Lower/OpenMP/Utils.h                |  2 ++
 flang/test/Lower/OpenMP/lastprivate-iv.f90    | 13 ++++++------
 .../test/Lower/OpenMP/linear-allocatable.f90  | 20 +++++++++++++++++++
 .../Lower/OpenMP/loop-pointer-variable.f90    | 18 ++++++++---------
 6 files changed, 54 insertions(+), 28 deletions(-)

diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index abe1df79f6aef2..abb4c53b3b1229 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -1518,7 +1518,7 @@ genLoopVars(mlir::Operation *op, lower::AbstractConverter &converter,
 
   std::size_t loopVarTypeSize = 0;
   for (const semantics::Symbol *arg : args)
-    loopVarTypeSize = std::max(loopVarTypeSize, arg->GetUltimate().size());
+    loopVarTypeSize = std::max(loopVarTypeSize, getLoopVarSize(*arg));
   mlir::Type loopVarType = getLoopVarType(converter, loopVarTypeSize);
   llvm::SmallVector<mlir::Type> tiv(args.size(), loopVarType);
   llvm::SmallVector<mlir::Location> locs(args.size(), loc);
@@ -2464,14 +2464,9 @@ static void genSimdImplicitLinear(
                   variable) != clauseOps.linearVars.end())
       continue;
 
-    // TODO: Implicit linearization is skipped if iv is a pointer
-    // or an allocatable, due to potential mismatch between the linear
-    // variable type (example !fir.ref<!fir.box<!fir.heap<i32>>>)
-    // and the linear step size (example: i64). Handle this type mismatch
-    // gracefully.
+    // TODO: Implicit linearization is skipped if iv is a pointer.
     if (loopVar->test(Fortran::semantics::Symbol::Flag::OmpLinear) &&
-        !(Fortran::semantics::IsAllocatableOrPointer(*loopVar) ||
-          Fortran::semantics::IsAllocatableOrPointer(loopVar->GetUltimate()))) {
+        !Fortran::semantics::IsPointer(loopVar->GetUltimate())) {
       mlir::Type ty = converter.genType(*loopVar);
       typeAttrs.push_back(mlir::TypeAttr::get(ty));
       if (semaCtx.langOptions().getOpenMPVersion() >= 52)
@@ -3075,7 +3070,7 @@ static void genCanonicalLoopNest(
         converter.genExprValue(*semantics::GetExpr(bounds->Upper()), stmtCtx));
 
     // Get the integer kind for the loop variable and cast the loop bounds.
-    size_t loopVarTypeSize = bounds->Name().thing.symbol->GetUltimate().size();
+    size_t loopVarTypeSize = getLoopVarSize(*bounds->Name().thing.symbol);
     mlir::Type loopVarType = getLoopVarType(converter, loopVarTypeSize);
     loopVarTypes.push_back(loopVarType);
     mlir::Value loopStepVar = [&]() {
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index 9e37c02eac3f1f..87016d2022e536 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -145,6 +145,18 @@ mlir::Type getLoopVarType(lower::AbstractConverter &converter,
   return converter.getFirOpBuilder().getIntegerType(loopVarTypeSize);
 }
 
+std::size_t getLoopVarSize(const semantics::Symbol &sym) {
+  const semantics::Symbol &ultimate = sym.GetUltimate();
+  // The storage of an ALLOCATABLE or POINTER is its descriptor; use the kind.
+  if (semantics::IsAllocatableOrPointer(ultimate))
+    if (const semantics::DeclTypeSpec *type = ultimate.GetType())
+      if (const semantics::IntrinsicTypeSpec *intrinsic = type->AsIntrinsic())
+        if (std::optional<std::int64_t> kind =
+                evaluate::ToInt64(intrinsic->kind()))
+          return *kind;
+  return ultimate.size();
+}
+
 semantics::Symbol *
 getIterationVariableSymbol(const lower::pft::Evaluation &eval) {
   return eval.visit(common::visitors{
@@ -897,8 +909,8 @@ void collectLoopRelatedInfo(
           currentLocation, firOpBuilder.getIntegerType(32), 1));
     }
     iv.push_back(bounds->Name().thing.symbol);
-    loopVarTypeSize = std::max(
-        loopVarTypeSize, bounds->Name().thing.symbol->GetUltimate().size());
+    loopVarTypeSize =
+        std::max(loopVarTypeSize, getLoopVarSize(*bounds->Name().thing.symbol));
     if (--collapseValue) {
       doConstructEval = tryGetNestedDoConstruct(*doConstructEval);
       // No DO construct left to descend into: COLLAPSE (or a tile SIZES list)
diff --git a/flang/lib/Lower/OpenMP/Utils.h b/flang/lib/Lower/OpenMP/Utils.h
index c769380aabbb01..16775f8facbc53 100644
--- a/flang/lib/Lower/OpenMP/Utils.h
+++ b/flang/lib/Lower/OpenMP/Utils.h
@@ -154,6 +154,8 @@ omp::ObjectList gatherObjectsOf(omp::Object derivedTypeMember,
 mlir::Type getLoopVarType(lower::AbstractConverter &converter,
                           std::size_t loopVarTypeSize);
 
+std::size_t getLoopVarSize(const semantics::Symbol &sym);
+
 semantics::Symbol *
 getIterationVariableSymbol(const lower::pft::Evaluation &eval);
 
diff --git a/flang/test/Lower/OpenMP/lastprivate-iv.f90 b/flang/test/Lower/OpenMP/lastprivate-iv.f90
index f40cfbc587fb01..bc0b2a0ead4c2c 100644
--- a/flang/test/Lower/OpenMP/lastprivate-iv.f90
+++ b/flang/test/Lower/OpenMP/lastprivate-iv.f90
@@ -96,27 +96,26 @@ subroutine lastprivate_iv_i1
 end subroutine
 
 !CHECK:    omp.wsloop private(@_QFlastprivate_iv_pointerEi_private_box_ptr_i32 %{{.*}}#0 -> %[[PRIVATE_IV:.*]] : !fir.ref<!fir.box<!fir.ptr<i32>>>) {
-!CHECK:      omp.loop_nest (%[[LOOP_INDEX:.*]]) : i64
+!CHECK:      omp.loop_nest (%[[LOOP_INDEX:.*]]) : i32
 !CHECK:        %[[PRIVATE_IV_DECL:.*]]:2 = hlfir.declare %[[PRIVATE_IV]] uniq_name("_QFlastprivate_iv_pointerEi") fortran_attrs<pointer> : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
-!CHECK:        %[[LOOP_INDEX_INCR:.*]] = arith.addi %[[LOOP_INDEX]], %{{.*}} : i64
+!CHECK:        %[[LOOP_INDEX_INCR:.*]] = arith.addi %[[LOOP_INDEX]], %{{.*}} : i32
 !CHECK:        fir.if %{{.*}} {
 !CHECK:          %[[PRIVATE_IV_BOX:.*]] = fir.load %[[PRIVATE_IV_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
 !CHECK:          %[[PRIVATE_IV_ADDR:.*]] = fir.box_addr %[[PRIVATE_IV_BOX]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
-!CHECK:          hlfir.assign %[[LOOP_INDEX_INCR]] to %[[PRIVATE_IV_ADDR]] : i64, !fir.ptr<i32>
+!CHECK:          hlfir.assign %[[LOOP_INDEX_INCR]] to %[[PRIVATE_IV_ADDR]] : i32, !fir.ptr<i32>
 !CHECK:        }
 !CHECK:        omp.yield
 !CHECK:      }
 !CHECK:    }
 
 !CHECK-FIR:    omp.wsloop private(@_QFlastprivate_iv_pointerEi_private_box_ptr_i32 %{{.*}} -> %[[PRIVATE_IV:.*]] : !fir.ref<!fir.box<!fir.ptr<i32>>>) {
-!CHECK-FIR:      omp.loop_nest (%[[LOOP_INDEX:.*]]) : i64
+!CHECK-FIR:      omp.loop_nest (%[[LOOP_INDEX:.*]]) : i32
 !CHECK-FIR:        %[[PRIVATE_IV_DECL:.*]] = fir.declare %[[PRIVATE_IV]] uniq_name("_QFlastprivate_iv_pointerEi") fortran_attrs<pointer> : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> !fir.ref<!fir.box<!fir.ptr<i32>>>
-!CHECK-FIR:        %[[LOOP_INDEX_INCR:.*]] = arith.addi %[[LOOP_INDEX]], %{{.*}} : i64
+!CHECK-FIR:        %[[LOOP_INDEX_INCR:.*]] = arith.addi %[[LOOP_INDEX]], %{{.*}} : i32
 !CHECK-FIR:        fir.if %{{.*}} {
 !CHECK-FIR:          %[[PRIVATE_IV_BOX:.*]] = fir.load %[[PRIVATE_IV_DECL]] : !fir.ref<!fir.box<!fir.ptr<i32>>>
 !CHECK-FIR:          %[[PRIVATE_IV_ADDR:.*]] = fir.box_addr %[[PRIVATE_IV_BOX]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
-!CHECK-FIR:          %[[LOOP_INDEX_CVT:.*]] = fir.convert %[[LOOP_INDEX_INCR]] : (i64) -> i32
-!CHECK-FIR:          fir.store %[[LOOP_INDEX_CVT]] to %[[PRIVATE_IV_ADDR]] : !fir.ptr<i32>
+!CHECK-FIR:          fir.store %[[LOOP_INDEX_INCR]] to %[[PRIVATE_IV_ADDR]] : !fir.ptr<i32>
 !CHECK-FIR:        }
 !CHECK-FIR:        omp.yield
 !CHECK-FIR:      }
diff --git a/flang/test/Lower/OpenMP/linear-allocatable.f90 b/flang/test/Lower/OpenMP/linear-allocatable.f90
index b6b62f5cf6872e..8a9df5b6ab9002 100644
--- a/flang/test/Lower/OpenMP/linear-allocatable.f90
+++ b/flang/test/Lower/OpenMP/linear-allocatable.f90
@@ -2,6 +2,9 @@
 
 ! RUN: %flang_fc1 -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
 ! RUN: bbc -emit-hlfir -fopenmp -o - %s 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=WARN --allow-empty
+
+! WARN-NOT: warning
 
 ! CHECK-LABEL: omp.private {type = linear} @_QFsimd_linear_allocatableEa_linear_box_heap_i32 : !fir.box<!fir.heap<i32>> init {
 ! CHECK:         fir.allocmem i32
@@ -111,3 +114,20 @@ subroutine original_used_after_loop()
   !$omp end simd
   a = 5
 end subroutine
+
+! An allocatable loop iteration variable is implicitly linear.
+! CHECK-LABEL: func.func @_QPimplicit_allocatable_iv
+! CHECK:         %[[I:.*]]:2 = hlfir.declare %{{.*}} uniq_name("_QFimplicit_allocatable_ivEi") fortran_attrs<allocatable>
+! CHECK:         omp.simd linear(@_QFimplicit_allocatable_ivEi_linear_box_heap_i32 %[[I]]#0 -> %{{.*}} : !fir.ref<!fir.box<!fir.heap<i32>>> = %{{.*}} : i32) linear_var_types([i32])
+! CHECK:           omp.loop_nest (%{{.*}}) : i32 =
+subroutine implicit_allocatable_iv()
+  integer, allocatable :: i
+  integer :: k
+  allocate(i)
+  k = 0
+  !$omp simd
+  do i = 1, 4
+    k = k + 1
+  end do
+  !$omp end simd
+end subroutine
diff --git a/flang/test/Lower/OpenMP/loop-pointer-variable.f90 b/flang/test/Lower/OpenMP/loop-pointer-variable.f90
index 0738e849cc7a7f..75c26fe6107999 100644
--- a/flang/test/Lower/OpenMP/loop-pointer-variable.f90
+++ b/flang/test/Lower/OpenMP/loop-pointer-variable.f90
@@ -10,17 +10,15 @@ program loop_var
 
 !CHECK:  %[[IA1:.*]]:2 = hlfir.declare %{{.*}} uniq_name("_QFEia1") fortran_attrs<allocatable>
 !CHECK:  omp.wsloop private(@_QFEip1_private_box_ptr_i32 %{{.*}}#0 -> %[[IP1_PVT:.*]], @_QFEip2_private_box_ptr_i32 %{{.*}}#0 -> %[[IP2_PVT:.*]] : !fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
-!CHECK:  omp.loop_nest (%[[IP1_INDX:.*]], %[[IP2_INDX:.*]]) : i64 = ({{.*}}) to ({{.*}}) inclusive step ({{.*}})
+!CHECK:  omp.loop_nest (%[[IP1_INDX:.*]], %[[IP2_INDX:.*]]) : i32 = ({{.*}}) to ({{.*}}) inclusive step ({{.*}})
 !CHECK:    %[[IP1_PVT_DECL:.*]]:2 = hlfir.declare %[[IP1_PVT]] uniq_name("_QFEip1") fortran_attrs<pointer> : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
 !CHECK:    %[[IP2_PVT_DECL:.*]]:2 = hlfir.declare %[[IP2_PVT]] uniq_name("_QFEip2") fortran_attrs<pointer> : (!fir.ref<!fir.box<!fir.ptr<i32>>>) -> (!fir.ref<!fir.box<!fir.ptr<i32>>>, !fir.ref<!fir.box<!fir.ptr<i32>>>)
-!CHECK:    %[[IP1:.*]] = fir.convert %[[IP1_INDX]] : (i64) -> i32
 !CHECK:    %[[IP1_BOX:.*]] = fir.load %[[IP1_PVT_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
 !CHECK:    %[[IP1_ADDR:.*]] = fir.box_addr %[[IP1_BOX]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
-!CHECK:    hlfir.assign %[[IP1]] to %[[IP1_ADDR]] : i32, !fir.ptr<i32>
-!CHECK:    %[[IP2:.*]] = fir.convert %[[IP2_INDX]] : (i64) -> i32
+!CHECK:    hlfir.assign %[[IP1_INDX]] to %[[IP1_ADDR]] : i32, !fir.ptr<i32>
 !CHECK:    %[[IP2_BOX:.*]] = fir.load %[[IP2_PVT_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<i32>>>
 !CHECK:    %[[IP2_ADDR:.*]] = fir.box_addr %[[IP2_BOX]] : (!fir.box<!fir.ptr<i32>>) -> !fir.ptr<i32>
-!CHECK:    hlfir.assign %[[IP2]] to %[[IP2_ADDR]] : i32, !fir.ptr<i32>
+!CHECK:    hlfir.assign %[[IP2_INDX]] to %[[IP2_ADDR]] : i32, !fir.ptr<i32>
 !CHECK:    omp.yield
   !$omp do collapse(2)
   do ip1 = 1, 10
@@ -29,12 +27,12 @@ program loop_var
   end do
   !$omp end do
 
-!CHECK:    omp.simd
-!CHECK:      omp.loop_nest (%[[IA1_INDX:.*]]) : i64 = ({{.*}}) to ({{.*}}) inclusive step ({{.*}})
-!CHECK:        %[[IA1_INDX_I32:.*]] = fir.convert %[[IA1_INDX]] : (i64) -> i32
-!CHECK:        %[[IA1_BOX:.*]] = fir.load %[[IA1]]#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
+!CHECK:    omp.simd linear(@_QFEia1_linear_box_heap_i32 %[[IA1]]#0 -> %[[IA1_PVT:.*]] : !fir.ref<!fir.box<!fir.heap<i32>>> = %{{.*}} : i32) linear_var_types([i32])
+!CHECK:      omp.loop_nest (%[[IA1_INDX:.*]]) : i32 = ({{.*}}) to ({{.*}}) inclusive step ({{.*}})
+!CHECK:        %[[IA1_PVT_DECL:.*]]:2 = hlfir.declare %[[IA1_PVT]] uniq_name("_QFEia1") fortran_attrs<allocatable>
+!CHECK:        %[[IA1_BOX:.*]] = fir.load %[[IA1_PVT_DECL]]#0 : !fir.ref<!fir.box<!fir.heap<i32>>>
 !CHECK:        %[[IA1_ADDR:.*]] = fir.box_addr %[[IA1_BOX]] : (!fir.box<!fir.heap<i32>>) -> !fir.heap<i32>
-!CHECK:        hlfir.assign %[[IA1_INDX_I32]] to %[[IA1_ADDR]] : i32, !fir.heap<i32>
+!CHECK:        hlfir.assign %[[IA1_INDX]] to %[[IA1_ADDR]] : i32, !fir.heap<i32>
 !CHECK:        omp.yield
   !$omp simd
   do ia1 = 1, 10

>From 5bf32fd127687f5e7c768a3a8a24a85b278ac23d Mon Sep 17 00:00:00 2001
From: Aditya Trivedi <adit4443ya at gmail.com>
Date: Wed, 21 Oct 2026 18:44:45 +0530
Subject: [PATCH 3/3] [flang][OpenMP] Update support docs for ALLOCATABLE loop
 variables

---
 flang/docs/OpenMPSupport.md | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/flang/docs/OpenMPSupport.md b/flang/docs/OpenMPSupport.md
index 83b0ad96d9ff3a..34ad87cec695bb 100644
--- a/flang/docs/OpenMPSupport.md
+++ b/flang/docs/OpenMPSupport.md
@@ -83,31 +83,31 @@ Parser/Semantics, MLIR, Lowering, or the OpenMPIRBuilder.
 | Feature                                                    | Status                            | Claimed By | Comments                                                |
 |:-----------------------------------------------------------|:----------------------------------|:-----------|:--------------------------------------------------------|
 | proc_bind clause                                           | <span class="good">done</span> | | |
-| simd construct                                             | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer or allocatable|
+| simd construct                                             | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer|
 | declare simd directive                                     | <span class="part">partial</span> | chichunchen | Semantics coverage exists (for example `flang/test/Semantics/OpenMP/declarative-directive01.f90`) and lowering exists for key forms (for example `flang/test/Lower/OpenMP/declare-simd-interface-body.f90`), but coverage is not yet complete for all variants. |
-| do simd construct                                          | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer or allocatable |
+| do simd construct                                          | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer |
 | target data construct                                      | <span class="good">done</span> | | |
 | target construct                                           | <span class="good">done</span> | | |
 | target update construct                                    | <span class="good">done</span> | | |
 | declare target directive                                   | <span class="good">done</span> | | |
 | teams construct                                            | <span class="good">done</span> | | |
 | distribute construct                                       | <span class="good">done</span> | | |
-| distribute simd construct                                  | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer or allocatable |
+| distribute simd construct                                  | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer |
 | distribute parallel loop construct                         | <span class="good">done</span> | | |
-| distribute parallel loop simd construct                    | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer or allocatable |
+| distribute parallel loop simd construct                    | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer |
 | depend clause                                              | <span class="good">done</span> | | |
 | declare reduction directive                                | <span class="part">partial</span> | sshrestha-aa | Partial support, including user-defined reductions with derived types. |
 | atomic construct extensions                                | <span class="good">done</span> | | |
 | cancel construct                                           | <span class="good">done</span> | | |
 | cancellation point construct                               | <span class="good">done</span> | | |
-| parallel do simd construct                                 | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer or allocatable |
+| parallel do simd construct                                 | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer |
 | target teams construct                                     | <span class="good">done</span> | | |
 | teams distribute construct                                 | <span class="good">done</span> | | |
-| teams distribute simd construct                            | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer or allocatable |
+| teams distribute simd construct                            | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer |
 | target teams distribute construct                          | <span class="good">done</span> | | |
 | teams distribute parallel loop construct                   | <span class="good">done</span> | | |
 | target teams distribute parallel loop construct            | <span class="good">done</span> | | |
-| teams distribute parallel loop simd construct              | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer or allocatable |
+| teams distribute parallel loop simd construct              | <span class="part">partial</span> | | Implicit linearization is skipped if iv is a pointer |
 | target teams distribute parallel loop simd construct       | <span class="part">partial</span> | | Implicit linearization is completely skipped |
 | taskgroup construct                                        | <span class="good">done</span> | | Semantics and lowering coverage exists (`flang/test/Semantics/OpenMP/taskgroup01.f90`, `flang/test/Lower/OpenMP/taskgroup.f90`). |
 



More information about the flang-commits mailing list