When testing LLVM 15.0.0 rc1 on Solaris, I found that 50+ flang tests
`FAIL`ed with
error:
/vol/llvm/src/llvm-project/local/flang/lib/Optimizer/CodeGen/Target.cpp:310:
not yet implemented: target not implemented
This patch fixes that for Solaris/x86, where the fix is trivial (just
handling it like the other x86 OSes).
Tested on `amd64-pc-solaris2.11`; only a single failure remains now.
Differential Revision: https://reviews.llvm.org/D131054
Fortran runtime supports mixed types by casting the loaded values
to the result type, so DOT_PRODUCT simplification has to do the same.
Differential Revision: https://reviews.llvm.org/D131726
This reland includes changes to the Python bindings.
Switch variadic operand and result segment size attributes to use the
dense i32 array. Dense integer arrays were introduced primarily to
represent index lists. They are a better fit for segment sizes than
dense elements attrs.
Depends on D131801
Reviewed By: rriddle
Differential Revision: https://reviews.llvm.org/D131803
Switch variadic operand and result segment size attributes to use the
dense i32 array. Dense integer arrays were introduced primarily to
represent index lists. They are a better fit for segment sizes than
dense elements attrs.
Depends on D131738
Reviewed By: mehdi_amini
Differential Revision: https://reviews.llvm.org/D131702
This patch "modernizes" the LLVM `insertvalue` and `extractvalue`
operations to use DenseI64ArrayAttr, since they only require an array of
indices and previously there was confusion about whether to use i32 or
i64 arrays, and to use assembly format.
Reviewed By: ftynse
Differential Revision: https://reviews.llvm.org/D131537
I would like to add DOT_PRODUCT support in this pass, so this restructuring
is the first step to allow some code reuse inside getOrCreateFunction().
Differential Revision: https://reviews.llvm.org/D131530
The newly added AlgebraicSimplification pass is triggering the
greedy pattern rewriter. Since we define a specific config in the
flang pipeline, this patch adds the ability to pass the config
to the pass directly.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D131474
This change removes dependency on pgmath mod, and also allows
Fortran runtime to issue a diagnostic message in case of zero
denominator.
Differential Revision: https://reviews.llvm.org/D131192
Find calls to FortranASum{Real8,Integer4}, check for dim and mask
arguments being absent - then produce an inlineable simple
version of the sum function.
(No longer a prototype, please review for push to llvm/main - not sure how to make Phabricator update the review with actual commit message)
Reviewed By: peixin, awarzynski
Differential Revision: https://reviews.llvm.org/D125407
The semantic checks and runtime have been supported. This supports the
lowering of intrinsic ABORT.
`gfortran` prints a backtrace before abort, unless `-fno-backtrace` is
given. This is good to use. The intrinsic BACKTRACE is not supported
yet, so add TODO in the runtime.
This extention is needed in SPEC2017 521.wrf_r in
https://github.com/llvm/llvm-project/issues/55955.
Reviewed By: klausler
Differential Revision: https://reviews.llvm.org/D130439
GCC and that specific build bot issued warnings turned errors, due to a narrowing conversion from `unsigned` to `int32_t`. Silence these via a static_cast.
This is the follow up on https://reviews.llvm.org/D130730 which goes through upstream code and removes creating constant values in favour of using the constant indices in GEP directly. This leads to less and more readable code and more compact IR as well.
Differential Revision: https://reviews.llvm.org/D130731
When an array is defined with "unknown" size, such as fir.array<2x?x5xi32>,
it should be converted to llvm.array<10 x i32>. The code so far has
been converting it to llvm.ptr<i32>.
Using a different function to check the if there starting are constant
dimensions, rather than if ALL dimensions are constant, it now produces
the correct array form.
Some tests has been updated, so they are now checking the new behaviour
rather than the old behaviour - so there's no need to add further tests
for this particular scenario.
This was originally found when compiling Spec 17 code, where an assert
in a GepOP was hit. That is bug #56141, which this change fixes.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D129196
This patch refactors the runtime support for GET_COMMAND_ARGUMENT to
have a single entry point instead of 2. It also updates lowering
accordingly.
This makes it easier to handle dynamically optional arguments. See also
https://reviews.llvm.org/D118777
Differential Revision: https://reviews.llvm.org/D130475
This change decouples common functionality for convering abstract
results, so it can be reused later.
Depends on D129485
Reviewed By: clementval, jeanPerier
Differential Revision: https://reviews.llvm.org/D129778
This patch replaces x.getValue() with *x if the reference is obviously
protected by a presence check. Otherwise, it replaces x.getValue()
with x.value().
As Fortran 2018 16.9.169, the argument of selected_int_kind is integer
scalar, and result is default integer scalar. The constant expression in
this intrinsic has been supported by folding the constant expression.
This supports lowering and runtime for variables in this intrinsic.
Reviewed By: Jean Perier
Differential Revision: https://reviews.llvm.org/D129959
As Fortran 2018 16.9.170, the argument of `selected_real_kind` is integer
scalar, and result is default integer scalar. The constant expression in
this intrinsic has been supported by folding the constant expression.
This supports lowering this intrinsic for variables using runtime.
Reviewed By: Jean Perier
Differential Revision: https://reviews.llvm.org/D130183
Flang C++ Style Guide tells us to use *X when the reference is
protected by a presense test. However, (*X).foo() is a little harder
to read, especially when X is a complicated expression.
This patch slightly deviates from the guide (but retains the spirit)
by using X->foo() instead.
Differential Revision: https://reviews.llvm.org/D130413
Try 2 to merge 4fbd1d6c87.
Flang algebraic simplification pass will run algebraic simplification
rewrite patterns for Math/Complex/etc. dialects. It is enabled
under opt-for-speed optimization levels (i.e. for O1/O2/O3; Os/Oz will not
enable it).
With this change the FIR/MLIR optimization pipeline becomes affected
by the -O* optimization level switches. Until now these switches
only affected the middle-end and back-end.
Differential Revision: https://reviews.llvm.org/D130035
Flang algebraic simplification pass will run algebraic simplification
rewrite patterns for Math/Complex/etc. dialects. It is enabled
under opt-for-speed optimization levels (i.e. for O1/O2/O3; Os/Oz will not
enable it).
With this change the FIR/MLIR optimization pipeline becomes affected
by the -O* optimization level switches. Until now these switches
only affected the middle-end and back-end.
Differential Revision: https://reviews.llvm.org/D130035
Flang C++ Style Guide tells us to use x.value() when no presence test
is obviously protecting the reference. Since assert can be disabled,
I don't count it as "protection" here.
Differential Revision: https://reviews.llvm.org/D130144
`AbstractResultOptions` is obsolete structure because `newArg` is used
only in `ReturnOpConversion`.
This change removes this struct, making dependencies of conversions more
straight-forward.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D129485
When computing the base addresses of an array slice to make a
descriptor, codegen generated two LLVM GEPs. The first to compute
the address of the base character element, and a second one to
compute the substring base inside that element.
The previous code did not care about getting the result of the first
GEP right: it used the base array LLVM type as the result type.
This used to work when opaque pointer were not enabled (the actual GEP
result type was probably applied in some later pass). But with opaque
pointers, the second GEP ends-up computing an offset of len*<LLVM array
type> instead of len*<character width>. A previous attempt to fix the
issue was done in D129079, but it does not cover the cases where the
array slice contains subcomponents before the substring
(e.g: array(:)%char_field(5:10)).
This patch fix the issue by computing the actual GEP result type in
codegen. There is also enough knowledge now so that a single GEP can be
generated instead of two.
Differential Revision: https://reviews.llvm.org/D129481
FirOpBuilder takes a fir::KindMapping reference. When the getKindMapping()
call is made inside the ctor call, the lifetime of this reference may
be as short as the ctor call (at least with when building flang in
release mode with clang 8). This can cause segfaults when later using
the FirOpBuilder.
Ensure the kindMap passed to the FirOpBuilder ctor is the same as the
FirOpBuilder.
Differential Revision: https://reviews.llvm.org/D129494
Flang C++ Style Guide tells us to avoid .has_value() in the predicate
expressions of control flow statements. I am treating ternary
expressions as control flow statements for the purpose of this patch.
Differential Revision: https://reviews.llvm.org/D128622
This required changing a bit of how attributes/types are parsed. A new
`KeywordSwitch` class was added to AsmParser that provides a StringSwitch
like API for parsing keywords with a set of potential matches. It intends to
both provide a cleaner API, and enable injection for code completion. This
required changing the API of `generated(Attr|Type)Parser` to handle the
parsing of the keyword, instead of having the user do it. Most upstream
dialects use the autogenerated handling and didn't require a direct update.
Differential Revision: https://reviews.llvm.org/D129267
Array-value-copy fails to generate a temporary array for case like this:
subroutine bug(b)
real, allocatable :: b(:)
b = b(2:1:-1)
end subroutine
Since LHS may need to be reallocated, lowering produces the following FIR:
%rhs_load = fir.array_load %b %slice
%lhs_mem = fir.if %b_is_allocated_with_right_shape {
fir.result %b
} else {
%new_storage = fir.allocmem %rhs_shape
fir.result %new_storage
}
%lhs = fir.array_load %lhs_mem
%loop = fir.do_loop {
....
}
fir.array_merge_store %lhs, %loop to %lhs_mem
// deallocate old storage if reallocation occured,
// and update b descriptor if needed.
Since %b in array_load and %lhs_mem in array_merge_store are not the same SSA
values, array-value-copy does not detect the conflict and does not produce
a temporary array. This causes incorrect result in runtime.
The suggested change in lowering is to generate this:
%rhs_load = fir.array_load %b %slice
%lhs_mem = fir.if %b_is_allocated_with_right_shape {
%lhs = fir.array_load %b
%loop = fir.do_loop {
....
}
fir.array_merge_store %lhs, %loop to %b
fir.result %b
} else {
%new_storage = fir.allocmem %rhs_shape
%lhs = fir.array_load %new_storage
%loop = fir.do_loop {
....
}
fir.array_merge_store %lhs, %loop to %new_storage
fir.result %new_storage
}
// deallocate old storage if reallocation occured,
// and update b descriptor if needed.
Note that there are actually 3 branches in FIR, so the assignment loops
are currently produced in three copies, which is a code-size issue.
It is possible to generate just two branches with two copies of the loops,
but it is not addressed in this change-set.
Differential Revision: https://reviews.llvm.org/D129314
This patch is part of the upstreaming effort from fir-dev branch.
This is the last patch for the upstreaming effort.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D129187
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
This commit refactors the syntax of "ugly" attribute/type formats to not use
strings for wrapping. This means that moving forward attirbutes and type formats
will always need to be in some recognizable form, i.e. if they use incompatible
characters they will need to manually wrap those in a string, the framework will
no longer do it automatically.
This has the benefit of greatly simplifying how parsing attributes/types work, given
that we currently rely on some extremely complicated nested parser logic which is
quite problematic for a myriad of reasons; unecessary complexity(we create a nested
source manager/lexer/etc.), diagnostic locations can be off/wrong given string escaping,
etc.
Differential Revision: https://reviews.llvm.org/D118505
When addressing a substring of a character array, codegen emits two
GEPs: one for to compute the address of the base element, and a second
one to address the first characters from that element.
The first GEP still returns the LLVM array type (if the FIR array type could be
translated to an array type. Therefore) so zero
indexes must be added to the second GEP in this case to cover for the
Fortran array dimensions before inserting the susbtring offset index.
Surprisingly, the previous code worked ok when MLIR emits none opaque
pointers. But with opaque pointers, the two GEPs are folded in an
invalid GEP where the substring offset becomes an offset for the outer
array dimension.
Note that I tried to fix the issue by modifying the first GEP to return the
element type, but this still gave bad results (here something might be
wrong with opaque pointer in MLIR or LLVM).
Differential Revision: https://reviews.llvm.org/D129079
This patch just make the code more similar
in each conversion.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D129071
The previous code made the assumption that the defining
operation is a fir::ConvertOp without checking. This results in
segmentation fault in code like the added test.
Reviewed By: jeanPerier
Differential Revision: https://reviews.llvm.org/D129077
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D128935
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>
Co-authored-by: Peter Steinfeld <psteinfeld@nvidia.com>
As Fortran 2018 16.9.163, the reshape is the only intrinsic which
requires the shape argument to be rank-one integer array and the SIZE
of it to be one constant expression. The current expression lowering
converts the shape expression with slice in intrinsic into one box value
with the box element type of unknown extent. However, the genReshape
requires the box element type to be constant size. So, convert the box
value into one with box element type of sequence of 1 x constant. This
corner case is found in cam4 in SPEC 2017
https://github.com/llvm/llvm-project/issues/56140.
Reviewed By: Jean Perier
Differential Revision: https://reviews.llvm.org/D128597
- Add verifiers that determine if an Op requires type parameters or
not and checks that the correct number of parameters is specified.
This patch is part of the upstreaming effort from fir-dev branch.
Reviewed By: PeteSteinfeld
Differential Revision: https://reviews.llvm.org/D128828
Co-authored-by: Eric Schweitz <eschweitz@nvidia.com>