Skip to content

Conversation

@kparzysz
Copy link
Contributor

Use getNestedDoConstruct from Utils to get the nested DoConstructs.

Fixes #169532

Use `getNestedDoConstruct` from Utils to get the nested DoConstructs.

Fixes #169532
@llvmbot llvmbot added flang Flang issues not falling into any other category flang:fir-hlfir flang:openmp labels Nov 25, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 25, 2025

@llvm/pr-subscribers-flang-openmp

@llvm/pr-subscribers-flang-fir-hlfir

Author: Krzysztof Parzyszek (kparzysz)

Changes

Use getNestedDoConstruct from Utils to get the nested DoConstructs.

Fixes #169532


Full diff: https://github.com/llvm/llvm-project/pull/169565.diff

4 Files Affected:

  • (modified) flang/lib/Lower/OpenMP/OpenMP.cpp (+4-8)
  • (modified) flang/lib/Lower/OpenMP/Utils.cpp (+1-1)
  • (modified) flang/lib/Lower/OpenMP/Utils.h (+2)
  • (added) flang/test/Lower/OpenMP/compiler-directives-loop.f90 (+31)
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 6ca8636bb6459..abe65cdb2102f 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -25,6 +25,7 @@
 #include "flang/Lower/ConvertVariable.h"
 #include "flang/Lower/DirectivesCommon.h"
 #include "flang/Lower/OpenMP/Clauses.h"
+#include "flang/Lower/PFTBuilder.h"
 #include "flang/Lower/StatementContext.h"
 #include "flang/Lower/Support/ReductionProcessor.h"
 #include "flang/Lower/SymbolMap.h"
@@ -568,14 +569,9 @@ getCollapsedLoopEval(lower::pft::Evaluation &eval, int collapseValue) {
   if (collapseValue == 0)
     return &eval;
 
-  lower::pft::Evaluation *curEval = &eval.getFirstNestedEvaluation();
-  for (int i = 1; i < collapseValue; i++) {
-    // The nested evaluations should be DoConstructs (i.e. they should form
-    // a loop nest). Each DoConstruct is a tuple <NonLabelDoStmt, Block,
-    // EndDoStmt>.
-    assert(curEval->isA<parser::DoConstruct>());
-    curEval = &*std::next(curEval->getNestedEvaluations().begin());
-  }
+  lower::pft::Evaluation *curEval = &eval;
+  for (int i = 0; i < collapseValue; i++)
+    curEval = getNestedDoConstruct(*curEval);
   return curEval;
 }
 
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index fed84eb4df071..ccac64335c29a 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -796,7 +796,7 @@ static void processTileSizesFromOpenMPConstruct(
   }
 }
 
-static pft::Evaluation *getNestedDoConstruct(pft::Evaluation &eval) {
+pft::Evaluation *getNestedDoConstruct(pft::Evaluation &eval) {
   for (pft::Evaluation &nested : eval.getNestedEvaluations()) {
     // In an OpenMPConstruct there can be compiler directives:
     // 1 <<OpenMPConstruct>>
diff --git a/flang/lib/Lower/OpenMP/Utils.h b/flang/lib/Lower/OpenMP/Utils.h
index 2960b663b08b2..8a68ff8bd3bdc 100644
--- a/flang/lib/Lower/OpenMP/Utils.h
+++ b/flang/lib/Lower/OpenMP/Utils.h
@@ -167,6 +167,8 @@ void genObjectList(const ObjectList &objects,
 void lastprivateModifierNotSupported(const omp::clause::Lastprivate &lastp,
                                      mlir::Location loc);
 
+pft::Evaluation *getNestedDoConstruct(pft::Evaluation &eval);
+
 int64_t collectLoopRelatedInfo(
     lower::AbstractConverter &converter, mlir::Location currentLocation,
     lower::pft::Evaluation &eval, const omp::List<omp::Clause> &clauses,
diff --git a/flang/test/Lower/OpenMP/compiler-directives-loop.f90 b/flang/test/Lower/OpenMP/compiler-directives-loop.f90
new file mode 100644
index 0000000000000..916b5a9fbd57f
--- /dev/null
+++ b/flang/test/Lower/OpenMP/compiler-directives-loop.f90
@@ -0,0 +1,31 @@
+!RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=60 %s -o - | FileCheck %s
+
+! Check that we generate proper body of the do-construct.
+
+!CHECK: omp.loop_nest (%[[ARG1:arg[0-9]+]]) : i32 = (%c1_i32) to (%c10_i32) inclusive step (%c1_i32_1) {
+!CHECK:   %[[V0:[0-9]+]]:2 = hlfir.declare %arg0 {uniq_name = "_QFEi"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)
+!CHECK:   hlfir.assign %[[ARG1]] to %[[V0]]#0 : i32, !fir.ref<i32>
+!CHECK:   %[[V1:[0-9]+]] = fir.load %[[V0]]#0 : !fir.ref<i32>
+!CHECK:   %[[V2:[0-9]+]] = fir.convert %[[V1]] : (i32) -> f32
+!CHECK:   %[[V3:[0-9]+]] = fir.load %[[V0]]#0 : !fir.ref<i32>
+!CHECK:   %[[V4:[0-9]+]] = fir.convert %[[V3]] : (i32) -> i64
+!CHECK:   %[[V5:[0-9]+]] = hlfir.designate %3#0 (%[[V4]])  : (!fir.ref<!fir.array<10xf32>>, i64) -> !fir.ref<f32>
+!CHECK:   hlfir.assign %[[V2]] to %[[V5]] : f32, !fir.ref<f32>
+!CHECK:   omp.yield
+!CHECK: }
+
+program omp_cdir_codegen
+  implicit none
+  integer, parameter :: n = 10
+  real :: a(n)
+  integer :: i
+
+!$omp parallel do
+!dir$ unroll
+  do i = 1, n
+    a(i) = real(i)
+  end do
+!$omp end parallel do
+
+  print *, 'a(1)=', a(1), ' a(n)=', a(n)
+end program omp_cdir_codegen

Copy link
Contributor

@kiranchandramohan kiranchandramohan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LG. Thanks @kparzysz

@kparzysz kparzysz merged commit fd22706 into main Nov 25, 2025
12 of 13 checks passed
@kparzysz kparzysz deleted the users/kparzysz/directive-codegen-error branch November 25, 2025 23:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

flang:fir-hlfir flang:openmp flang Flang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Flang][OpenMP][Regression] OMP SIMD regression with compiler directives.

4 participants