[Flang][OpenMP] Fix crash and IR errors for user-defined reduction on allocatable variables (#186765)
Fixes - https://github.com/llvm/llvm-project/issues/186743
This patch fixes flang crashes and invalid IR when using user-defined
reductions (declare reduction) with allocatable variables (scalars, 1D,
2D arrays). Previously, flang would either crash during FIR lowering or
emit bad LLVM IR (type mismatch in _FortranAAssign and llvm.memcpy).
The fix ensures that declare_reduction ops are created for the correct
boxed type when the reduction variable is allocatable or pointer. This
works for both integer and character types.
[MLIR][OpenMP] Support calls added between MarkDeclareTarget runs
Currently, if there are multiple executions of the `MarkDeclareTarget`
pass in a compiler pipeline and somewhere between both runs function
calls get added to a non-declare_target function that was marked as such
implicitly, potential changes to the `device_type` won't get propagated.
This is because we can't distinguish between a user-specified
`declare_target` function attribute and one added by that pass. This
patch addresses this by adding a new parameter to `DeclareTargetAttr`
that is used by that pass to know whether new `declare_target`
information could be propagated to it.
The `automap` and `implicit` parameters are given default values to
simplify the representation of these attributes.
[libc++] Make all of <random> depend on <__math/FOO.h> instead of <cmath> (#213084)
Some of `<random>` functionality depends on the system's `math.h` header
instead of `__math/FOO.h`. System's are just undefined symbol to be
linked, but the `__math/FOO.h` are implemented with potentially
constexpr-friendly builtins. Also, some of the functionality seems to be
using `__math::` namespace and some doesn't, seemingly randomly.
This PR fixes such inconsistency, avoids using non-constexpr functions
from the system's `math.h`, and in turn removes obstacles for P3791
`constexpr <random>`.
Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>
[Flang][OpenMP] Improve implicit declare_target propagation
After starting to run the `MarkDeclareTarget` pass later in the
pipeline, some limitations of its original implementation started to be
hit; specifically, some calls being missed could result in an overly
restrictive marking that would cause the `HostOpFiltering` pass to
remove reachable device code.
This patch aims to address these problems by making the following
changes:
- It makes sure to mark functions in every `RecipeInterface` op pointed
to by OpenMP operations.
- It recursively propagates and combines declare_target information from
target regions and explicitly set declare_target functions to unmarked
functions, but it never modifies explicitly marked functions.
- External and public functions can now only be marked with
`device_type(any)`. Before, marking them as `nohost` or `host` was
possible, but without the ability to see all users we can't give such
guarantees.
[7 lines not shown]
[Flang][OpenMP] Remove the DeleteUnreachableTargets pass
The `DeleteUnreachableTargets` pass was initially added to work around
a problem caused by the interaction between the function filtering and
host op filtering passes and generic MLIR optimizations.
Specifically, by running function and host op filtering before these
optimizations, we would lose the ability to detect unreachable
`omp.target` operations when compiling for the device. This would cause
GPU kernels being created for them, for which no host counterpart
existed.
By now having moved both passes towards the end of the compilation
pipeline, after FIR to LLVM lowering, removal of unreachable host and
device code is no longer impacted by them. This makes the
`DeleteUnreachableTargets` pass redundant.
[Flang][MLIR][OpenMP] Move function filtering to the omp dialect
The `FunctionFilteringPass`, which removes host-only functions when
compiling for an OpenMP target device, is currently defined only for
Flang. However, it implements logic that would generally be useful for
other frontends that can generate OpenMP offloading code. This patch
makes that transition by implementing the following changes:
- It rewrites the `FunctionFilteringPass` to work on lower level non-FIR
MLIR modules.
- It splits off preexisting logic to check for not-yet-implemented target
device features during function filtering to its own pass and it improves
context detection to properly diagnostic only device code.
- It delays function filtering to run at the end of the pipeline, as well
as the `MarkDeclareTargetPass`. This will enable the latter to run
only once in the pipeline after the `UnimplementedDeviceCheckPass`
becomes no longer necessary.
One side effect of these changes is that delaying the filtering will
cause all following passes to process host functions that are eventually
[4 lines not shown]
[Analysis] Use CycleInfo for BlockFrequencyInfo (#213488)
BranchProbabilityAnalysis uses CycleInfo, but BFI doesn't, causing the
somewhat redundant construction of an extra LoopInfo. Avoid this by
porting BFI to use CycleInfo.
This requires a minor change to the BFI implementation to avoid
incorrect results with irreducible loops that show up as nested but
don't show up as nested loops -- such cycle entries are skipped now.
(Such an entry heads a loop the cycle absorbed, and which entry keeps a
nested cycle of its own depends on the order the search found the entries
in.) @crossloops reaches c1 and c2 alike, yet only c1 heads a nested cycle,
so seeding it gave c1 a loop scale c2 never got and their frequencies came
out 0.68571 and 1.1429 where the test derives 1.0 for both. Represent none
of those entries and leave the region to computeIrreducibleMass, which
decomposes it from the reverse postorder as it does when LoopInfo finds
no natural loop there.
Passing the parent down also fixes the loop nest: &Loops.back() is whichever
[3 lines not shown]
[libc++] Try fixing flaky fs.op.space test on FreeBSD (#213988)
As part of this test, we check the capacity available on the filesystem
and compare it against an expected capacity. However, on some
filesystems, the capacity is actually computed and may change depending
on filesystem usage. This creates a race condition since the disk may be
filling up (by e.g. other running tests) between the two calls.
For that same reason, other checks for the available size were using an
approximate equality up to a delta. Use the same approach for the
capacity here.
[mlir][bufferization] Handle scf.if deallocs in static memory planner (#213634)
Extends the static memory planner (#209106) to handle two scf.if
patterns that previously errored or were silently missed.
**What changed**
Replaced the hand-rolled `BufferViewFlowOpInterface` DFS with the shared
`BufferViewFlowAnalysis`. This covers arith.select, scf.if/for results,
cf branches, and view ops in one place — no new interface needed.
Two new cases are handled:
1. Alloc flows through an `scf.if` result; `dealloc` is on that result.
`resolve()` finds the alias and picks up the dealloc.
2. Alloc is in the entry block; `dealloc` is inside an `scf.if` body.
`findAncestorOpInBlock` anchors the lifetime to the enclosing `scf.if` —
conservative but correct.
[10 lines not shown]
[MLIR][OpenMP] Support calls added between MarkDeclareTarget runs
Currently, if there are multiple executions of the `MarkDeclareTarget`
pass in a compiler pipeline and somewhere between both runs function
calls get added to a non-declare_target function that was marked as such
implicitly, potential changes to the `device_type` won't get propagated.
This is because we can't distinguish between a user-specified
`declare_target` function attribute and one added by that pass. This
patch addresses this by adding a new parameter to `DeclareTargetAttr`
that is used by that pass to know whether new `declare_target`
information could be propagated to it.
The `automap` and `implicit` parameters are given default values to
simplify the representation of these attributes.
[libc++] Use the granular headers instead of <__locale> (#214029)
After splitting up <__locale> into sub-headers, we can now use the
granular includes from the rest of the code and remove <__locale>.
[Flang][OpenMP] Improve implicit declare_target propagation
After starting to run the `MarkDeclareTarget` pass later in the
pipeline, some limitations of its original implementation started to be
hit; specifically, some calls being missed could result in an overly
restrictive marking that would cause the `HostOpFiltering` pass to
remove reachable device code.
This patch aims to address these problems by making the following
changes:
- It makes sure to mark functions in every `RecipeInterface` op pointed
to by OpenMP operations.
- It recursively propagates and combines declare_target information from
target regions and explicitly set declare_target functions to unmarked
functions, but it never modifies explicitly marked functions.
- External and public functions can now only be marked with
`device_type(any)`. Before, marking them as `nohost` or `host` was
possible, but without the ability to see all users we can't give such
guarantees.
[7 lines not shown]
[libc++] Require installing dependencies before running LNT tooling (#214020)
This makes all benchmark-related utilities consistently rely on a
virtual environment containing libcxx/utils/requirements.txt instead of
some scripts installing their dependencies explicitly, which is
duplicate work in most cases.
[runtimes] Remove override of LLVM_ENABLE_PER_TARGET_RUNTIME_DIR on Darwin (#213748)
It should be possible to produce a per-target include directory even on
Apple platforms. That's not the way we ship the library by default, but
there's no reason not to allow selecting that configuration.
[libc++] Move math special functions under __cmath (#213944)
It was always a bit weird that these were the only functions under
__math/ which were not in the __math namespace and were not in the
global namespace. This also led to a workaround in the C++20 modules
testing.
Instead, move math special functions under __cmath/, which will contain
APIs that are part of `<cmath>` but not `<math.h>`.