[flang-commits] [flang] [flang][acc] Implement cache directive lowering (PR #174897)

via flang-commits flang-commits at lists.llvm.org
Fri Jan 9 08:43:55 PST 2026


================
@@ -3506,7 +3506,14 @@ class FirConverter : public Fortran::lower::AbstractConverter {
 
   void genFIR(const Fortran::parser::OpenACCConstruct &acc) {
     mlir::OpBuilder::InsertPoint insertPt = builder->saveInsertionPoint();
-    localSymbols.pushScope();
+
+    // Cache constructs should not push/pop a scope because they need to update
+    // the symbol map for subsequent statements in the same loop body.
----------------
jeanPerier wrote:

The remapping change is assuming that all the textually subsequent use of the symbol inside the compute region containing the acc cache are dominated by the acc cache directive, otherwise the compiler will likely crash and complain about use of non dominating SSA value.

I do not know how useful it is in OpenACC to have the cache directive to be inside some nested if-stmt or loop before the actual with the actual usage of the variable being after the loop/if, but I am a bit uneased by the fact that we are opening the gate to ICE on this kind of code that I do not think semantic is preventing.

Examples:

I think this one may cause an ICE, even though it is probably very unlikely user code.
```
subroutine test_cache_weird_if(a, b, cache)
  integer, parameter :: n = 10
  real, dimension(n) :: a, b
  logical :: cache
  integer :: i

  !$acc loop
  do i = 1, n
    if (cache) then
      !$acc cache(b)
    end if
    a(i) = b(i)
  end do
end subroutine
```

The example below with a loop will likely not cause an ICE given the a scope is pushed for the inner DoConstruct, so all the reference of the symbol after that inner do will refer to the original one. I guess the main care here would be to ensure the caching is not dead code eliminated and is performed (if it makes any sense). Anyway, if this one does not cause an ICE, it is not a blocker for your patch.

```
subroutine test_weird_cache()
  integer, parameter :: n = 1000, m = 100, l = 100
  real, dimension(n, m, l) :: a, b
  integer :: i

  !$acc loop
  do i = 1, n

    ! launch transfer of b(i,j,:) for every other j now to saturate data transfers
    do j = 1,m,2
      !$acc cache(b(i,m,:))
    end do

    ! Now start doing the copies
    do j = 1,m,2
      a(i, m, :) = b(i, m, :)
    end do

  end do
end subroutine
```


https://github.com/llvm/llvm-project/pull/174897


More information about the flang-commits mailing list