When alias analysis reports potential aliasing between LHS and RHS when
inlining `hlfir.assign`, use `ArraySectionAnalyzer` to determine if the
sections are disjoint or identical, which is safe for element-wise
assignment.
Co-authored-by: Delaram Talaashrafi <dtalaashrafi@rome5.pgi.net>
User-defined reductions declared in a module were not visible to
programs that imported the module via USE statements, causing valid code
to be incorrectly rejected. The reduction identifier defined in the
module scope wasn't being found during semantic analysis of the main
program.
Ref:
OpenMP Spec 5.1
_"If a directive appears in the specification part of a module then the
behavior is as if that directive,
with the variables, types and procedures that have PRIVATE accessibility
omitted, appears in the
specification part of any compilation unit that references the module
unless otherwise specified "_
Fixes :
[https://github.com/llvm/llvm-project/issues/176279](https://github.com/llvm/llvm-project/issues/176279)
Co-authored-by: Chandra Ghale <ghale@pe31.hpc.amslabs.hpecorp.net>
For cases like the following don't actually compute concatenation of
`str // "abc"`, because we only need final length:
```
character(len=*), intent(in) :: str
character(len=len(str // "abc")) :: res
```
For such cases, don't emit hlfir.concat.
Fixes#157763
Implement `F_C_STRING` to convert a Fortran string to a C
null-terminated string. Documented in F2023 Standard: 18.2.3.9
`F_C_STRING (STRING [, ASIS])`.
Previous commit message:
>Previous commit message:
>
>> Original commit message:
>>
>>>When users explicitly specify a PTX version via -mattr=+ptxNN that's
insufficient for their target SM, we now emit a fatal error. Previously,
we silently upgraded the PTX version to the minimum required for the
target SM.
>>>
>>>When no SM or PTX version is specified, we now use PTX 3.2 (the
minimum for the default SM 3.0) instead of PTX 6.0.
>>
>>The following commits should fix the failures that arose when I
previously tried to land this commit:
>>
>>
>>9fc5fd0ad6
should address the llvm-nvptx*-nvidia-* build failures:
https://github.com/llvm/llvm-project/pull/174834#issuecomment-3742242651
>>
>>
>>600514a637
should address the MLIR failures
>
>The previous commit was reverted with
d23cb79ba4
because the
[mlir-nvidia](https://lab.llvm.org/buildbot/#/builders/138/builds/24797)
and
[mlir-nvidia-gcc7](https://lab.llvm.org/buildbot/#/builders/116/builds/23929)
Buildbots were failing.
>
>Those tests failed because MLIR's default SM was 5.0, which caused
NVPTX
to target PTX ISA v4.0, which did not support the intrinsics used in the
failing tests.
>
>243f011577
should address this by bumping MLIR's default SM to 7.5. Now, using
MLIR's new default SM, NVPTX
targets the PTX ISA v6.3, which supports the intrinsics used in the
failing tests.
---
The previous commit was reverted with
e9b578a4d77025e18318efedd0f3f3764338d859
[because](https://github.com/llvm/llvm-project/pull/179304#issuecomment-3856301333)
the clang driver set the default PTX ISA version to v4.2 when no CUDA
installation is found. However, given our patch, we should not set a
default; instead, let the LLVM backend select the appropriate PTX ISA
version for the target SM.
When the actual argument associated with the VALUES= dummy argument of
the intrinsic subroutine DATE_AND_TIME has fewer than eight elements, we
crash with an internal error in the runtime.
With this patch, the compiler now checks the size of the vector at
compilation time, when it is known, and gracefully copes with a short
vector at execution time otherwise, without crashing.
The compiler can recognize a compiler directive when one results from a
macro expansion at the beginning of a non-comment source line, as in
"#define FOO !$OMP". But it can't recognize a compiler directive that
initially appears as a comment line, as in "!BAR" after "#define BAR
$OMP". Extend the prescanner to recognize such cases in free form
source. (Fixed form is a much more complicated case for this recognition
and will be addressed later if needed.)
Fixes https://github.com/llvm/llvm-project/issues/178481.
Fixes#177501
This PR fixes a compilation crash when using character types in OpenMP
REDUCTION clauses with declare_reduction directives.
The problem was that character types weren't being handled properly
during OpenMP lowering. Specifically:
- Missing character length parameters in hlfir.declare operations
- Incorrect type wrapping for by-ref reductions
- Missing special case handling for boxed/unboxed character types
The fix ensures character types are treated similarly to derived types
throughout the reduction pipeline, since fir::isa_trivial() excludes
them.
Added a regression test to verify the fix works for both allocatable and
non-allocatable character reductions.
<img width="654" height="47" alt="image"
src="https://github.com/user-attachments/assets/cc962f01-3432-44ce-befb-324644767c8b"
/>
This pass splits up the `vscaleRange` pass-option from the
`VScaleAttrPass` into `vscaleMin` and `vscaleMax` respectively, since a
`std::pair<>` cannot be used as a cli-option and crashes when running
`flang -march=rv64gcv -O3 file.f90 -mmlir -debug`.
Since the options can now be set individually I added some error
checking following the semantics described in the langref
https://llvm.org/docs/LangRef.html#function-attributes.
I also added tests since there were none for only this pass before.
Improve `ScheduleOrderedAssignments` to avoid creating temporary storage
for masks in `WHERE` constructs when the mask modification is "aligned"
with the assignment (e.g., `where(a(i)>0) a(i)=...`).
- Identify "aligned" conflicts (identical array elements accessed in
order) using the `ArraySectionAnalyzer` that is extracted from
OptimizedBufferization.
- Defer saving regions with aligned conflicts, allowing fusion if
possible.
- Implement retroactive saving: if a region was modified in a previous
run (fused via aligned conflict) but is needed by a later split run,
insert a `SaveEntity` action before the modifying run.
- Use `std::list` for the schedule to support stable iterators for run
insertion.
- Update tests to verify fewer temporaries and correct retroactive
saves.
- Update flang pipeline at O2 and more to try fusing assignments in
WHERE/FORALL. This allows maximizing the chances that mask temps are not
needed (because a mask variable cannot be reused in a later run/loop
nest if it was modified even if all the accesses are in order, being in
order only matter for accesses generated inside the same loop nest).
This fixes suboptimal code generation where temporaries were created
unnecessarily for common patterns like `where (x > 0) x = ...`.
Fix https://github.com/llvm/llvm-project/issues/180374
I initially suspected an issue with some lower bound adjustment missing,
and indeed found an unrelated issue because gen1DSection was always
called with all-ones lower bounds because the genLowerbounds was called
on the result fir.shape.
But this is actually not relevant for the issue where this code path is
not exercised. The issue was `nuw` (no unsigned-wrap) was being set on
arithmetic inside the kernel generated for CSHIFT, but because this
arithmetic is dealing with user defined bounds, it may actually have to
deal with negative values (even if the offsets from the CSHIFT itself
are not negative).
This caused LLVM optimization to generate completely invalid code when
the lower bounds of CSHIFT input are zero or less.
Without alias analysis Flang assumes no aliasing in lowering record
assignments which can result in miscompilation of programs using
`SEQUENCE` types and `EQUIVALENCE`.
Use alias analysis to guard the fast path in `genRecordAssignment`;
otherwise fall back to element-wise expansion.
Update FIR FileCheck expectations
Add `FIRAnalysis` to "flang/unittests/Optimizer/CMakeLists.txt" to fix
the Windows x64 build failure (linker error).
Add `SEQUENCE` handling and update tests accordingly.
Fixes#175246 (and includes the fix to
"flang/lib/Optimizer/Builder/CMakeLists.txt" in PR #176483).
Co-authored-by: Matt P. Dziubinski <matt-p.dziubinski@hpe.com>
Follow-up to https://github.com/llvm/llvm-project/pull/178739.
The locality check assumed that immediately after the initial symbol
resolution (i.e. prior to the OpenMP code in resolve-directives.cpp),
the scope that owns a given symbol is the scope which owns the symbol's
storage. Turns out that this isn't necessarily true as illustrated by
the included testcase, roughly something like:
```
program main
integer :: j ! host j (storage-owning)
contains
subroutine f
!$omp parallel ! scope that owns j, but j is host-associated
do j = ...
end do
!$omp end parallel
end
end program
```
In such cases, the locality should be checked for the symbol that owns
storage, i.e. a clone of the symbol that is has been privatized or a
symbol that is not host- or use-associated. This is similar to obtaning
the ultimate symbol (i.e. from the end of association chain), except the
chain traversal would stop at a privatized symbol, potentially before
reaching the end.
This fixes a few regressions in the Fujitsu test suite:
Fujitsu/Fortran/0160/Fujitsu-Fortran-0160_0000.test
Fujitsu/Fortran/0160/Fujitsu-Fortran-0160_0012.test
Fujitsu/Fortran/0160/Fujitsu-Fortran-0160_0013.test
Fujitsu/Fortran/0660/Fujitsu-Fortran-0660_0096.test
Fujitsu/Fortran/0660/Fujitsu-Fortran-0660_0097.test
Fujitsu/Fortran/1052/Fujitsu-Fortran-1052_0108.test
Fujitsu/Fortran/1052/Fujitsu-Fortran-1052_0112.test
In fixed source form, allow conditional compilation statements to begin
with a continuation line and emit a warning. This behavior is similar
to that of regular statements and -E mode.
Fixes#129457
Extract `ArraySectionAnalyzer` from `OptimizedBufferization` into a
standalone
analysis utility so it can be reused by other passes (e.g.,
`ScheduleOrderedAssignments`).
Also extracts the logic to detect if a designate is using the indices
of an elemental operation in storage order.
This will be used in WHERE construct optimization in the next patch.
When a pointer component has no default initialization in the derived
type definition and does not appear explicitly as a component in a
structure constructor, we assume that it is meant to be NULL() as an
extension. But there's no warning or documentation for this extension;
add them.
Fixes https://github.com/llvm/llvm-project/issues/179580.
When checking an actual argument for any CUDA data attributes, be sure
to check the symbols in a designator like a%b%c in order, taking the
last symbol that has a CUDA attribute. And be sure to interpret a
function result symbol of a device function as a device object, at least
for generic interface resolution for defined assignments and operators.
This patch exposed errors in flang/test/Semantics/bug1214.cuf, which
have been fixed.
I'm emitting a false warning "used without definition" warning for
variable cited in an inquiry intrinsic (e.g. LBOUND), and failing to
emit an "unused local" warning for allocatables that only appear in
ALLOCATE statements.
This patch makes the analysis more context-aware by rewriting it in
terms of typed expression traversal, and moves the analysis part into
Evaluate/check-expression.cpp from Semantics/expression.cpp.
Without alias analysis Flang assumes no aliasing in lowering record
assignments which can result in miscompilation of programs using
SEQUENCE types and EQUIVALENCE.
Use alias analysis to guard the fast path in `genRecordAssignment`;
otherwise fall back to element-wise expansion.
Update FIR FileCheck expectations
Add `FIRAnalysis` to `"flang/unittests/Optimizer/CMakeLists.txt"` to fix
the Windows x64 build failure (linker error).
Add `SEQUENCE` handling and update tests accordingly.
Fixes#175246 (and includes the fix to
flang/lib/Optimizer/Builder/CMakeLists.txt in PR #176483).
Co-authored-by: Matt P. Dziubinski <matt-p.dziubinski@hpe.com>
This change makes `fir.field_index` a Pure operation, and
add support of `ConditionallySpeculatable` interface for
`fir.coordinate_of`. The test demonstrates how this affects
Flang LICM.
This change basically treats the descriptors' and data loads
as non-aliasing (with one exception) same way as we do it
for the purpose of the TBAA tags generation for LLVM
to do better optimizations. This change enables more LICM in Flang MLIR.
Previous commit message:
> Original commit message:
>
>>When users explicitly specify a PTX version via -mattr=+ptxNN that's
insufficient for their target SM, we now emit a fatal error. Previously,
we silently upgraded the PTX version to the minimum required for the
target SM.
>>
>>When no SM or PTX version is specified, we now use PTX 3.2 (the
minimum for the default SM 3.0) instead of PTX 6.0.
>
>The following commits should fix the failures that arose when I
previously tried to land this commit:
>
>9fc5fd0ad6
should address the llvm-nvptx*-nvidia-* build failures:
https://github.com/llvm/llvm-project/pull/174834#issuecomment-3742242651
>
>600514a637
should address the MLIR failures
---
The previous commit was reverted with
d23cb79ba497281de050ef609cb91b91058bf323 because the
[mlir-nvidia](https://lab.llvm.org/buildbot/#/builders/138/builds/24797)
and
[mlir-nvidia-gcc7](https://lab.llvm.org/buildbot/#/builders/116/builds/23929)
Buildbots were failing.
Those tests failed because MLIR's default SM was 5.0, which caused NVPTX
to target PTX ISA v4.0, which did not support the intrinsics used in the
failing tests.
243f011577193c99358ccc4142b296d4fa80ea11 should address this by bumping
MLIR's default SM to 7.5. Now, using MLIR's new default SM, NVPTX
targets the PTX ISA v6.3, which supports the intrinsics used in the
failing tests.
When an assembly file is passed to the Flang driver, it currently fails
with a confusing internal error mentioning the unsupported `-cc1as`
tool.
This update detects assembly inputs early in the driver and emits a
clear, user-facing diagnostic explaining that Flang does not support
assembly files as input. The logic is implemented in a small helper
function and is intentionally temporary, so it can be removed once Flang
gains support for assembling inputs.
Fixes: #173528
Without alias analysis Flang assumes no aliasing in lowering record
assignments which can result in miscompilation of programs using
SEQUENCE types and EQUIVALENCE.
Represent `SEQUENCE` in fir.type.
For `SEQUENCE` types, use alias analysis to guard the fast path in
`genRecordAssignment`; otherwise fall back to element-wise expansion.
Update FIR FileCheck expectations
Add `FIRAnalysis` to `"flang/unittests/Optimizer/CMakeLists.txt"` to fix
the Windows x64 build failure (linker error).
Fixes#175246.
Co-authored-by: Matt P. Dziubinski <matt-p.dziubinski@hpe.com>
Fixes [#178614](https://github.com/llvm/llvm-project/issues/178614)
This PR implements support for multiple types in OpenMP declare
reduction directives, as specified in OpenMP
Spec(`6.0-7.6.14declare_reduction Directive`).
When a declare reduction directive specifies several types (e.g.,` !$omp
declare reduction(name: integer, real : ...)`), separate reduction
operations are now generated for each type.
Modified `flang/lib/Lower/OpenMP/OpenMP.cpp` to:
- Loop through each type in the type list
- Generate a separate omp.declare_reduction operation for each type
---------
Co-authored-by: urvi-rav <urvi.rav@hpe.com>
When descriptor dummy args have ignore_tkr(c), we want to use the
descriptor unchanged. As such, disable various semantic error checks
that are normally performed on descriptor based dummy args without
ignore_tkr(c)
https://github.com/llvm/llvm-project/pull/179362 changes which op is
checked for visibility during nested symbol resolution. This cause
issues in the CUDA Fortran pipeline and make some lookup fails. Update
the visibility of declaration copied to the gpu.module to nested.
Extract `FIRToLLVMPassOptions` initialization into a helper function,
allowing other code to construct pass options from pipeline
configuration without duplication.
---------
Co-authored-by: Delaram Talaashrafi <dtalaashrafi@rome5.pgi.net>
Fix https://github.com/llvm/llvm-project/issues/168561.
The issue was that the allocatable function result used as WHERE mask
was freed too early.
This happened because lowering was moving the result via as_expr but was
still inserting the deallocation directly on the storage instead of
passing that responsibility to the moved value (hlfir.expr). Later, the
pass optimizing WHERE is extending the expr lifetime usage passed the
deallocation of the storage because it (rightfully) assumes it can
extent lifetime of hlfir.expr as long as it moves the related destroy.
Fix lowering to pass the storage ownership to the expression after the
call instead.
There is code in resolve-directives.cpp that tries to apply DSA flags to
symbols encountered inside constructs. This code was written with the
assumption that all such symbols will be declared outside of the
construct.
When a symbol declared in a BLOCK construct nested in a construct was
found, the code would attempt to either privatize or share it in the
enclosing construct (where the symbol didn't exist) leading to trouble.
BLOCK constructs (and thus the possibility of having local variables)
was introduced in F2008.
The first OpenMP spec that considered F2008 was 5.0, where the behavior
of the BLOCK construct was explicitly left unspecified. From OpenMP 5.1
onwards, all local non-static variables are private in the construct
enclosing the declaration. This PR extends this behavior retroactively
to all prior OpenMP versions.
Fixes https://github.com/llvm/llvm-project/issues/178613
Make sure to add the source range whenever we create a scope for an
OpenMP construct or a clause. This allows that scope to be located via
context.FindScope(source).
When a derived type component is mapped via a data clause (e.g.,
`copyin(data%A(...))`), the base address inside the parallel region
comes from an `hlfir.declare` op (for the mapped address) instead of
an `hlfir.designate` op. Use `FortranVariableOpInterface` to extract
shape/typeparams/attrs, which works for both cases since both ops
implement this interface.
The workaround for no_create with array section is not needed anymore
because it has been expected that it would be up to the runtime to make
sure fir.box for the variable are always readable on the device even
when the variable is not present.
Semantics is instantiating derived types too soon is some cases, leading
to incorrect sizes and component offsets in cases of valid forward
references to derived types -- these appear in the declarations of
allocatable and pointer components. The incorrect size led to a runtime
crash in the linked bug report after an insufficient allocation.
Since those components are indirect, their sizes in the derived type
instantiation can be known without having to recursive instantiate the
components' types. Then, after laying out the derived type
instantiation, the compiler can then ensure that the components' types
are instantiated.
Fixes https://github.com/llvm/llvm-project/issues/178786.
When scanning the specific procedures of a generic interface for a match
for a set of actual arguments, accept a constant actual argument as a
match for a dummy argument with the DEVICE attribute.