[all-commits] [llvm/llvm-project] 20d6cf: [flang][cuda] Share the managed companion pointer ...

Kareem Ergawy via All-commits all-commits at lists.llvm.org
Wed Sep 23 04:15:55 PDT 2026


  Branch: refs/heads/users/ergawy/managed-pointer-linkage
  Home:   https://github.com/llvm/llvm-project
  Commit: 20d6cfc2cad2d80a34a5af23b7c0ccf74d65bbf4
      https://github.com/llvm/llvm-project/commit/20d6cfc2cad2d80a34a5af23b7c0ccf74d65bbf4
  Author: ergawy <kareem.ergawy at gmail.com>
  Date:   2026-09-23 (Wed, 23 Sep 2026)

  Changed paths:
    M flang/lib/Optimizer/Transforms/CUDA/CUFAddConstructor.cpp
    M flang/test/Fir/CUDA/cuda-constructor-2.f90
    M flang/test/Fir/CUDA/cuda-managed-descriptor-component.fir
    A flang/test/Fir/CUDA/cuda-managed-pointer-linkage.cuf

  Log Message:
  -----------
  [flang][cuda] Share the managed companion pointer across translation units

A non-allocatable managed module variable is accessed through a companion
pointer in the `__nv_managed_data__` section, which the CUDA runtime fills in
with the unified memory address at module initialization. Every translation
unit referencing the variable emitted its own internal pointer and registered
it. The runtime populates only the registration performed first for a given
variable name (*), so every other unit was left loading through a null pointer and
crashed at run time.

Emit a single pointer with external linkage instead. The unit defining the
variable emits the definition, zero-initialized and in __nv_managed_data__,
and registers it; a unit that only USEs the variable emits a declaration and
no registration, resolving to that definition at link time.

(*) I verified this using the following reproducer:

`exp_mod.f90`:
```fortran
module m
  implicit none
  type :: t
    integer :: n
    real, allocatable, managed :: a(:)
  end type
  type(t) :: g
end module
```

`exp_use.f90`:
```fortran
program p
  use m
  allocate(g%a(4))
  g%n = 4
  print *, "n=", g%n, " size=", size(g%a)
end program
```
And the following sequence of events:
1. Compile each source individually to its `*.o` file.
2. Manually link the 2 object files:
  2.1. If we link `exp_mod.o exp_use.o` (object file that does actually
  use the global last), then we get a seg fault because the companion
  global is not initialized.
  2.2. If we reverse the linking order `exp_use.o exp_mod.o`, the
  companion pointer of the users object file get proper initialized and
  the binary does not seg fault.

If we add uses to both files, then we get a seg fault regradless of the
linking order.



To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications


More information about the All-commits mailing list