[flang-commits] [flang] [flang][OpenACC] Attach a source location to the skipped-directive warning (PR #224348)

Eugene Epshteyn via flang-commits flang-commits at lists.llvm.org
Thu Sep 17 08:58:03 PDT 2026


https://github.com/eugeneepshteyn created https://github.com/llvm/llvm-project/pull/224348

Follow-up to #223579.

## Summary

- The "compiler directive ignored: it appears between loop levels of a collapsed or tiled loop nest" warning was emitted with an unknown source location: directive evaluations are created without a `position` (`enterConstructOrDirective` in `flang/lib/Lower/PFTBuilder.cpp`), so `genLocation(e->position)` produced an unknown location and the warning printed as a bare `warning: ...` with no file or line — unactionable in any nontrivial file. Use the `CompilerDirective`'s own `source` instead, so the warning points at the ignored directive.
- Harden `flang/test/Lower/OpenACC/acc-loop-collapse-directive-between-loops.f90`:
  - a `WARN` FileCheck prefix pinning one *located* warning per skipped directive (four in the file) and, via `WARN-NOT`, that nothing else warns — this also pins that the `collapse(force:)` path stays silent;
  - a `collapse(force:2)` subroutine with a real statement and a directive between the levels — the `!collapseForce` carve-out in the descent is load-bearing (without it this shape would hit the "unsupported statement between the levels" TODO on code that semantic analysis accepts under `force`) and previously had no coverage;
  - exact `control(...)` arity on each `acc.loop` CHECK, so a regression that collapses fewer levels than requested (leaving a nested `fir.do_loop` with the body still inside the region and the clause-derived `collapse([n])` attribute still printed) can no longer pass.

## Test plan

- Verified the `WARN` block fails against the previous location-less warning and passes with the fix.
- `check-flang` Lower/OpenACC, Lower/CUDA, and Semantics/CUDA suites pass.


>From 9db452179ca9c0b9e79f76679f53c554c67e820b Mon Sep 17 00:00:00 2001
From: Eugene Epshteyn <eepshteyn at nvidia.com>
Date: Thu, 17 Sep 2026 08:50:21 -0700
Subject: [PATCH] [flang][OpenACC] Attach a source location to the
 skipped-directive warning

The 'compiler directive ignored' warning emitted when a directive appears
between the levels of a collapsed or tiled loop nest carried no source
location: directive evaluations are created without a position (see
enterConstructOrDirective in PFTBuilder.cpp), so genLocation(e->position)
produced an unknown location and the warning printed with no file or line.
Point it at the CompilerDirective's own source instead.

Also harden acc-loop-collapse-directive-between-loops.f90: check one located
warning per skipped directive (and none elsewhere), add a collapse(force:)
case with intervening code between the levels (the force carve-out in the
descent previously had no coverage), and pin the exact control(...) arity on
each acc.loop so a partial-collapse regression cannot pass.
---
 flang/lib/Lower/Bridge.cpp                    | 12 +++--
 ...-loop-collapse-directive-between-loops.f90 | 45 +++++++++++++++++--
 2 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 4af51dfb569f2..64fd597c7ad3f 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -3527,9 +3527,15 @@ class FirConverter : public Fortran::lower::AbstractConverter {
       if (e->isA<Fortran::parser::NonLabelDoStmt>())
         continue;
       if (e->isDirective()) {
-        mlir::emitWarning(genLocation(e->position),
-                          "compiler directive ignored: it appears between "
-                          "loop levels of a collapsed or tiled loop nest");
+        // Directive evaluations carry no position (enterConstructOrDirective
+        // in PFTBuilder.cpp creates them without one), so e->position maps to
+        // an unknown location; point the warning at the directive's own
+        // source text instead.
+        mlir::Location loc = genLocation(e->position);
+        if (const auto *dir = e->getIf<Fortran::parser::CompilerDirective>())
+          loc = genLocation(dir->source);
+        mlir::emitWarning(loc, "compiler directive ignored: it appears between "
+                               "loop levels of a collapsed or tiled loop nest");
         continue;
       }
       TODO(genLocation(e->position),
diff --git a/flang/test/Lower/OpenACC/acc-loop-collapse-directive-between-loops.f90 b/flang/test/Lower/OpenACC/acc-loop-collapse-directive-between-loops.f90
index e2e13c2ee2984..8d008f2aadd22 100644
--- a/flang/test/Lower/OpenACC/acc-loop-collapse-directive-between-loops.f90
+++ b/flang/test/Lower/OpenACC/acc-loop-collapse-directive-between-loops.f90
@@ -1,4 +1,5 @@
 ! RUN: bbc -fopenacc -emit-hlfir %s -o - | FileCheck %s
+! RUN: bbc -fopenacc -emit-hlfir %s -o %t 2>&1 | FileCheck %s --check-prefix=WARN
 
 ! Verify that a compiler directive (e.g. !DIR$ IVDEP) appearing between the
 ! levels of a collapsed loop nest does not get mistaken for the next nested
@@ -23,7 +24,7 @@ subroutine collapse2_directive_between_loops(n, a)
 
 ! CHECK-LABEL: func.func @_QPcollapse2_directive_between_loops(
 ! CHECK: acc.parallel
-! CHECK: acc.loop combined(parallel)
+! CHECK: acc.loop combined(parallel) {{.*}} control(%{{[^ ]+}} : i32, %{{[^ ]+}} : i32) =
 ! CHECK: hlfir.designate
 ! CHECK: hlfir.assign
 ! CHECK: acc.yield
@@ -48,7 +49,7 @@ subroutine collapse3_directive_between_loops(n, a)
 
 ! CHECK-LABEL: func.func @_QPcollapse3_directive_between_loops(
 ! CHECK: acc.parallel
-! CHECK: acc.loop combined(parallel)
+! CHECK: acc.loop combined(parallel) {{.*}} control(%{{[^ ]+}} : i32, %{{[^ ]+}} : i32, %{{[^ ]+}} : i32) =
 ! CHECK: hlfir.designate
 ! CHECK: hlfir.assign
 ! CHECK: acc.yield
@@ -76,7 +77,7 @@ subroutine collapse3_directive_between_inner_loops(n, a)
 
 ! CHECK-LABEL: func.func @_QPcollapse3_directive_between_inner_loops(
 ! CHECK: acc.parallel
-! CHECK: acc.loop combined(parallel)
+! CHECK: acc.loop combined(parallel) {{.*}} control(%{{[^ ]+}} : i32, %{{[^ ]+}} : i32, %{{[^ ]+}} : i32) =
 ! CHECK: hlfir.designate
 ! CHECK: hlfir.assign
 ! CHECK: acc.yield
@@ -99,7 +100,43 @@ subroutine tile_directive_between_loops(n, a)
 
 ! CHECK-LABEL: func.func @_QPtile_directive_between_loops(
 ! CHECK: acc.parallel
-! CHECK: acc.loop combined(parallel) {{.*}} tile(
+! CHECK: acc.loop combined(parallel) {{.*}} tile({{.*}} control(%{{[^ ]+}} : i32, %{{[^ ]+}} : i32) =
 ! CHECK: hlfir.designate
 ! CHECK: hlfir.assign
 ! CHECK: acc.yield
+
+! collapse(force: ...) explicitly allows intervening code between the loop
+! levels; the strict per-level descent (and its "directive ignored" warning)
+! must not run for it -- the force lowering sinks the prologue statements
+! (and the directive) into the collapsed body instead.
+subroutine collapse_force_stmt_between_loops(n, a, s)
+  integer, intent(in) :: n
+  integer :: a(n,n), s
+  integer :: i, j
+
+  !$acc parallel loop collapse(force:2) copy(a)
+  do i = 1, n
+    s = s + i
+!DIR$ IVDEP
+    do j = 1, n
+      a(j,i) = 1
+    end do
+  end do
+  !$acc end parallel loop
+end subroutine
+
+! CHECK-LABEL: func.func @_QPcollapse_force_stmt_between_loops(
+! CHECK: acc.parallel
+! CHECK: acc.loop combined(parallel) {{.*}} control(%{{[^ ]+}} : i32, %{{[^ ]+}} : i32) =
+! CHECK: hlfir.assign
+! CHECK: hlfir.assign
+! CHECK: acc.yield
+! CHECK: collapse([2])
+
+! One warning per skipped directive, each carrying the directive's source
+! location, in subroutine order; the force subroutine must not warn.
+! WARN: warning: loc("{{.*}}acc-loop-collapse-directive-between-loops.f90":{{[0-9]+}}:{{[0-9]+}}): compiler directive ignored: it appears between loop levels of a collapsed or tiled loop nest
+! WARN: warning: loc("{{.*}}acc-loop-collapse-directive-between-loops.f90":{{[0-9]+}}:{{[0-9]+}}): compiler directive ignored: it appears between loop levels of a collapsed or tiled loop nest
+! WARN: warning: loc("{{.*}}acc-loop-collapse-directive-between-loops.f90":{{[0-9]+}}:{{[0-9]+}}): compiler directive ignored: it appears between loop levels of a collapsed or tiled loop nest
+! WARN: warning: loc("{{.*}}acc-loop-collapse-directive-between-loops.f90":{{[0-9]+}}:{{[0-9]+}}): compiler directive ignored: it appears between loop levels of a collapsed or tiled loop nest
+! WARN-NOT: compiler directive ignored



More information about the flang-commits mailing list