[flang-commits] [flang] [mlir] [flang][mlir][OpenMP] Allow for flexible typing of linear step variables (PR #182816)

via flang-commits flang-commits at lists.llvm.org
Mon Feb 23 04:50:27 PST 2026


https://github.com/NimishMishra updated https://github.com/llvm/llvm-project/pull/182816

>From 2c535ffca0e2c596d8545fae4efb19ccb3c034e5 Mon Sep 17 00:00:00 2001
From: NimishMishra <neelam.nimish at gmail.com>
Date: Mon, 23 Feb 2026 13:09:47 +0530
Subject: [PATCH 1/2] [flang][mlir][OpenMP] Allow for flexible typing of linear
 step variables

---
 flang/lib/Lower/OpenMP/ClauseProcessor.cpp    | 20 ++++++++-----
 .../Lower/OpenMP/composite_simd_linear.f90    | 12 ++++----
 flang/test/Lower/OpenMP/declare-simd.f90      |  4 +--
 .../Lower/OpenMP/parallel-private-clause.f90  |  2 +-
 flang/test/Lower/OpenMP/simd-linear.f90       | 12 ++++----
 flang/test/Lower/OpenMP/wsloop-linear.f90     |  6 ++--
 .../mlir/Dialect/OpenMP/OpenMPClauses.td      |  4 +--
 mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp  | 21 +++++++------
 mlir/test/Dialect/OpenMP/ops.mlir             | 30 +++++++++----------
 .../Target/LLVMIR/openmp-llvm-invalid.mlir    |  4 +--
 mlir/test/Target/LLVMIR/openmp-llvm.mlir      |  8 ++---
 .../Target/LLVMIR/openmp-simd-guided.mlir     |  2 +-
 12 files changed, 67 insertions(+), 58 deletions(-)

diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index e62395676a696..2987907d2ea67 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1313,10 +1313,7 @@ bool ClauseProcessor::processLinear(mlir::omp::LinearClauseOps &result) const {
       result.linearVars.push_back(variable);
       mlir::Type ty = converter.genType(*sym);
       typeAttrs.push_back(mlir::TypeAttr::get(ty));
-    }
-    result.linearVarTypes =
-        mlir::ArrayAttr::get(&converter.getMLIRContext(), typeAttrs);
-    if (objects.size()) {
+
       if (auto &mod =
               std::get<std::optional<omp::clause::Linear::StepComplexModifier>>(
                   clause.t)) {
@@ -1331,11 +1328,20 @@ bool ClauseProcessor::processLinear(mlir::omp::LinearClauseOps &result) const {
         // If nothing is present, add the default step of 1.
         fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
         mlir::Location currentLocation = converter.getCurrentLocation();
-        mlir::Value operand = firOpBuilder.createIntegerConstant(
-            currentLocation, firOpBuilder.getI32Type(), 1);
-        result.linearStepVars.append(objects.size(), operand);
+        if (ty.isInteger()) {
+          mlir::Value operand =
+              firOpBuilder.createIntegerConstant(currentLocation, ty, 1);
+          result.linearStepVars.append(objects.size(), operand);
+        } else {
+          // Default to I32 type
+          mlir::Value operand = firOpBuilder.createIntegerConstant(
+              currentLocation, firOpBuilder.getI32Type(), 1);
+          result.linearStepVars.append(objects.size(), operand);
+        }
       }
     }
+    result.linearVarTypes =
+        mlir::ArrayAttr::get(&converter.getMLIRContext(), typeAttrs);
   });
 }
 
diff --git a/flang/test/Lower/OpenMP/composite_simd_linear.f90 b/flang/test/Lower/OpenMP/composite_simd_linear.f90
index 706b09d378db4..ff26f8663b35f 100644
--- a/flang/test/Lower/OpenMP/composite_simd_linear.f90
+++ b/flang/test/Lower/OpenMP/composite_simd_linear.f90
@@ -8,7 +8,7 @@ subroutine do_simd
 !CHECK: %{{.*}} = arith.constant 1 : i32
 !CHECK: %[[IV_STEP:.*]] = arith.constant 1 : i32
 !CHECK: omp.wsloop {
-!CHECK: omp.simd linear(%[[X]]#0 = %[[CONST]] : !fir.ref<i32>, %[[I]]#0 = %[[IV_STEP]] : !fir.ref<i32>) private(@_QFdo_simdEi_private_i32 {{.*}} -> %arg0 : !fir.ref<i32>) {
+!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[CONST]] : i32, %[[I]]#0 : !fir.ref<i32> = %[[IV_STEP]] : i32) private(@_QFdo_simdEi_private_i32 {{.*}} -> %arg0 : !fir.ref<i32>) {
 !CHECK: }
 !CHECK: } {linear_var_types = [i32, i32], omp.composite}
 !CHECK: } {omp.composite}
@@ -23,7 +23,7 @@ end subroutine do_simd
 subroutine distribute_simd
 !CHECK: omp.teams {
 !CHECK: omp.distribute private(@_QFdistribute_simdEi_private_i32 {{.*}} -> %[[ARG0:.*]] : !fir.ref<i32>) {
-!CHECK: omp.simd linear(%[[ARG0]] = %c1_i32 : !fir.ref<i32>) private(@_QFdistribute_simdEi_private_i32 %[[ARG0]] -> {{.*}} : !fir.ref<i32>) {
+!CHECK: omp.simd linear(%[[ARG0]] : !fir.ref<i32> = %c1_i32 : i32) private(@_QFdistribute_simdEi_private_i32 %[[ARG0]] -> {{.*}} : !fir.ref<i32>) {
 !CHECK: } {linear_var_types = [i32], omp.composite}
 !CHECK: } {omp.composite}
     integer :: i
@@ -44,7 +44,7 @@ subroutine distribute_parallel_do
 !CHECK: %[[CONST]] = arith.constant 1 : i32
 !CHECK: omp.distribute {
 !CHECK: omp.wsloop {
-!CHECK: omp.simd linear(%[[I]]#0 = %[[CONST]] : !fir.ref<i32>) private(@_QFdistribute_parallel_doEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) { 
+!CHECK: omp.simd linear(%[[I]]#0 : !fir.ref<i32> = %[[CONST]] : i32) private(@_QFdistribute_parallel_doEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) { 
     !$omp teams
     !$omp distribute parallel do simd linear(i:1)
     do i = 1, N
@@ -62,7 +62,7 @@ subroutine parallel_do
 !CHECK: %{{.*}} = arith.constant 1 : i32
 !CHECK: %[[IV_STEP:.*]] = arith.constant 1 : i32
 !CHECK: omp.wsloop {
-!CHECK: omp.simd linear(%[[X]]#0 = %[[LINEAR_STEP]] : !fir.ref<i32>, %[[I]]#0 = %[[IV_STEP]] : !fir.ref<i32>) private(@_QFparallel_doEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) {
+!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[LINEAR_STEP]] : i32, %[[I]]#0 : !fir.ref<i32> = %[[IV_STEP]] : i32) private(@_QFparallel_doEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) {
     integer :: x
     !$omp parallel do simd linear(x:2)
     do i = 1, N
@@ -79,7 +79,7 @@ subroutine teams_distribute
 !CHECK: {{.*}} = arith.constant 1 : i32
 !CHECK: %[[IV_STEP:.*]] = arith.constant 1 : i32
 !CHECK: omp.distribute {
-!CHECK: omp.simd linear(%[[X]]#0 = %[[LINEAR_STEP]] : !fir.ref<i32>, %[[I]]#0 = %[[IV_STEP]] : !fir.ref<i32>) private(@_QFteams_distributeEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) {
+!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[LINEAR_STEP]] : i32, %[[I]]#0 : !fir.ref<i32> = %[[IV_STEP]] : i32) private(@_QFteams_distributeEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) {
     integer :: x
     !$omp teams distribute simd linear(x)
     do i = 1, N
@@ -98,7 +98,7 @@ subroutine teams_distribute_parallel_do
 !CHECK: %[[IV_STEP:.*]] = arith.constant 1 : i32
 !CHECK: omp.distribute {
 !CHECK: omp.wsloop {
-!CHECK: omp.simd linear(%[[X]]#0 = %c1_i32 : !fir.ref<i32>, %[[I]]#0 = %c1_i32_1 : !fir.ref<i32>) private(@_QFteams_distribute_parallel_doEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) {
+!CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %c1_i32 : i32, %[[I]]#0 : !fir.ref<i32> = %c1_i32_1 : i32) private(@_QFteams_distribute_parallel_doEi_private_i32 %[[I]]#0 -> %arg0 : !fir.ref<i32>) {
     integer :: x
     !$omp teams distribute parallel do simd linear(x)
     do i = 1, N
diff --git a/flang/test/Lower/OpenMP/declare-simd.f90 b/flang/test/Lower/OpenMP/declare-simd.f90
index b80bcc5105e7e..5b578b436817a 100644
--- a/flang/test/Lower/OpenMP/declare-simd.f90
+++ b/flang/test/Lower/OpenMP/declare-simd.f90
@@ -57,7 +57,7 @@ end subroutine  declare_simd_linear
 ! CHECK: %[[SCOPE:.*]] = fir.dummy_scope : !fir.dscope
 ! CHECK: %[[I:.*]]:2 = hlfir.declare %{{.*}} dummy_scope %[[SCOPE]] arg 4 {{.*}} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)
 ! CHECK: %[[C1:.*]] = arith.constant 1 : i32
-! CHECK: omp.declare_simd linear(%[[I]]#0 = %[[C1]] : !fir.ref<i32>) {linear_var_types = [i32]}{{$}}
+! CHECK: omp.declare_simd linear(%[[I]]#0 : !fir.ref<i32> = %[[C1]] : i32) {linear_var_types = [i32]}{{$}}
 ! CHECK: return
 
 subroutine declare_simd_simdlen(x, y, n, i)
@@ -157,7 +157,7 @@ end subroutine declare_simd_combined
 ! CHECK-SAME: aligned(%[[X_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64,
 ! CHECK-SAME:         %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>> -> 64 : i64)
 ! CHECK-SAME: inbranch
-! CHECK-SAME: linear(%[[I_DECL]]#0 = %[[C1]] : !fir.ref<i32>)
+! CHECK-SAME: linear(%[[I_DECL]]#0 : !fir.ref<i32> = %[[C1]] : i32)
 ! CHECK-SAME: simdlen(8)
 ! CHECK-SAME: uniform(%[[X_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>,
 ! CHECK-SAME:         %[[Y_DECL]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xf64>>>>)
diff --git a/flang/test/Lower/OpenMP/parallel-private-clause.f90 b/flang/test/Lower/OpenMP/parallel-private-clause.f90
index a198ca8d09867..f998c09fc4d4f 100644
--- a/flang/test/Lower/OpenMP/parallel-private-clause.f90
+++ b/flang/test/Lower/OpenMP/parallel-private-clause.f90
@@ -349,7 +349,7 @@ subroutine simd_loop_1
   ! FIRDialect:     %[[UB:.*]] = arith.constant 9 : i32
   ! FIRDialect:     %[[STEP:.*]] = arith.constant 1 : i32
 
-  ! FIRDialect: omp.simd linear({{.*}} = %[[STEP]] : !fir.ref<i32>) private({{.*}}) {
+  ! FIRDialect: omp.simd linear({{.*}} : !fir.ref<i32> = %[[STEP]] : i32) private({{.*}}) {
   ! FIRDialect-NEXT: omp.loop_nest (%[[I:.*]]) : i32 = (%[[LB]]) to (%[[UB]]) inclusive step (%[[STEP]]) {
   !$OMP SIMD PRIVATE(r)
   do i=1, 9
diff --git a/flang/test/Lower/OpenMP/simd-linear.f90 b/flang/test/Lower/OpenMP/simd-linear.f90
index 2caf1b0ad05fa..3c8fe926ff8d1 100644
--- a/flang/test/Lower/OpenMP/simd-linear.f90
+++ b/flang/test/Lower/OpenMP/simd-linear.f90
@@ -16,9 +16,9 @@
 subroutine simple_linear
     implicit none
     integer :: x, y, i
-    !CHECK: omp.simd linear(%[[X]]#0 = %[[const]] : !fir.ref<i32>) {{.*}}
+    !CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[const]] : i32) {{.*}}
 
-    !IMPLICIT: omp.simd linear(%[[X]]#0 = %[[const]] : !fir.ref<i32>, %[[I]]#0 = %{{.*}} : !fir.ref<i32>) {{.*}}
+    !IMPLICIT: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[const]] : i32, %[[I]]#0 : !fir.ref<i32> = %{{.*}} : i32) {{.*}}
     !$omp simd linear(x)
     do i = 1, 10
     end do
@@ -39,9 +39,9 @@ subroutine linear_step
     implicit none
     integer :: x, y, i
     !CHECK: %[[const:.*]] = arith.constant 4 : i32
-    !CHECK: omp.simd linear(%[[X]]#0 = %[[const]] : !fir.ref<i32>) {{.*}}
+    !CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[const]] : i32) {{.*}}
 
-    !IMPLICIT: omp.simd linear(%[[X]]#0 = %[[const]] : !fir.ref<i32>, %[[I]]#0 = %{{.*}} : !fir.ref<i32>) {{.*}}
+    !IMPLICIT: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[const]] : i32, %[[I]]#0 : !fir.ref<i32> = %{{.*}} : i32) {{.*}}
     !$omp simd linear(x:4)
     do i = 1, 10
     end do
@@ -71,9 +71,9 @@ subroutine linear_expr
     !IMPLICIT: %[[const:.*]] = arith.constant 4 : i32
     !IMPLICIT: %[[LINEAR_EXPR:.*]] = arith.addi %[[LOAD_A]], %[[const]] : i32
 
-    !CHECK: omp.simd linear(%[[X]]#0 = %[[LINEAR_EXPR]] : !fir.ref<i32>) {{.*}}
+    !CHECK: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[LINEAR_EXPR]] : i32) {{.*}}
 
-    !IMPLICIT: omp.simd linear(%[[X]]#0 = %[[LINEAR_EXPR]] : !fir.ref<i32>, %[[I]]#0 = {{.*}} : !fir.ref<i32>) {{.*}}
+    !IMPLICIT: omp.simd linear(%[[X]]#0 : !fir.ref<i32> = %[[LINEAR_EXPR]] : i32, %[[I]]#0 : !fir.ref<i32> = {{.*}} : i32) {{.*}}
     !$omp simd linear(x:a+4)
     do i = 1, 10
     end do
diff --git a/flang/test/Lower/OpenMP/wsloop-linear.f90 b/flang/test/Lower/OpenMP/wsloop-linear.f90
index 0145be6a7c4e6..67588e24c4c5a 100644
--- a/flang/test/Lower/OpenMP/wsloop-linear.f90
+++ b/flang/test/Lower/OpenMP/wsloop-linear.f90
@@ -9,7 +9,7 @@
 subroutine simple_linear
     implicit none
     integer :: x, y, i
-    !CHECK: omp.wsloop linear(%[[X]]#0 = %[[const]] : !fir.ref<i32>) {{.*}}
+    !CHECK: omp.wsloop linear(%[[X]]#0 : !fir.ref<i32> = %[[const]] : i32) {{.*}}
     !$omp do linear(x)
     !CHECK: %[[LOAD:.*]] = fir.load %[[X]]#0 : !fir.ref<i32>
     !CHECK: %[[const:.*]] = arith.constant 2 : i32
@@ -28,7 +28,7 @@ subroutine linear_step
     implicit none
     integer :: x, y, i
     !CHECK: %[[const:.*]] = arith.constant 4 : i32
-    !CHECK: omp.wsloop linear(%[[X]]#0 = %[[const]] : !fir.ref<i32>) {{.*}}
+    !CHECK: omp.wsloop linear(%[[X]]#0 : !fir.ref<i32> = %[[const]] : i32) {{.*}}
     !$omp do linear(x:4)
     !CHECK: %[[LOAD:.*]] = fir.load %[[X]]#0 : !fir.ref<i32>
     !CHECK: %[[const:.*]] = arith.constant 2 : i32
@@ -50,7 +50,7 @@ subroutine linear_expr
     !CHECK: %[[LOAD_A:.*]] = fir.load %[[A]]#0 : !fir.ref<i32>
     !CHECK: %[[const:.*]] = arith.constant 4 : i32
     !CHECK: %[[LINEAR_EXPR:.*]] = arith.addi %[[LOAD_A]], %[[const]] : i32
-    !CHECK: omp.wsloop linear(%[[X]]#0 = %[[LINEAR_EXPR]] : !fir.ref<i32>) {{.*}}
+    !CHECK: omp.wsloop linear(%[[X]]#0 : !fir.ref<i32> = %[[LINEAR_EXPR]] : i32) {{.*}}
     !$omp do linear(x:a+4)
     do i = 1, 10
         y = x + 2
diff --git a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
index ba52e52ebf58d..20f14c0124969 100644
--- a/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
+++ b/mlir/include/mlir/Dialect/OpenMP/OpenMPClauses.td
@@ -770,13 +770,13 @@ class OpenMP_LinearClauseSkip<
   > : OpenMP_Clause<traits, arguments, assemblyFormat, description,
                     extraClassDeclaration> {
   let arguments = (ins Variadic<AnyType>:$linear_vars,
-      Variadic<I32>:$linear_step_vars,
+      Variadic<AnyInteger>:$linear_step_vars,
       OptionalAttr<ArrayAttr>:$linear_var_types);
 
   let optAssemblyFormat = [{
     `linear` `(`
       custom<LinearClause>($linear_vars, type($linear_vars),
-                           $linear_step_vars) `)`
+                           $linear_step_vars, type($linear_step_vars)) `)`
   }];
 
   let description = [{
diff --git a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
index 601c970bc8a69..8ffbe99756ff2 100644
--- a/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
+++ b/mlir/lib/Dialect/OpenMP/IR/OpenMPDialect.cpp
@@ -423,18 +423,21 @@ static ParseResult parseLinearClause(
     OpAsmParser &parser,
     SmallVectorImpl<OpAsmParser::UnresolvedOperand> &linearVars,
     SmallVectorImpl<Type> &linearTypes,
-    SmallVectorImpl<OpAsmParser::UnresolvedOperand> &linearStepVars) {
+    SmallVectorImpl<OpAsmParser::UnresolvedOperand> &linearStepVars,
+    SmallVectorImpl<Type> &linearStepTypes) {
   return parser.parseCommaSeparatedList([&]() {
     OpAsmParser::UnresolvedOperand var;
-    Type type;
+    Type type, stepType;
     OpAsmParser::UnresolvedOperand stepVar;
-    if (parser.parseOperand(var) || parser.parseEqual() ||
-        parser.parseOperand(stepVar) || parser.parseColonType(type))
+    if (parser.parseOperand(var) || parser.parseColonType(type) ||
+        parser.parseEqual() || parser.parseOperand(stepVar) ||
+        parser.parseColonType(stepType))
       return failure();
 
     linearVars.push_back(var);
     linearTypes.push_back(type);
     linearStepVars.push_back(stepVar);
+    linearStepTypes.push_back(stepType);
     return success();
   });
 }
@@ -442,14 +445,14 @@ static ParseResult parseLinearClause(
 /// Print Linear Clause
 static void printLinearClause(OpAsmPrinter &p, Operation *op,
                               ValueRange linearVars, TypeRange linearTypes,
-                              ValueRange linearStepVars) {
+                              ValueRange linearStepVars,
+                              TypeRange stepVarTypes) {
   size_t linearVarsSize = linearVars.size();
   for (unsigned i = 0; i < linearVarsSize; ++i) {
     std::string separator = i == linearVarsSize - 1 ? "" : ", ";
-    p << linearVars[i];
-    if (linearStepVars.size() > i)
-      p << " = " << linearStepVars[i];
-    p << " : " << linearVars[i].getType() << separator;
+    p << linearVars[i] << " : " << linearTypes[i];
+    p << " = " << linearStepVars[i] << " : " << stepVarTypes[i];
+    p << separator;
   }
 }
 
diff --git a/mlir/test/Dialect/OpenMP/ops.mlir b/mlir/test/Dialect/OpenMP/ops.mlir
index 5c2849cc9b5ea..d73f09ae29cd0 100644
--- a/mlir/test/Dialect/OpenMP/ops.mlir
+++ b/mlir/test/Dialect/OpenMP/ops.mlir
@@ -454,7 +454,7 @@ func.func @omp_wsloop(%lb : index, %ub : index, %step : index, %data_var : memre
   }) {operandSegmentSizes = array<i32: 0,0,0,0,0,0,0>, ordered = 1} :
     () -> ()
 
-  // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) schedule(static) {
+  // CHECK: omp.wsloop linear(%{{.*}} : memref<i32> = %{{.*}} : i32) schedule(static) {
   // CHECK-NEXT: omp.loop_nest
   "omp.wsloop" (%data_var, %linear_var) ({
     omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
@@ -463,7 +463,7 @@ func.func @omp_wsloop(%lb : index, %ub : index, %step : index, %data_var : memre
   }) {operandSegmentSizes = array<i32: 0,0,1,1,0,0,0>, schedule_kind = #omp<schedulekind static>,
      linear_var_types = [i32]} : (memref<i32>, i32) -> ()
 
-  // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>, %{{.*}} = %{{.*}} : memref<i32>) schedule(static) {
+  // CHECK: omp.wsloop linear(%{{.*}} : memref<i32> = %{{.*}} : i32, %{{.*}} : memref<i32> = %{{.*}} : i32) schedule(static) {
   // CHECK-NEXT: omp.loop_nest
   "omp.wsloop" (%data_var, %data_var, %linear_var, %linear_var) ({
     omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
@@ -473,7 +473,7 @@ func.func @omp_wsloop(%lb : index, %ub : index, %step : index, %data_var : memre
      linear_var_types = [i32,i32]} :
     (memref<i32>, memref<i32>, i32, i32) -> ()
 
-  // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) ordered(2) schedule(dynamic = %{{.*}}) {
+  // CHECK: omp.wsloop linear(%{{.*}} : memref<i32> = %{{.*}} : i32) ordered(2) schedule(dynamic = %{{.*}}) {
   // CHECK-NEXT: omp.loop_nest
   "omp.wsloop" (%data_var, %linear_var, %chunk_var) ({
     omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
@@ -516,33 +516,33 @@ func.func @omp_wsloop_pretty(%lb : index, %ub : index, %step : index, %data_var
     }
   }
 
-  // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) schedule(static) {
+  // CHECK: omp.wsloop linear(%{{.*}} : memref<i32> = %{{.*}} : i32) schedule(static) {
   // CHECK-NEXT: omp.loop_nest
-  omp.wsloop schedule(static) linear(%data_var = %linear_var : memref<i32>) {
+  omp.wsloop schedule(static) linear(%data_var : memref<i32> = %linear_var : i32) {
     omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
       omp.yield
     }
   } { linear_var_types = [i32] }
 
-  // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) ordered(2) schedule(static = %{{.*}} : i32) {
+  // CHECK: omp.wsloop linear(%{{.*}} : memref<i32> = %{{.*}} : i32) ordered(2) schedule(static = %{{.*}} : i32) {
   // CHECK-NEXT: omp.loop_nest
-  omp.wsloop ordered(2) linear(%data_var = %linear_var : memref<i32>) schedule(static = %chunk_var : i32) {
+  omp.wsloop ordered(2) linear(%data_var : memref<i32> = %linear_var : i32) schedule(static = %chunk_var : i32) {
     omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
       omp.yield
     }
   } { linear_var_types = [i32] }
 
-  // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) ordered(2) schedule(dynamic = %{{.*}} : i32, nonmonotonic) {
+  // CHECK: omp.wsloop linear(%{{.*}} : memref<i32> = %{{.*}} : i32) ordered(2) schedule(dynamic = %{{.*}} : i32, nonmonotonic) {
   // CHECK-NEXT: omp.loop_nest
-  omp.wsloop ordered(2) linear(%data_var = %linear_var : memref<i32>) schedule(dynamic = %chunk_var : i32, nonmonotonic) {
+  omp.wsloop ordered(2) linear(%data_var : memref<i32> = %linear_var : i32) schedule(dynamic = %chunk_var : i32, nonmonotonic) {
     omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step)  {
       omp.yield
     }
   } { linear_var_types = [i32] }
 
-  // CHECK: omp.wsloop linear(%{{.*}} = %{{.*}} : memref<i32>) ordered(2) schedule(dynamic = %{{.*}} : i16, monotonic) {
+  // CHECK: omp.wsloop linear(%{{.*}} : memref<i32> = %{{.*}} : i32) ordered(2) schedule(dynamic = %{{.*}} : i16, monotonic) {
   // CHECK-NEXT: omp.loop_nest
-  omp.wsloop ordered(2) linear(%data_var = %linear_var : memref<i32>) schedule(dynamic = %chunk_var2 : i16, monotonic) {
+  omp.wsloop ordered(2) linear(%data_var : memref<i32> = %linear_var : i32) schedule(dynamic = %chunk_var2 : i16, monotonic) {
     omp.loop_nest (%iv) : index = (%lb) to (%ub) step (%step) {
       omp.yield
     }
@@ -3447,8 +3447,8 @@ func.func @omp_declare_simd_aligned_list_generic(%arg0: f64, %arg1: f64,
 // CHECK-LABEL: func.func @omp_declare_simd_linear
 func.func @omp_declare_simd_linear(%a: f64, %b: f64, %iv: i32, %step: i32) -> () {
   // CHECK: omp.declare_simd
-  // CHECK-SAME: linear(%{{.*}} = %{{.*}} : i32)
-  omp.declare_simd linear(%iv = %step : i32)
+  // CHECK-SAME: linear(%{{.*}} : i32 = %{{.*}} : i32)
+  omp.declare_simd linear(%iv : i32 = %step : i32)
   return
 }
 
@@ -3507,7 +3507,7 @@ func.func @omp_declare_simd_all_clauses(%a: f64, %b: f64,
   // CHECK-SAME: %{{.*}} : memref<i32> -> 32 : i64,
   // CHECK-SAME: %{{.*}} : memref<i32> -> 128 : i64)
   // CHECK-SAME: inbranch
-  // CHECK-SAME: linear(%{{.*}} = %{{.*}} : i32)
+  // CHECK-SAME: linear(%{{.*}} : i32 = %{{.*}} : i32)
   // CHECK-SAME: simdlen(8)
   // CHECK-SAME: uniform(
   // CHECK-SAME: %{{.*}} : memref<i32>,
@@ -3515,7 +3515,7 @@ func.func @omp_declare_simd_all_clauses(%a: f64, %b: f64,
   omp.declare_simd simdlen(8)
     aligned(%p0 : memref<i32> -> 32 : i64,
             %p1 : memref<i32> -> 128 : i64)
-    linear(%iv = %step : i32)
+    linear(%iv : i32 = %step : i32)
     uniform(%p0 : memref<i32>, %p1 : memref<i32>)
     inbranch
   return
diff --git a/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir b/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir
index 73f753dc3f92e..d9459ace54422 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm-invalid.mlir
@@ -94,7 +94,7 @@ llvm.func @omp_threadprivate() {
 
 llvm.func @wsloop_linear(%lb : i32, %ub : i32, %step : i32, %x : !llvm.ptr) {
   // expected-error @below {{Ill-formed type attributes for linear variables}}
-  omp.wsloop linear(%x = %step : !llvm.ptr) {
+  omp.wsloop linear(%x : !llvm.ptr = %step : i32) {
      omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) {
        omp.yield
      }
@@ -106,7 +106,7 @@ llvm.func @wsloop_linear(%lb : i32, %ub : i32, %step : i32, %x : !llvm.ptr) {
 
 llvm.func @simd_linear(%lb : i32, %ub : i32, %step : i32, %x : !llvm.ptr) {
   // expected-error @below {{Ill-formed type attributes for linear variables}} 
-  omp.simd linear(%x = %step : !llvm.ptr) {
+  omp.simd linear(%x : !llvm.ptr = %step : i32) {
      omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) {
        omp.yield
      }
diff --git a/mlir/test/Target/LLVMIR/openmp-llvm.mlir b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
index 0b8a9765a4b87..a03c19559e9cd 100644
--- a/mlir/test/Target/LLVMIR/openmp-llvm.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-llvm.mlir
@@ -364,7 +364,7 @@ llvm.func @wsloop_linear(%lb : i32, %ub : i32, %step : i32, %x : !llvm.ptr) {
 // CHECK: call void @__kmpc_barrier(ptr {{.*}}, i32 %[[THREAD_ID]])
 // CHECK: br label %omp_loop.after
 
-  omp.wsloop linear(%x = %step : !llvm.ptr) {
+  omp.wsloop linear(%x : !llvm.ptr = %step : i32) {
     omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) {
       omp.yield
     }
@@ -759,7 +759,7 @@ llvm.func @simd_linear(%lb : i32, %ub : i32, %step : i32, %x : !llvm.ptr) {
 // CHECK: %[[MUL:.*]] = mul i32 %omp_loop.iv, {{.*}}
 // CHECK: %[[ADD:.*]] = add i32 %[[LOAD]], %[[MUL]]
 // CHECK: store i32 %[[ADD]], ptr %[[LINEAR_RESULT]], align 4, !llvm.access.group !1
-  omp.simd linear(%x = %step : !llvm.ptr) {
+  omp.simd linear(%x : !llvm.ptr = %step : i32) {
     omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) {
       omp.yield
     }
@@ -791,7 +791,7 @@ llvm.func @simd_linear_i64_var_i32_step(%lb : i32, %ub : i32, %x : !llvm.ptr) {
 // CHECK: %[[MUL:.*]] = mul i64 %[[IV_I64]], {{.*}}
 // CHECK: %[[ADD:.*]] = add i64 %[[LOAD]], %[[MUL]]
 // CHECK: store i64 %[[ADD]], ptr %[[LINEAR_RESULT]], {{.*}}!llvm.access.group
-  omp.simd linear(%x = %step : !llvm.ptr) {
+  omp.simd linear(%x : !llvm.ptr = %step : i32) {
     omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) {
       omp.yield
     }
@@ -823,7 +823,7 @@ llvm.func @simd_linear_f64_var_i32_step(%lb : i32, %ub : i32, %x : !llvm.ptr) {
 // CHECK-NEXT: %[[MUL_FP:.*]] = sitofp i32 %[[MUL_INT]] to double
 // CHECK-NEXT: %[[ADD:.*]] = fadd double %[[LOAD]], %[[MUL_FP]]
 // CHECK-NEXT: store double %[[ADD]], ptr %[[LINEAR_RESULT]], {{.*}}!llvm.access.group
-  omp.simd linear(%x = %step : !llvm.ptr) {
+  omp.simd linear(%x : !llvm.ptr = %step : i32) {
     omp.loop_nest (%iv) : i32 = (%lb) to (%ub) step (%step) {
       omp.yield
     }
diff --git a/mlir/test/Target/LLVMIR/openmp-simd-guided.mlir b/mlir/test/Target/LLVMIR/openmp-simd-guided.mlir
index ac46b4a56ba32..5c82689c6de03 100644
--- a/mlir/test/Target/LLVMIR/openmp-simd-guided.mlir
+++ b/mlir/test/Target/LLVMIR/openmp-simd-guided.mlir
@@ -10,7 +10,7 @@ llvm.func @test_simd_guided() {
   %c4_i32 = llvm.mlir.constant (4 : i32) : i32
   %1 = llvm.alloca %0 x i32 {bindc_name = "i"} : (i64) -> !llvm.ptr
   omp.wsloop schedule(guided = %c4_i32 : i32, simd) {
-    omp.simd linear(%1 = %c1_i32 : !llvm.ptr) private(@_QFEi_private_i32 %1 -> %arg0 : !llvm.ptr) {
+    omp.simd linear(%1 : !llvm.ptr = %c1_i32 : i32) private(@_QFEi_private_i32 %1 -> %arg0 : !llvm.ptr) {
       omp.loop_nest (%arg1) : i32 = (%c0_i32) to (%c64_i32) inclusive step (%c1_i32) {
         omp.yield
       }

>From 4221255f57e2b29219ea2fb900343eae6296c0d5 Mon Sep 17 00:00:00 2001
From: NimishMishra <42909663+NimishMishra at users.noreply.github.com>
Date: Mon, 23 Feb 2026 04:50:19 -0800
Subject: [PATCH 2/2] Update flang/lib/Lower/OpenMP/ClauseProcessor.cpp

Co-authored-by: Tom Eccles <t at freedommail.info>
---
 flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 2987907d2ea67..fe4f74919493d 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1328,16 +1328,10 @@ bool ClauseProcessor::processLinear(mlir::omp::LinearClauseOps &result) const {
         // If nothing is present, add the default step of 1.
         fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder();
         mlir::Location currentLocation = converter.getCurrentLocation();
-        if (ty.isInteger()) {
-          mlir::Value operand =
-              firOpBuilder.createIntegerConstant(currentLocation, ty, 1);
+       mlir::Type integerTy = ty.isInteger() ? ty : firOpBuilder.getI32Type();
+       mlir::Value operand =
+              firOpBuilder.createIntegerConstant(currentLocation, integerTy, 1);
           result.linearStepVars.append(objects.size(), operand);
-        } else {
-          // Default to I32 type
-          mlir::Value operand = firOpBuilder.createIntegerConstant(
-              currentLocation, firOpBuilder.getI32Type(), 1);
-          result.linearStepVars.append(objects.size(), operand);
-        }
       }
     }
     result.linearVarTypes =



More information about the flang-commits mailing list