511 Commits

Author SHA1 Message Date
Asher Mancinelli
f486cc4417
[flang] Add loop annotation attributes to the loop backedge (#126082)
Flang currently adds loop metadata to a conditional branch in the loop
preheader, while clang adds it to the loop latch's branch instruction.
Langref says:

> Currently, loop metadata is implemented as metadata attached to the
branch instruction in the loop latch block.
>
> https://llvm.org/docs/LangRef.html#llvm-loop

I misread langref a couple times, but I think this is the appropriate
branch op for the LoopAnnotationAttr. In a couple examples I found that
the metadata was lost entirely during canonicalization. This patch makes
the codegen look more like clang's and the annotations persist through
codegen.

* current clang: https://godbolt.org/z/8WhbcrnG3
* current flang: https://godbolt.org/z/TrPboqqcn
2025-05-14 07:07:57 -07:00
Dominik Adamski
cf16c97bfa
[Flang] Turn on alias analysis for locally allocated objects (#139682)
Previously, a bug in the MemCptOpt LLVM IR pass caused issues with
adding alias tags for locally allocated objects for Fortran code.

However, the bug has now been fixed (
https://github.com/llvm/llvm-project/pull/129537 ), and we can safely
enable alias tags for these objects. This change should improve the
accuracy of the alias analysis.
2025-05-14 09:21:18 +02:00
Sergio Afonso
7e8b3fea43
[Flang] Add missing dependent dialects to MLIR passes (#139260)
This patch updates several passes to include the DLTI dialect, since
their use of the `fir::support::getOrSetMLIRDataLayout()` utility
function could, in some cases, require this dialect to be loaded in
advance.

Also, the `CUFComputeSharedMemoryOffsetsAndSize` pass has been updated
with a dependency to the GPU dialect, as its invocation to
`cuf::getOrCreateGPUModule()` would result in the same kind of error if
no other operations or attributes from that dialect were present in the
input MLIR module.
2025-05-13 16:17:49 +01:00
Asher Mancinelli
bbb7f01481
[flang] Fix volatile attribute propagation on allocatables (#139183)
Ensure volatility is reflected not just on the reference to an
allocatable, but on the box, too. When we declare a volatile
allocatable, we now get a volatile reference to a volatile box.

Some related cleanups:
* SELECT TYPE constructs check the selector's type for volatility when
creating and designating the type used in the selecting block.
* Refine the verifier for fir.convert. In general, I think it is ok to
implicitly drop volatility in any ptr-to-int conversion because it means
we are in codegen (and representing volatility on the LLVM ops and
intrinsics) or we are calling an external function (are there any cases
I'm not thinking of?)
* An allocatable test that was XFAILed is now passing. Making
allocatables' boxes volatile resulted in accesses of those boxes being
volatile, which resolved some errors coming from the strict verifier.
* I noticed a runtime function was missing the fir.runtime attribute.
2025-05-13 08:13:47 -07:00
Slava Zakharin
2d12d31f44
[flang] Propagate contiguous attribute through HLFIR. (#138797)
This change allows marking more designators producing an opaque
box with 'contiguous' attribute, e.g. like in test1 case
in flang/test/HLFIR/propagate-contiguous-attribute.fir.
This would make isSimplyContiguous() return true for such
designators allowing merging hlfir.eval_in_mem with hlfir.assign
where the LHS is a contiguous array section.

Depends on #139003
2025-05-12 18:33:47 -07:00
Kareem Ergawy
2cc8734c45
[flang][fir] Basic lowering fir.do_concurrent locality specs to fir.do_loop ... unordered (#138512)
Extends lowering `fir.do_concurrent` to `fir.do_loop ... unordered` by
adding support for locality specifiers.

In particular, for `local` specifiers, a `fir.alloca` op is created
using the localizer type. For `local_init` specifiers, the `copy` region
is additionally inlined in the `do concurrent` loop's body.

PR stack:
- https://github.com/llvm/llvm-project/pull/137928
- https://github.com/llvm/llvm-project/pull/138505
- https://github.com/llvm/llvm-project/pull/138506
- https://github.com/llvm/llvm-project/pull/138512 (this PR)
- https://github.com/llvm/llvm-project/pull/138534
- https://github.com/llvm/llvm-project/pull/138816
2025-05-09 16:27:18 +02:00
Sergio Afonso
4923cffc1d
[Flang] Add missing dependency to AddDebugInfo pass (#139099)
The `AddDebugInfo` pass currently has a dependency on the `DLTI` MLIR
dialect caused by a call to the `fir::support::getOrSetMLIRDataLayout()`
utility function.

This dependency is not captured in the pass definition. This patch adds
the dependency and simplifies several unit tests that had to explicitly
use the `DLTI` dialect to prevent the missing dependency from causing
compiler failures.
2025-05-09 12:19:53 +01:00
MingYan
db2d5762eb
[flang][fir] Support promoting fir.do_loop with results to affine.for. (#137790)
Co-authored-by: yanming <ming.yan@terapines.com>
2025-05-09 10:55:21 +08:00
Anchu Rajendran S
580da48a93
[flang][flang-driver] Support flag -finstrument-functions (#137996) 2025-05-02 07:38:44 -07:00
Valentin Clement (バレンタイン クレメン)
9b6b144438
Revert "[flang][cuda] Use a reference for asyncObject" (#138221)
Reverts llvm/llvm-project#138186
2025-05-01 17:41:44 -07:00
Valentin Clement (バレンタイン クレメン)
7f922f1400
[flang][cuda] Use a reference for asyncObject (#138186)
Switch from `int64_t` to `int64_t*` to fit with the rest of the
implementation.

New tentative with some fix. The previous was reverted yesterday.
2025-05-01 17:04:12 -07:00
Valentin Clement (バレンタイン クレメン)
01a18809ee
Revert "[flang][cuda] Use a reference for asyncObject (#138010)" (#138082)
This reverts commit 9b0eaf71e674a28ee55be3afa11b5f7d4da732c0.
2025-04-30 22:03:26 -07:00
Valentin Clement (バレンタイン クレメン)
9b0eaf71e6
[flang][cuda] Use a reference for asyncObject (#138010)
Switch from `int64_t` to `int64_t*` to fit with the rest of the
implementation.
2025-04-30 14:02:29 -07:00
Oleksandr "Alex" Zinenko
7318074168
[mlir] allow function type cloning to fail (#137130)
`FunctionOpInterface` assumed the fact that the function type (attribute
of the operation) can be cloned with arbirary lists of function
arguments and results to support argument and result list mutation. This
is not always correct, in particular, LLVM dialect functions require
exactly one result making it impossible to erase the result.

Allow function type cloning to fail and propagate this failure through
various APIs that use it. The common assumption is that existing IR has
not been modified.

Fixes #131142.

Reland a8c7ecdcbc3e89b493b495c6831cc93671c3b844 / #136300.
2025-04-30 09:26:42 +02:00
Valentin Clement (バレンタイン クレメン)
d5272e4f41
[flang][cuda] Only copy global that have effective use (#137890) 2025-04-29 16:52:55 -07:00
Slava Zakharin
82c036e2de
[flang] Restructured TBAA trees in AddAliasTags pass. (#136725)
This patch produces the following TBAA tree for a function:
```
  Function root
  |
  "any access"
  |
  |- "descriptor member"
  |- "any data access"
     |
     |- "dummy arg data"
     |- "target data"
        |
        |- "allocated data"
        |- "direct data"
        |- "global data"
```
The TBAA tags are assigned using the following logic:
  * All POINTER variables point to the root of "target data".
  * Dummy arguments without POINTER/TARGET point to their
    leafs under "dummy arg data".
  * Dummy arguments with TARGET point to the root of "target data".
  * Global variables without descriptors point to their leafs under
    "global data" (including the ones with TARGET).
  * Global variables with descriptors point to their leafs under
    "direct data" (including the ones with TARGET).
  * Locally allocated variables point to their leafs under
   "allocated data" (including the ones with TARGET).

This change makes it possible to disambiguate globals like:
```
  module data
    real, allocatable :: a(:)
    real, allocatable, target :: b(:)
  end
```

Indeed, two direct references to global vars cannot alias
even if any/both of them have TARGET attribute.
In addition, the dummy arguments without POINTER/TARGET cannot alias
any other variable even with POINTER/TARGET. This was not expressed
in TBAA before this change.

As before, any "unknown" memory references (such as with Indirect
source, as classified by FIR alias analysis) may alias with
anything, as long as they point to the root of "any access".

Please think of the counterexamples for which this structure
may not work.
2025-04-29 10:17:11 -07:00
Valentin Clement (バレンタイン クレメン)
c8dc3ed9c4
[flang][cuda] Convert gpu.launch_func with result (#137231)
We cannot use `replaceOp` because the newly created operation has not
the same number of results.
2025-04-24 12:13:30 -07:00
Oleksandr "Alex" Zinenko
0c61b24337
[mlir] add a fluent API to GreedyRewriterConfig (#137122)
This is similar to other configuration objects used across MLIR.

Rename some fields to better reflect that they are no longer booleans.

Reland 04d261101b4f229189463136a794e3e362a793af / #132253.
2025-04-24 09:51:42 +02:00
Valentin Clement (バレンタイン クレメン)
d08e980065
[flang][cuda] Only convert launch from CUDA Fortran kernels (#136221)
Make sure `gpu.launch_func` has a CUDA proc attribute and update the
conversion pattern to only convert those with the attribute.
2025-04-21 10:51:48 -07:00
Valentin Clement (バレンタイン クレメン)
d79bb93278
[flang][cuda] Carry over the stream information to kernel launch (#136217)
In CUDA Fortran the stream is encoded in an INTEGER(cuda_stream_kind)
variable.

This information is carried over the GPU dialect through the
`cuf.stream_cast` and the token in the GPU ops.

When converting the `gpu.launch_func` to runtime call, the
`cuf.stream_cast` becomes a no-op and the reference to the stream is
passed to the runtime.

The runtime is adapted to take integer references instead of value for
stream.
2025-04-18 10:44:18 -07:00
Kazu Hirata
4cb9a3700c Revert "[mlir] add a fluent API to GreedyRewriterConfig (#132253)"
This reverts commit 63b8f1c9482ed0a964980df4aed89bef922b8078.

Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/172/builds/12083/steps/5/logs/stdio

I've reproduced the error with a release build (-DCMAKE_BUILD_TYPE=Release).
2025-04-18 09:40:28 -07:00
Oleksandr "Alex" Zinenko
63b8f1c948
[mlir] add a fluent API to GreedyRewriterConfig (#132253)
This is similar to other configuration objects used across MLIR.
2025-04-18 15:19:57 +02:00
Valentin Clement (バレンタイン クレメン)
91f9f0fa1e
[flang][cuda] Update cuf.kernel_launch stream and conversion (#136179)
Update `cuf.kernel_launch` to take the stream as a reference. Update the
conversion to insert the `cuf.stream_cast` op so the stream can be set
as dependency.
2025-04-17 12:55:08 -07:00
Slava Zakharin
da959c92c5
[flang] Fixed out-of-bounds access in SimplifyIntrinsics. (#136171)
When the mask is scalar, it is incorrect to cast it to
!fir.box<!fir.array<1xlogical<>>>, because the coordinate
operation will try to read the dim-1 stride from the box
to get the address of the first element. Even though
the stride value will be multiplied by 0, and does not matter,
it is still a read past the allocated box object.
Instead, we should just use box_addr to get the address
of the scalar mask.
2025-04-17 11:46:06 -07:00
Slava Zakharin
27bc8a1811
[flang][NFC] Split CG dialect and the passes. (#135240)
I am making a CG pass to depend on `FIROpenACCSupport` in #134346.
This introduces a cyclic dependency between `FIROpenACCSupport`
and `FIRCodeGen`. This patch splits `FIRCodeGen` into
`FIRCodeGenDialect` (for FIR CG dialect definition) and `FIRCodeGen`
(for the CG passes).

Now, `FIROpenACCSupport` depends on `FIRCodeGenDialect`,
and `FIRCodeGen` depends on `FIROpenACCSupport`.
2025-04-10 16:13:04 -07:00
Valentin Clement (バレンタイン クレメン)
49f8ccd1eb
[flang][cuda] Pass stream information to kernel launch functions (#135246) 2025-04-10 13:50:50 -07:00
Valentin Clement (バレンタイン クレメン)
ca53463137
[flang][cuda] Propagate stream information to gpu.launch_func op (#135227)
Use the information from `cuf.kernel_launch` to `gpu.launch_func`
2025-04-10 11:58:18 -07:00
Valentin Clement (バレンタイン クレメン)
18ff8df958
[flang][cuda] Register managed variables with double descriptor (#134444)
Allocatable or pointer module variables with the CUDA managed attribute
are defined with a double descriptor. One on the host and one on the
device. Only the data pointed to by the descriptor will be allocated in
managed memory.
Allow the registration of any allocatable or pointer module variables
like device or constant.
2025-04-04 14:38:01 -07:00
Slava Zakharin
58551faaf1
[flang] Inline fir.is_contiguous_box in some cases. (#133812)
Added inlining for `rank == 1` and `innermost` cases.
2025-04-01 08:41:11 -07:00
Slava Zakharin
0ac8cb1b3d
[flang] Recognize fir.pack_array in LoopVersioning. (#133191)
This change enables LoopVersioning when `fir.pack_array` is met
in the def-use chain. It fixes a couple of huge performance regressions
caused by enabling `-frepack-arrays`.
2025-03-31 11:41:43 -07:00
Bruno Cardoso Lopes
7c3ecffe9b
[MLIR][LLVMIR] Add support for the full form of global_{ctor,dtor} (#133176)
Currently only ctor/dtor list and their priorities are supported. This
PR adds support for the missing data field.

Few implementation notes:
- The assembly printer has a fixed form because previous `attr_dict`
will sort the dict by key name, making global_dtor and global_ctor
differ in the order of printed arguments.
- LLVM's `ptr null` is being converted to `#llvm.zero` otherwise we'd
have to create a region to use the default operation conversion from
`ptr null`, which is silly given that the field only support null or a
symbol.
2025-03-27 14:11:05 -07:00
Peter Klausler
4ea5aa09de
[flang][NFC] Restore I/O runtime API header name (#132423)
flang/include/flang/Runtime/io-api.h was changed into io-api-consts.h,
then wrapped into a new io-api.h that includes io-api-consts.h, does
some redundant includes and declarations, and then declares the
prototype of one function, InquiryKeywordHashDecode.

Make that function static in io-stmt.cpp prior to its sole call site,
then undo the renaming, to reduce confusion and redundancy.
2025-03-26 12:09:16 -07:00
Valentin Clement (バレンタイン クレメン)
e6dda9c23a
[flang][cuda] Only create shared memory global when needed (#132999) 2025-03-26 09:26:50 -07:00
Valentin Clement (バレンタイン クレメン)
5be9082fed
[flang][cuda] Carry over the dynamic shared memory size to gpu.launch_func (#132837) 2025-03-24 18:37:19 -07:00
Kareem Ergawy
6328506536
[flang][fir] Add rewrite pattern to convert fir.do_concurrent to fir.do_loop (#132207)
Rewrites `fir.do_concurrent` ops to a corresponding nest of `fir.do_loop
... unordered` ops.
2025-03-24 12:09:32 +01:00
Slava Zakharin
9ed772cecc
[flang] Fixed computation of position of function's arg in AddDebugInfo. (#131672)
I am working on `-frepack-array` feature (#127147), which produces
non-trivial manipulations with arguments of `fir.declare`.
In this case, we end up with CFG computation of the `fir.declare`
argument, and AddDebugInfo pass incorrectly mapped two dummy arguments
to the same arg index in the debug attributes.
This patch makes sure that we assign the arg index only if we can prove
that we've traced the block argument to the function's entry block.
I believe this problem is not specific to `-frepack-arrays`, e.g.
it may appear due to MLIR inlining as well.
2025-03-18 16:46:59 -07:00
Valentin Clement (バレンタイン クレメン)
e5ec7bb21b
[flang][cuda] Set correct offsets for multiple variables in dynamic shared memory (#131674) 2025-03-17 17:13:06 -07:00
Valentin Clement (バレンタイン クレメン)
74d4fc0a3e
[flang][cuda][NFC] Use ssa value for offset in shared memory op (#131661)
Switch from attribute to a value as we need to support dynamic offset
when multiple variables are used with dynamic shared memory.
2025-03-17 14:23:34 -07:00
Valentin Clement (バレンタイン クレメン)
e86081b6c2
[flang][cuda] Convert cuf.shared_memory operation to LLVM ops (#131396)
Convert the operation to `llvm.addressof` operation with
`llvm.getelementptr` with the appropriate offset.
2025-03-14 19:34:55 -07:00
Valentin Clement (バレンタイン クレメン)
4fb20b85fd
[flang][cuda] Compute offset on cuf.shared_memory ops (#131395)
Add a pass to compute the size of the shared memory (static shared
memory) and the offsets of each variables to be placed in shared memory.
The global representing the shared memory is also created during this
pass.

In case of dynamic shared memory, the global as a type of
`!fir.array<0xi8>` and the size of the memory is set at kernel launch.
2025-03-14 19:34:35 -07:00
Slava Zakharin
00f9c855fb
[flang] Added fir.is_contiguous_box and fir.box_total_elements ops. (#131047)
These are helper operations to aid with expanding of fir.pack_array.
2025-03-14 08:25:05 -07:00
Valentin Clement (バレンタイン クレメン)
478e516140
[flang][cuda] Sync double descriptor after c_f_pointer call (#130194)
After a global device pointer is set through `c_f_pointer`, we need to
sync the double descriptor so the version on the device is also up to
date.
2025-03-06 19:19:51 -08:00
Kelvin Li
996092d5a5
[flang] probably convert Fortran logical to i1 in expanding hlfir.maxloc/hlfir.minloc opcodes (#129791)
If mask is a scalar, it always converts to !fir.box<!fir.array<1xi1>>.
The wrong value may be picked up when passing to the function
on the big endian platform. This patch is to do the conversion 
based on the original type of the mask and convert the value to 
i1 after the load.
2025-03-06 15:47:44 -05:00
Slava Zakharin
0735cece68
[flang] Fixed fir.coordinate_of access in AddDebugInfo. (#129423)
The issue came up after #127231, when fir.coordinate_of, fed into
a declare, only has the field attribute and no coordinates.
2025-03-03 07:53:17 -08:00
Slava Zakharin
0caa8f42be Reland "[flang] Set LLVM specific attributes to fir.call's of Fortran runtime. (#128093)"
This change is inspired by a case in facerec benchmark, where
performance
of scalar code may improve by about 6%@aarch64 due to getting rid of
redundant
loads from Fortran descriptors. These descriptors are corresponding
to subroutine local ALLOCATABLE, SAVE variables. The scalar loop nest
in LocalMove subroutine contains call to Fortran runtime IO functions,
and LLVM globals-aa analysis cannot prove that these calls do not modify
the globalized descriptors with internal linkage.

This patch sets and propagates llvm.memory_effects attribute for
fir.call
operations calling Fortran runtime functions. In particular, it tries
to set the Other memory effect to NoModRef. The Other memory effect
includes accesses to globals and captured pointers, so we cannot set
it for functions taking Fortran descriptors with one exception
for calls where the Fortran descriptor arguments are all null.

As long as different calls to the same Fortran runtime function may have
different attributes, I decided to attach the attributes to the calls
rather than functions. Moreover, attaching the attributes to func.func
will require propagating these attributes to llvm.func, which is not
happening right now.

In addition to llvm.memory_effects, the new pass sets llvm.nosync
and llvm.nocallback attributes that may also help LLVM alias analysis
(e.g. see #127707). These attributes are ignored currently.
I will support them in LLVM IR dialect in a separate patch.

I also added another pass for developers to be able to print
declarations/calls of all Fortran runtime functions that are recognized
by the attributes setting pass. It should help with maintenance
of the LIT tests.
2025-02-24 14:18:17 -08:00
Slava Zakharin
69cc16fb55 Revert "[flang] Set LLVM specific attributes to fir.call's of Fortran runtime. (#128093)"
This reverts commit 36fdeb2aded08a776fcffefa73cb7667e7fc6c2d.
2025-02-24 10:52:53 -08:00
Slava Zakharin
4d53616901 Revert "[flang] Workaround build failure."
This reverts commit 823a597d2ad0a76e8d5278a789f37a07b393cd2a.
2025-02-24 10:52:48 -08:00
Slava Zakharin
823a597d2a [flang] Workaround build failure.
https://lab.llvm.org/buildbot/#/builders/140/builds/17587
Looks like it is related to some specific version of the build compiler.
2025-02-24 10:36:36 -08:00
Slava Zakharin
36fdeb2ade
[flang] Set LLVM specific attributes to fir.call's of Fortran runtime. (#128093)
This change is inspired by a case in facerec benchmark, where
performance
of scalar code may improve by about 6%@aarch64 due to getting rid of
redundant
loads from Fortran descriptors. These descriptors are corresponding
to subroutine local ALLOCATABLE, SAVE variables. The scalar loop nest
in LocalMove subroutine contains call to Fortran runtime IO functions,
and LLVM globals-aa analysis cannot prove that these calls do not modify
the globalized descriptors with internal linkage.

This patch sets and propagates llvm.memory_effects attribute for
fir.call
operations calling Fortran runtime functions. In particular, it tries
to set the Other memory effect to NoModRef. The Other memory effect
includes accesses to globals and captured pointers, so we cannot set
it for functions taking Fortran descriptors with one exception
for calls where the Fortran descriptor arguments are all null.

As long as different calls to the same Fortran runtime function may have
different attributes, I decided to attach the attributes to the calls
rather than functions. Moreover, attaching the attributes to func.func
will require propagating these attributes to llvm.func, which is not
happening right now.

In addition to llvm.memory_effects, the new pass sets llvm.nosync
and llvm.nocallback attributes that may also help LLVM alias analysis
(e.g. see #127707). These attributes are ignored currently.
I will support them in LLVM IR dialect in a separate patch.

I also added another pass for developers to be able to print
declarations/calls of all Fortran runtime functions that are recognized
by the attributes setting pass. It should help with maintenance
of the LIT tests.
2025-02-24 09:27:48 -08:00
Valentin Clement (バレンタイン クレメン)
93b2e47f12
[flang][cuda] Avoid assign element mismatch when doing data transfer from a constant (#128252)
Currently when we do a CUDA data transfer from a constant, we embox it
and delegate the assignment to the runtime. When the type of the
constant is not exactly the same as the destination descriptor, the
runtime will emit an assignment mismatch error.

Convert the constant when necessary so the assignment is fine.
2025-02-21 17:46:46 -08:00