446 Commits

Author SHA1 Message Date
Sunil Shrestha
205ee34317
[flang][openmp] Fix GPU byref reduction descriptor initialization (#178934)
When generating GPU reduction code for arrays passed by reference, only
the base_ptr field was initialized in the shuffled descriptor, leaving
extent, stride, and rank fields uninitialized. This caused garbage
metadata to be passed to user reduction combiners, resulting in
incorrect iteration bounds and crashes on GPU targets.

Fix by copying the entire source descriptor and then updating the
base_ptr to point to thread-private storage. This preserves all metadata
(extents, strides, rank) while correctly pointing to the shuffled data
location.

The fix applies to three reduction helper functions:
- _omp_reduction_shuffle_and_reduce_func (warp-level shuffle)
- _omp_reduction_list_to_global_reduce_func (block-to-global)
- _omp_reduction_global_to_list_copy_func (global-to-block)

Fixes multi-dimensional array reductions on GPU target regions with
teams distribute parallel for directives.

Co-authored-by: Sunil Shrestha <sshrestha@pe28vega.hpc.amslabs.hpecorp.net>
2026-02-05 11:26:44 +01:00
Jack Styles
8949c6d86b
[MLIR][OpenMP] Add Taskloop Collapse Support (#175924)
Following work completed in #174386 and #174623, this patch adds support
for collapse to Taskloop. Collapse allows for the user to compress
multiple loop nests into a single loop, and for this to work with
Taskloop, there needs to be some changes to how we process the loops,
and the tasks that run them.

This patch brings Taskloop equivalent to OpenMP 4.5 support for MLIR and
Flang.
2026-02-05 08:59:00 +00:00
Jack Styles
f95b63b7e6
[llvm][OpenMP] Allow Chunk Size on SIMD Guided (#178853)
As per the OpenMP Spec, Chunk Size is allowed when using the guided
kind-type with the schedule clause. However, when being used in cases
such as `!$omp do simd schedule (simd:guided,4)`, this was not allowed
as the base type, BaseGuidedSimd, would hit an assert not allowing
ChunkSizes.

By making this change, we can allow the use of the Guided type, with a
ChunkSize and the schedule clause when using OMPIRBuidler.

Fixes #82106
2026-02-03 09:27:55 +00:00
Nikita Popov
fd1e37b653
[IR] Remove Before argument from splitBlock APIs (NFC) (#179195)
We never need to use this conditionally (and it doesn't really make
sense, as the behavior is substantially different). Force the use of
separate APIs instead of a boolean argument.
2026-02-02 10:50:58 +00:00
Sergio Afonso
4cc80831ea
[MLIR][OpenMP] Simplify OpenMP device codegen (#137201)
After removing host operations from the device MLIR module, it is no
longer necessary to provide special codegen logic to prevent these
operations from causing compiler crashes or miscompilations.

This patch removes these now unnecessary code paths to simplify codegen
logic. Some MLIR tests are now replaced with Flang tests, since the
responsibility of dealing with host operations has been moved earlier in
the compilation flow.

MLIR tests holding target device modules are updated to no longer
include now unsupported host operations.
2026-01-29 12:44:40 +00:00
Abhinav Gaba
339f779570
Reland "[OpenMP][Mappers] Fix ref-count tracking for maps inserted by mappers. (#177059)" (#177673)
This reverts commit 5a457837dd988aa01c65820848381a5b99a74c0a.

Includes the test fix from
https://github.com/llvm/llvm-project/pull/177659.

The test had to be updated to exclude a scenario that was failing
with/without the change (involving mapping a struct with a byref member
with a mapper).

-----
**Original PR's description:**

This is a fix for https://github.com/llvm/llvm-project/issues/61636.

Ravi had this implemented downstream before he retired. This PR is a
chery-pick of that.

The test is taken from @jdoerfert's WIP change in

527bf4b129.

The change partially undoes the changes done in
0caf736d7e1d16d1059553fc28dbac31f0b9f788, so @alexey-bataev might need
to take a look.
2026-01-27 15:31:16 -08:00
Abhinav Gaba
5a457837dd
Revert "[OpenMP][Mappers] Fix ref-count tracking for maps inserted by mappers. (#177059)" (#177623)
Reverts llvm/llvm-project#177059 and llvm/llvm-project#177491.

The new test may have an issue.
2026-01-23 12:02:44 -08:00
Abhinav Gaba
a7b57cf7bb
[OpenMP][Mappers] Fix ref-count tracking for maps inserted by mappers. (#177059)
This is a fix for https://github.com/llvm/llvm-project/issues/61636.

Ravi had this implemented downstream before he retired. This PR is a
chery-pick of that.

The test is taken from @jdoerfert's WIP change in

527bf4b129.

The change partially undoes the changes done in
0caf736d7e1d16d1059553fc28dbac31f0b9f788, so @alexey-bataev might need
to take a look.

---------

Co-authored-by: Ravi Narayanaswamy <ravi.narayanaswamy@intel.com>
Co-authored-by: Johannes Doerfert <johannes@jdoerfert.de>
2026-01-22 15:10:00 -08:00
Simon Pilgrim
d7078b6737
OMPIRBuilder.cpp - fix gcc Wparentheses warning. NFC. (#177403) 2026-01-22 17:33:28 +00:00
Michael Klemm
9f19d1895d
[OpenMP] Fix truncation/extension bug when calling __kmpc_push_num_teams (#173067)
This PR fixes a bug when the lower and upper bound for the number of
teams was not an `int32`, but a different type. In this case, an
internal compiler would trigger due to a mismatching call to
`__kmpc_push_num_teams`.
2026-01-19 11:20:11 +01:00
Austin Jiang
e6cdfb75ac
Fix typos and spelling errors across codebase (#156270)
Corrected various spelling mistakes such as 'occurred', 'receiver',
'initialized', 'length', and others in comments, variable names,
function names, and documentation throughout the project. These
changes improve code readability and maintain consistency in naming
and documentation.

Co-authored-by: Louis Dionne <ldionne.2@gmail.com>
2026-01-13 11:52:46 -05:00
Jack Styles
b7c17ab957
[MLIR][OpenMP] Add Initial Taskloop Clause Support (#174623)
Following on from the work to implement MLIR -> LLVM IR Translation for
Taskloop, this adds support for the following clauses to be used
alongside taskloop:
- if
- grainsize
- num_tasks
- untied
- Nogroup
- Final
- Mergeable
- Priority

These clauses are ones which work directly through the relevant OpenMP
Runtime functions, so their information just needed collecting from the
relevant location and passing through to the appropriate runtime
function.

Remaining clauses retain their TODO message as they have not yet been
implemented.
2026-01-09 10:34:03 +00:00
Tom Eccles
1af1cc21c8
[mlir][OpenMP] Translation support for taskloop construct (#174386)
This PR replaces #166903

This implements translation for taskloop, along with DSA clauses. Other
clauses will follow immediately after this is merged.

This patch was collaborative work by myself, @kaviya2510, and
@Stylie777. I’ve left the commits unsquashed to make authorship clear.
My only changes to other author’s commits are to rebase and run
clang-format.

The taskloop implementation in the runtime works roughly like this: if
the number of loop iterations to perform are more than some threshold,
the current task is duplicated and both resulting tasks gets half of the
loop range. This continues recursively until each task has a small
enough loop range to run itself in a single thread.

This leads to two implementation complexities:
- The runtime needs to be able to update the loop bounds used when
executing the loop inside of the task. This has been implemented by
forcing them to always have a fixed location inside of the structure
produced when outlining the task.
- When a task is duplicated, all data stored for the task’s
(first)private variables needs to also be duplicated and appropriate
constructors run. This is handled by a task duplication function invoked
by the runtime.

With regards to testing, most existing tests in the gfortran and fujitsu
test suites require the reduction clause (not part of OpenMP 4.5). I
wrote some tests of my own and was satisfied that it seems to be
working.

Co-authored-by: Kaviya Rajendiran <kaviyara2000@gmail.com>
Co-authored-by: Jack Styles <jack.styles@arm.com>

---------

Co-authored-by: Kaviya Rajendiran <kaviyara2000@gmail.com>
Co-authored-by: Jack Styles <jack.styles@arm.com>
2026-01-08 11:08:13 +00:00
Chi-Chun, Chen
3f5d91bfbc
[Flang][OpenMP] Implement device clause lowering for target directive (#173509)
Add lowering support for the OpenMP `device` clause on the `target`
directive in Flang.

The device expression is propagated through MLIR OpenMP and passed to
the host-side `__tgt_target_kernel` call.
2026-01-06 11:10:03 -06:00
Jason-VanBeusekom
7a174c91f3
[OpenMP][clang] Register Vtables on device for indirect calls (#159856) 2026-01-05 13:25:03 -05:00
Kareem Ergawy
dae453ac2a
[OpenMP][OMPIRBuilder] Hoist static parallel region allocas to the entry block on the CPU (#174314)
Follow-up on #171597, this PR hoists allocas in a parallel region to the
entry block of its corresponding outlined function. This PR does this
for the CPU while #171597 introduced the main mechanism to do so and did
it for the GPU.
2026-01-05 07:59:19 +01:00
Kareem Ergawy
ccb47d0fb9
[OpenMP][MLIR] Hoist static allocas emitted by private init regions to the allocation IP of the construct (#171597)
Having more than 1 descritpr (allocatable or array) on the same
`private` clause triggers a runtime crash on GPUs at the moment.

For SPMD kernels, the issue happens because the initialization logic
includes:
* Allocating a number of temporary structs (these are emitted by flang
when `fir` is lowered to `mlir.llvm`).
* There is a conditional branch that determines whether we will allocate
storage for the descriptor and initialize array bounds from the original
descriptor or whether we will initialize the private descriptor to null.

Because of these 2 things, temp allocations needed for descriptors
beyond the 1st one are preceded by branching which causes the observed
the runtime crash.

This PR solves this issue by hoisting these static `alloca`s
instructions to the suitable allca IP of the parent construct.
2026-01-05 06:39:52 +01:00
Abhinav Gaba
1fbf33cd40
[OpenMP][Clang] Use ATTACH map-type for list-items with base-pointers. (#153683)
This adds support for using `ATTACH` map-type for proper
pointer-attachment when mapping list-items that have base-pointers.

For example, for the following:

```c
  int *p;
  #pragma omp target enter data map(p[1:10])
```

The following maps are now emitted by clang:
```
  (A)
  &p[0], &p[1], 10 * sizeof(p[1]), TO | FROM
  &p, &p[1], sizeof(p), ATTACH
```

Previously, the two possible maps emitted by clang were:
```
  (B)
  &p[0], &p[1], 10 * sizeof(p[1]), TO | FROM

  (C)
  &p, &p[1], 10 * sizeof(p[1]), TO | FROM | PTR_AND_OBJ
````

(B) does not perform any pointer attachment, while (C) also maps the
pointer p, both of which are incorrect.

-----

With this change, we are using ATTACH-style maps, like `(A)`, for cases
where the expression has a base-pointer. For example:


```cpp
  int *p, **pp;
  S *ps, **pps;
  ... map(p[0])
  ... map(p[10:20])
  ... map(*p)
  ... map(([20])p)
  ... map(ps->a)
  ... map(pps->p->a)
  ... map(pp[0][0])
  ... map(*(pp + 10)[0])

```

#### Grouping of maps based on attach base-pointers
We also group mapping of clauses with the same base decl in the order of
the increasing complexity of their base-pointers, e.g. for something
like:
```
  S **spp;
  map(spp[0][0], spp[0][0].a), // attach-ptr: spp[0]
  map(spp[0]),                 // attach-ptr: spp
  map(spp),                    // attach-ptr: N/A
```

We first map `spp`, then `spp[0]` then `spp[0][0]` and `spp[0][0].a`.

This allows us to also group "struct" allocation based on their attach
pointers. This resolves the issues of us always mapping everything from
the beginning of the symbol `spp`. Each group is mapped independently,
and at the same level, like `spp[0][0]` and its member `spp[0][0].a`, we
still get map them together as part of the same contiguous struct
`spp[0][0]`. This resolves issue #141042.

#### use_device_ptr/addr fixes
The handling of `use_device_ptr/addr` was updated to use the attach-ptr
information, and works for many cases that were failing before. It has
to be done as part of this series because otherwise, the switch from
ptr_to_obj to attach-style mapping would have caused regressions in
existing use_device_ptr/addr tests.

#### Handling of attach-pointers that are members of implicitly mapped
structs:
* When a struct member-pointer, like `p` below, is a base-pointer in a
`map` clause on a target construct (like `map(p[0:1])`, and the base of
that struct is either the `this` pointer (implicitly or explicitly), or
a struct that is implicitly mapped on that construct, we add an implicit
`map(p)` so that we don't implicitly map the full struct.
 ```c
  struct S { int *p;
  void f1() {
    #pragma omp target map(p[0:1]) // Implicitly map this->p, to ensure
// that the implicit map of `this[:]` does
                                   // not map the full struct
       printf("%p %p\n", &p, p);
  }
 ```

#### Scope for improvement:
* We may be able to compute attach-ptr expr while collecting
component-lists in Sema.
* But we cache the computation results already, and `findAttachPtrExpr`
is fairly simple, and fast.
* There may be a better way to implement semantic expr comparison.

#### Needs future work:
* Attach-style maps not yet emitted for declare mappers.
* Mapping of class member references: We are still using PTR_AND_OBJ
maps for them. We will likely need to change that to handle
`ref_ptr/ref_ptee`, and `attach` map-type-modifier on them.
* Implicit capturing of "this" needs to map the full `this[0:1]` unless
there is an explicit map on one of the members, or a map with a member
as its base-pointer.
* Implicit map added for capturing a class member pointer needs to also
add a zero-length-array-section map.
* `use_device_addr` on array-sections-on-pointers need further
improvements (documented using FIXMEs)

#### Why a large PR
While it's unfortunate that this PR has gotten large and difficult to
review, the issue is that all the functional changes have to be made
together, to prevent regressions from partially implemented changes.

For example, the changes to capturing were previously done separately
(#145454), but they would still cause stability issues in absence of
full attach-mapping. And attach-mapping needs those changes to be able
to launch kernels.

We extracted the utilities and functions, like those for finding
attach-ptrs, or comparing exprs, out as a separate NFC PR that doesn't
call those functions, just adds them (#155625). Maybe the change that
adds a new error message for use_device_addr on array-sections with
non-var base-pointers could have been extracted out too (but that would
have had to be a follow-up change in that case, and we would get
comp-fails with this PR when the erroneous case was not
caught/diagnosed).

---------

Co-authored-by: Alex Duran <alejandro.duran@intel.com>
2025-12-15 16:40:31 -08:00
Mikael Holmen
f90fe01f85
[OpenMP] Fix -Wparentheses warning [NFC]
Without this gcc warned
 ../lib/Frontend/OpenMP/OMPIRBuilder.cpp:5082:45: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
2025-12-09 14:48:59 +01:00
Kevin Sala Penades
0e92beb0c0
[Clang][OpenMP] Switch to __kmpc_parallel_60 with strict parameter (#171082)
This commit switches the `__kmpc_parallel_51` to `__kmpc_parallel_60`,
and adds the strict boolean for the number of threads.
2025-12-08 09:37:11 -08:00
Michael Klemm
8c8074f0fa
[Flang][OpenMP] Fix OpenMP static scheduling when trip count is zero (#170863)
Code-gen produced incorrect code for cases when the trip count an
associated DO loop was zero. The generated code evaluated the trip count
of the loop and substracted 1 from it. When this was passed to
__kmpc_for_static_init_4u, the value was interpreted as unsigned, which
made the upper bound of the worksharing loop 2^32-1 and caused a
division by zero in the calculation of the loop bounds for the threads.
2025-12-08 18:29:02 +01:00
Jack Styles
e5603da73d
[mlir][OpenMP] Fix assert in processing of dist_schedule (#170269)
When #152736 was initially merged, the assert that checks for the
chunksize when applying a static-chunked schedule was incorrect. While
it would not have changed the behaviour of the assert, the string
attached to it would have been emitted in cases where it was simplified.

This was raised here:
https://github.com/llvm/llvm-project/pull/152736#discussion_r2578314276

Testing for this was explored, but this assert is a last chance failure
point that should never be reached as applyWorkshareLoop decides the
`EffectiveScheduleType` based on the existence of `ChunkSize` or
`DistScheduleChunkSize`, so this will only trigger if there are issues
with that conversion, and UnitTesting already exists for
`applyWorkshareLoop`
2025-12-04 10:00:09 +00:00
Kareem Ergawy
867d353cff
[OpenMP][flang] Support GPU team-reductions on allocatables (#169651)
Extends the work started in #165714 by supporting team reductions.
Similar to what was done in #165714, this PR introduces proper
allocations, loads, and stores for by-ref reductions in teams-related
callbacks:
* `_omp_reduction_list_to_global_copy_func`,
* `_omp_reduction_list_to_global_reduce_func`,
* `_omp_reduction_global_to_list_copy_func`, and
* `_omp_reduction_global_to_list_reduce_func`.
2025-12-02 05:20:10 +01:00
Tom Eccles
bf22687c48
[OMPIRBuilder] CANCEL IF(FALSE) is still a cancellation point (#170095)
From OpenMP 4.0:

> When an if clause is present on a cancel construct and the if
expression
> evaluates to false, the cancel construct does not activate
cancellation.
> The cancellation point associated with the cancel construct is always
> encountered regardless of the value of the if expression.

This wording is retained unmodified in OpenMP 6.0.

This re-opens the already approved PR #164587, which was closed by
accident. The only changes are a rebase.
2025-12-01 11:23:14 +00:00
Tom Eccles
8ec2112ec8
[OMPIRBuilder] re-land cancel barriers patch #164586 (#169931)
A barrier will pause execution until all threads reach it. If some go to
a different barrier then we deadlock. This manifests in that the
finalization callback must only be run once. Fix by ensuring we always
go through the same finalization block whether the thread in cancelled
or not and no matter which cancellation point causes the cancellation.

The old callback only affected PARALLEL, so it has been moved into the
code generating PARALLEL. For this reason, we don't need similar changes
for other cancellable constructs. We need to create the barrier on the
shared exit from the outlined function instead of only on the cancelled
branch to make sure that threads exiting normally (without cancellation)
meet the same barriers as those which were cancelled. For example,
previously we might have generated code like

```
...
  %ret = call i32 @__kmpc_cancel(...)
  %cond = icmp eq i32 %ret, 0
  br i1 %cond, label %continue, label %cancel

continue:
  // do the rest of the callback, eventually branching to %fini
  br label %fini

cancel:
  // Populated by the callback:
  // unsafe: if any thread makes it to the end without being cancelled
  // it won't reach this barrier and then the program will deadlock
  %unused = call i32 @__kmpc_cancel_barrier(...)
  br label %fini

fini:
  // run destructors etc
  ret
```

In the new version the barrier is moved into fini. I generate it *after*
the destructors because the standard describes the barrier as occurring
after the end of the parallel region.

```
...
  %ret = call i32 @__kmpc_cancel(...)
  %cond = icmp eq i32 %ret, 0
  br i1 %cond, label %continue, label %cancel

continue:
  // do the rest of the callback, eventually branching to %fini
  br label %fini

cancel:
  br label %fini

fini:
  // run destructors etc
  // safe so long as every exit from the function happens via this block:
  %unused = call i32 @__kmpc_cancel_barrier(...)
  ret
```

To achieve this, the barrier is now generated alongside the finalization
code instead of in the callback. This is the reason for the changes to
the unit test.

I'm unsure if I should keep the incorrect barrier generation callback
only on the cancellation branch in clang with the OMPIRBuilder backend
because that would match clang's ordinary codegen. Right now I have
opted to remove it entirely because it is a deadlock waiting to happen.

---

This re-lands #164586 with a small fix for a failing buildbot running
address sanitizer on clang lit tests.

In the previous version of the patch I added an insertion point guard
"just to be safe" and never removed it. There isn't insertion point
guarding on the other route out of this function and we do not
preserve the insertion point around getFiniBB either so it is not
needed here.

The problem flagged by the sanitizers was because the saved insertion
point pointed to an instruction which was then removed inside the FiniCB
for some clang codegen functions. The instruction was freed when it was
removed. Then accessing it to restore the insertion point was a use
after free bug.
2025-12-01 10:07:19 +00:00
Tom Eccles
58fa7e4ccd
Revert "[OMPIRBuilder] always leave PARALLEL via the same barrier" (#169829)
Reverts llvm/llvm-project#164586

Reverting due to buildbot failure:
https://lab.llvm.org/buildbot/#/builders/169/builds/17519
2025-11-27 16:19:52 +00:00
Jack Styles
47ae3eaa29
[MLIR][OpenMP] Add MLIR Lowering Support for dist_schedule (#152736)
`dist_schedule` was previously supported in Flang/Clang but was not
implemented in MLIR, instead a user would get a "not yet implemented"
error. This patch adds support for the `dist_schedule` clause to be
lowered to LLVM IR when used in an `omp.distribute` or `omp.wsloop`
section.

There has needed to be some rework required to ensure that MLIR/LLVM
emits the correct Schedule Type for the clause, as it uses a different
schedule type to other OpenMP directives/clauses in the runtime library.

This patch also ensures that when using dist_schedule or a chunked
schedule clause, the correct llvm loop parallel accesses details are
added.
2025-11-27 14:16:44 +00:00
Tom Eccles
0e5633fcd9
[OMPIRBuilder] always leave PARALLEL via the same barrier (#164586)
A barrier will pause execution until all threads reach it. If some go to
a different barrier then we deadlock. This manifests in that the
finalization callback must only be run once. Fix by ensuring we always
go through the same finalization block whether the thread in cancelled
or not and no matter which cancellation point causes the cancellation.

The old callback only affected PARALLEL, so it has been moved into the
code generating PARALLEL. For this reason, we don't need similar changes
for other cancellable constructs. We need to create the barrier on the
shared exit from the outlined function instead of only on the cancelled
branch to make sure that threads exiting normally (without cancellation)
meet the same barriers as those which were cancelled. For example,
previously we might have generated code like

```
...
  %ret = call i32 @__kmpc_cancel(...)
  %cond = icmp eq i32 %ret, 0
  br i1 %cond, label %continue, label %cancel

continue:
  // do the rest of the callback, eventually branching to %fini
  br label %fini

cancel:
  // Populated by the callback:
  // unsafe: if any thread makes it to the end without being cancelled
  // it won't reach this barrier and then the program will deadlock
  %unused = call i32 @__kmpc_cancel_barrier(...)
  br label %fini

fini:
  // run destructors etc
  ret
```

In the new version the barrier is moved into fini. I generate it *after*
the destructors because the standard describes the barrier as occurring
after the end of the parallel region.

```
...
  %ret = call i32 @__kmpc_cancel(...)
  %cond = icmp eq i32 %ret, 0
  br i1 %cond, label %continue, label %cancel

continue:
  // do the rest of the callback, eventually branching to %fini
  br label %fini

cancel:
  br label %fini

fini:
  // run destructors etc
  // safe so long as every exit from the function happens via this block:
  %unused = call i32 @__kmpc_cancel_barrier(...)
  ret
```

To achieve this, the barrier is now generated alongside the finalization
code instead of in the callback. This is the reason for the changes to
the unit test.

I'm unsure if I should keep the incorrect barrier generation callback
only on the cancellation branch in clang with the OMPIRBuilder backend
because that would match clang's ordinary codegen. Right now I have
opted to remove it entirely because it is a deadlock waiting to happen.
2025-11-27 14:13:25 +00:00
Kareem Ergawy
f481f5bef9
[OpenMP][flang] Add initial support for by-ref reductions on the GPU (#165714)
Adds initial support for GPU by-ref reductions. The main problem for
reduction by reference is that, prior to this PR, we were shuffling
(from remote lanes within the same warp or across different warps within
the block) pointers/references to the private reduction values rather
than the private reduction values themselves.

In particular, this diff adds support for reductions on scalar
allocatables where reductions happen on loops nested in `target`
regions. For example:

```fortran
  integer :: i
  real, allocatable :: scalar_alloc

  allocate(scalar_alloc)
  scalar_alloc = 0

  !$omp target map(tofrom: scalar_alloc)
  !$omp parallel do reduction(+: scalar_alloc)
  do i = 1, 1000000
    scalar_alloc = scalar_alloc + 1
  end do
  !$omp end target
```

This PR supports by-ref reductions on the intra- and inter-warp levels.

So far, there are still steps to be takens for full support of by-ref
reductions, for example:
* Support inter-block value combination is still not supported.
Therefore, `target teams distribute parallel do` is still not supported.
* Support for dynamically-sized arrays still needs to be added.
* Support for more than one allocatable/array on the same `reduction`
clause.
2025-11-26 11:59:22 +01:00
Nick Sarnie
4538818c79
[OpenMP][OMPIRBuilder] Use runtime CC for runtime calls (#168608)
Some targets have a specific calling convention that should be used for
generated calls to runtime functions.

Pass that down and use it.

Signed-off-by: Nick Sarnie <nick.sarnie@intel.com>
2025-11-21 15:40:20 +00:00
Nick Sarnie
ae5036681c
[OMPIRBuilder] Use AS 0 for internal variables for AMDGPU (#167377)
We see some libomptarget test failures if we use the default global AS.

See https://github.com/llvm/llvm-project/pull/166459 for more info.

Signed-off-by: Nick Sarnie <nick.sarnie@intel.com>
2025-11-10 19:33:17 -08:00
Kevin Sala Penades
540250ca7a
[OpenMP][Clang] Add codegen support for dyn_groupprivate clause (#152830)
This adds the codegen support for the dyn_groupprivate clause.
2025-11-10 13:11:03 -08:00
Nick Sarnie
c17a839d83
[OMPIRBuilder] Fix addrspace of internal critical section lock (#166459)
First, for internal variables, they are always global, so use the global
AS by default unless specified otherwise. We can't really use `0` as a
default like we do now because that has an actual meaning on some
targets, so we really need specified vs unspecified, so I used
`std::optional` which is already used in many places in OMPIRBuilder.

Second, for the critical lock variable, add an addrspace cast if needed.

Signed-off-by: Nick Sarnie <nick.sarnie@intel.com>
2025-11-10 15:12:13 +00:00
Kazu Hirata
902b0bd04a
[llvm] Remove "const" in the presence of "constexpr" (NFC) (#166109)
"const" is extraneous in the presence of "constexpr" for simple
variables and arrays.
2025-11-02 15:52:44 -08:00
Krish Gupta
22a10c8c21
[OpenMP][Flang] Fix atomic operations on complex types (#165366)
Fixes https://github.com/llvm/llvm-project/issues/165184

In OMPIRBuilder::createAtomicRead() and createAtomicWrite(), the size
parameter for __atomic_load/__atomic_store was incorrectly computed
from the pointer type instead of the pointee (element) type.

On 64-bit systems, this resulted in only 8 bytes being transferred
regardless of the actual struct size.

Changed both functions to use XElemTy (element type) instead of the
pointer type when computing LoadSize. This ensures the full struct
is transferred.
2025-10-29 08:55:52 -05:00
Nick Sarnie
d59f7f2717
[clang][OMPIRBuilder] Fix reduction codegen for SPIR-V (#162529)
When creating function pointers, make sure the pointer is in the program
address space.

Also fix a spot where I forgot to set `setDefaultTargetAS` and one spot
where we didn't use the default AS for a pointer.

---------

Signed-off-by: Sarnie, Nick <nick.sarnie@intel.com>
2025-10-09 14:25:36 +00:00
Jan Svoboda
c580ad488e
[clang] Use the VFS to create the OpenMP region entry ID (#160918)
This PR uses the VFS to create the OpenMP target entry instead of going
straight to the real file system. This matches the behavior of other
input files of the compiler.
2025-09-26 12:25:37 -07:00
Dominik Adamski
83ef38a274
[Flang][OpenMP] Enable no-loop kernels (#155818)
Enable the generation of no-loop kernels for Fortran OpenMP code. target
teams distribute parallel do pragmas can be promoted to no-loop kernels
if the user adds the -fopenmp-assume-teams-oversubscription and
-fopenmp-assume-threads-oversubscription flags.

If the OpenMP kernel contains reduction or num_teams clauses, it is not
promoted to no-loop mode.

The global OpenMP device RTL oversubscription flags no longer force
no-loop code generation for Fortran.
2025-09-26 13:57:51 +02:00
Tom Eccles
6f02969164
[OMPIRBuilder] Don't outline DISTRIBUTE on CPUs (#158317)
We use different OpenMP runtime functions on CPU and target offload. The
one used for DISTRIBUTE on target offload needs a function pointer to an
offloaded function, but the one on CPU doesn't. This caused unnessecary
overhead on CPUs because SHARED or FIRSTPRIVATE memory from the
surrounding context has to be packaged into a context structure just for
an ordinary function call (which would hopefully eventually get
inlined). This also makes the IR harder to read.
2025-09-23 11:09:13 +01:00
Kareem Ergawy
2ab02b6f56
[flang][OpenMP] Support multi-block reduction combiner regions on the GPU (#156837)
Fixes a bug related to insertion points when inlining multi-block
combiner reduction regions. The IP at the end of the inlined region was
not used resulting in emitting BBs with multiple terminators.

PR stack:
- https://github.com/llvm/llvm-project/pull/155754
- https://github.com/llvm/llvm-project/pull/155987
- https://github.com/llvm/llvm-project/pull/155992
- https://github.com/llvm/llvm-project/pull/155993
- https://github.com/llvm/llvm-project/pull/157638
- https://github.com/llvm/llvm-project/pull/156610
- https://github.com/llvm/llvm-project/pull/156837 ◀️
2025-09-23 08:32:31 +02:00
agozillon
046d6a3998
[Flang][OpenMP] Additional global address space modifications for device (#119585)
A prior PR added a portion of the global address space modifications
required for declare target to, this PR seeks to add
 a small amount more leftover from that PR.
   
The intent is to allow for more correct IR that the backends (in
particular AMDGPU) can treat more aptly for optimisations and code
correctness
    
1/3 required PRs to enable declare target to mapping, should look at PR
3/3 to check for full green passes (this one will fail a number due to
some dependencies).
    
Co-authored-by: Raghu Maddhipatla raghu.maddhipatla@amd.com
2025-09-17 03:27:03 +02:00
Nick Sarnie
c7acd0796c
[clang][OMPIRBuilder] Use default target AS to create types (#158152)
Currently we assume that `0` is the default AS, which is usually true,
but it isn't for `SPIR-V`.

Pass down the AS from `clang` and use it to create types.

After this change, we finally generate fully valid SPIR-V for a basic
OpenMP Offloading example.

Signed-off-by: Sarnie, Nick <nick.sarnie@intel.com>
2025-09-15 15:11:38 +00:00
Jan Svoboda
d1c0b1b620
[clang] Use VFS for -fopenmp-host-ir-file-path (#156727)
This is a follow-up to #150124. This PR makes it so that the
`-fopenmp-host-ir-file-path` respects VFS overlays, like any other input
file.
2025-09-11 09:08:47 -07:00
Nick Sarnie
e6c63d920d
[OMPIRBuilder] Use target global AS for SrcLocStr (#156520)
We should set the correct target-specific AS for the SrcLocStr global
created in OMPIRBuilder.

We also may have to insert a constexpr addrspacecast because the struct
field type may be different than the value used to initialize it.

I actually want the cast to be from AS 1 to AS 4, but getting the type
to be AS4 relies on a PR currently in-review, so leave the cast target
to AS 0 for now.

---------

Signed-off-by: Sarnie, Nick <nick.sarnie@intel.com>
2025-09-03 14:35:33 +00:00
Abid Qadeer
cea2c8625e
[OMPIRBuilder][Debug] Remove unnecessary code. (#156468)
In the code that fix ups the debug information, we handles both the
debug intrinsics and debug records. The debug intrinsics are being
phased out and I recently changed mlir translation to not generate them.
This means that we should not get debug intrinsics anymore and code can
be simplified by removing their handling.
2025-09-02 21:09:36 +01:00
Abid Qadeer
4159fd819a
[OMPIRBuilder] Avoid crash in BasicBlock::splice. (#154987)
Calling `BasicBlock::splice` in `spliceBB` when both `Old` and `New` are
empty is a `nop` currently but it can cause a crash once debug records
are used instead of debug intrinsics. This PR makes the call conditional
on at least one of `Old` or `New` being non-empty.

Consider the following mlir:
```
omp.target map_entries() {
  llvm.intr.dbg.declare ...
  llvm.intr.dbg.declare ...
  omp.teams ...
  ...
}
```

Current code would translate llvm.intr Ops to llvm intrinsics. Old is
the BasicBlock where they were get inserted and it will have 2 llvm
debug intrinsics by the time the implementation of `omp.teams` starts.
This implementation creates many BasicBlocks by calling `splitBB`. The
`New` is the just created BasicBlock which is empty.

In the new scheme (using debug records), there will be no instruction in
the `Old` BB after llvm.intr Ops get translated but just 2 trailing
debug records. So both `Old` and `New` are empty. When control reaches
`BasicBlock::splice`, it calls `spliceDebugInfoEmptyBlock`. This
function expects that in this case (`Src` is empty but has trailing
debug records), the `ToIt` is valid and it can call `adoptDbgRecords` on
it. This assumption is not true in this case as `New` is empty and
`ToIt` is pointing to end(). The fix is to only call
`BasicBlock::splice` when at least of `Old` or `New` is not empty.
2025-08-29 16:56:26 +01:00
Michael Kruse
e9a27a3a75
[OpenMPIRBuilder] Fix tripcount not a multiple of tile size (#154999)
The emitted code tests whether the current tile should executing the
remainder iterations by checking the logical iteration number is the one
after the floor iterations that execute the non-remainder iterations.
There are two counts of how many iterations there are: Those of
non-remainder iterations (simply rounded-down division of tripcount and
tile size), and those including an additional floor iteration for the
remainder iterations. The code was used the wrong one that caused the
condition to never match.
2025-08-26 11:30:42 +02:00
Kazu Hirata
11b4f110e0
[llvm] Remove unused includes of SmallSet.h (NFC) (#154893)
We just replaced SmallSet<T *, N> with SmallPtrSet<T *, N>, bypassing
the redirection found in SmallSet.h.  With that, we no longer need to
include SmallSet.h in many files.
2025-08-22 10:33:46 -07:00
Dominik Adamski
b69fd34e76
[Offload] Add oneInterationPerThread param to loop device RTL (#151959)
Currently, Flang can generate no-loop kernels for all OpenMP target
kernels in the program if the flags
-fopenmp-assume-teams-oversubscription or
-fopenmp-assume-threads-oversubscription are set.
If we add an additional parameter, we can choose
in the future which OpenMP kernels should be generated as no-loop
kernels.

This PR doesn't modify current behavior of oversubscription flags.

RFC for no-loop kernels:
https://discourse.llvm.org/t/rfc-no-loop-mode-for-openmp-gpu-kernels/87517
2025-08-21 09:03:56 +02:00
Jim Lin
174135863f [OMPIRBuilder] Use CreateNUWMul instead of passing flags to CreateMul. NFC 2025-08-20 17:00:17 +08:00