`Constant::isZeroValue` currently behaves same as
`Constant::isNullValue` for all types except floating-point, where it
additionally returns true for negative zero (`-0.0`). However, in
practice, almost all callers operate on integer/pointer types where the
two are equivalent, and the few FP-relevant callers have no meaningful
dependence on the `-0.0` behavior.
This PR removes `isZeroValue` to eliminate the confusing API. All
callers are changed to `isNullValue` with no test failures.
`isZeroValue` will be reintroduced in a future change with clearer
semantics: when null pointers may have non-zero bit patterns,
`isZeroValue` will check for bitwise-all-zeros, while `isNullValue` will
check for the semantic null (which
may be non-zero).
This patch puts together a lot more of the CIR infrastructure for
function attributes, plus adds a bunch of 'TODO' messages for areas that
have been skipped.
Along the way, we also implement 8 attributes in some way: -Convergent
gets a little more work, to make the `noconvergent` C attribute have an
effect
-optsize/minsize are implemented, sourced from the command line
-nobuiltin is a call-only attribute that tells not to replace the
individual call with a builtin. This is a touch confusing, since
no-builtins is an attribute that means "don't replace anything in the
body of this function with builtins (from this list)". The spelling
confusion is existing, and it seems that changing the names away from
LLVM would be confusing.
-save_reg_params & zero_call_used_regs are boht pretty simple registers
-temp-func-name just passes a string to LLVM, consistent with existing
implementation.
-default-func-attrs is a difficult one. It takes command line arguments
and passes them as LLVM-IR attributes directly on functions/calls. In
the dialect, we are capturing these in their own attribute to pass them
on correctly. However, this is one we cannot recover from LLVM-IR for
obvious reasons, so we instead choose to let the 'passthrough' mechanism
work for those.
Convert "denormal-fp-math" and "denormal-fp-math-f32" into a first
class denormal_fpenv attribute. Previously the query for the effective
denormal mode involved two string attribute queries with parsing. I'm
introducing more uses of this, so it makes sense to convert this
to a more efficient encoding. The old representation was also awkward
since it was split across two separate attributes. The new encoding
just stores the default and float modes as bitfields, largely avoiding
the need to consider if the other mode is set.
The syntax in the common cases looks like this:
`denormal_fpenv(preservesign,preservesign)`
`denormal_fpenv(float: preservesign,preservesign)`
`denormal_fpenv(dynamic,dynamic float: preservesign,preservesign)`
I wasn't sure about reusing the float type name instead of adding a
new keyword. It's parsed as a type but only accepts float. I'm also
debating switching the name to subnormal to match the current
preferred IEEE terminology (also used by nofpclass and other
contexts).
This has a behavior change when using the command flag debug
options to set the denormal mode. The behavior of the flag
ignored functions with an explicit attribute set, per
the default and f32 version. Now that these are one attribute,
the flag logic can't distinguish which of the two components
were explicitly set on the function. Only one test appeared to
rely on this behavior, so I just avoided using the flags in it.
This also does not perform all the code cleanups this enables.
In particular the attributor handling could be cleaned up.
I also guessed at how to support this in MLIR. I followed
MemoryEffects as a reference; it appears bitfields are expanded
into arguments to attributes, so the representation there is
a bit uglier with the 2 2-element fields flattened into 4 arguments.
The alloc_size attribute takes the argument number(normalized to the
index!) of the element size and count, for things like 'malloc' or
'calloc'.
This ends up being slightly more complicated than others, as this has
data that we have to decide on a format for. LLVM chooses to pack both
of these 32 bit values into a single i64, but unpacks it for the purpose
of input/output. The second value, the number of elements, is optional.
This patch uses a DenseI32ArrayAttr to store them for the LLVMIR
dialect, which gets us the packed nature, but doesn't require us doing
any work to unpack it.
This patch adds the 'no-builtins' and 'no-builtin-XXX' attributes from
LLVM-IR to both LLVMIR-MLIR and Clang lowering. However, I've done a
slightly different implementation of them.
LLVM-IR represents them as 'no-builtins' and 'no-builtin-NAME', where
the latter can be multiple names. This is problematic for the MLIR for a
variety of reasons, most particularly is our preference for explicit
attribute (of which the latter is an infinite list). Additionally of
course, our inability to have dashes in attribute names is troublesome.
Therefore, I've lowered them instead as `nobuiltins` for both, which is
an array attribute.
IF the array attribute is empty, it is intended to mean 'all functions'
(ie, the same as `no-builtins`), else it is a list of StringAttrs that
contain the variants of `NAME`.
I considered using nobuiltins=['*'] for the 'all functions', but that
seemed like a differentiation without purpose.
This patch lowers 3 more attributes, two of which are trivial, and one
which has a touch of a complication.
The two trivial ones are no_caller_saved_registers and nocallback, which
are language-level attributes that are effectively just passed on.
The final one is a touch more complicated, as it is a 'string'
attribute: modular-format. Also, it has a dash in the LLVM-IR version,
but that isn't possible to add as a name in the LLVM-IR MLIR Dialect
(see the comment inline). It also has a string of some consequence (that
is checked in LLVM), but that is just passed to LLVM directly.
Continuing my quest to get most of the attributes completed, this patch
implements 5 attributes for CIR/Clang CIR codegen.
4 of the 5 are also implemented in LLVM-MLIR, since 'convergent' was
already there.
As a part of this, we also had to make sure that attributes were handled
properly for Call operation lowering, like we do for function
attributes.
This mirrors what LLVM does, and requires propagating into the LLVM
dialect: When the user specifies 'noreturn' we propagate this down
throughout the stack.
Note the similar 'willreturn' is too strong of a guarantee (in that they
are not opposites of each other, as there is a 'unknown' implied by all
others), so we cannot use that on non-noreturn functions.
This updates the LLVM IR ConstantInt creation from mlir::IntegerAttr so
that unsigned integers and 1-bit integers are zero-extended rather than
sign-extended.
Add createIntrinsicCall overload that accepts return type and arguments,
automatically resolve overload types rather than requiring manual
computation. Simplifies NVVM_PrefetchOp by removing conditional overload
logic.
This commit enhances MLIR's TBAA export with support for anonymous TBAA roots. The import for this was around for a bit but the export was missing.
Fixes: #160721
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>
We have `noinline` and `alwaysinline` present as first class function
attributes. Add `inline_hint` to the list of function attributes as
well.
Update the module import and translation to support the new attribute.
The verifier does not need to be changed as `inlinehint` does not
conflict with `noinline` or `alwaysinline`.
`inline_hint` is needed to support the `inline` C/C++ keyword in CIR.
Use wrappers around `std::accumulate` to make the code more concise and
less bug-prone: https://github.com/llvm/llvm-project/pull/162129.
With `std::accumulate`, it's the initial value that determines the
accumulator type. `llvm::sum_of` and `llvm::product_of` pick the right
accumulator type based on the range element type.
Found some funny bugs like a local accumulate helper that calculated a
sum with initial value of 1 -- we didn't hit the bug because the code
was actually dead...
Adds a `target_specific_attrs` optional array attribute to
`mlir.global`, as well as conversions to and from LLVM attributes on
`llvm::GlobalVariable` objects. This is necessary to preserve unknown
attributes on global variables when converting to and from the LLVM
Dialect. Previously, any attributes on an `llvm::GlobalVariable` not
explicitly modeled by `mlir.global` were dropped during conversion.
Currently the `DbgDeclareOP/DbgValueOP/DbgLabelOp` are first converted
to llvm debug intrinsics which are later translated to debug records by
a call of `convertToNewDbgValues`. This is not only inefficient but also
makes the code that works on intermediate IR unnecessarily complicated.
The debug intrinsics are also being phased out. This PR converts these
Ops directly to debug records.
The conversion is relatively simple but there is a bit of code
repetition due to how the APIs in the `DIBuilders` are named. There are
few `cast<>` which I would like to do without but could not see a good
way around them. Any suggestions welcome here. Also noticed that
`DISubprogramAttr` is inherited from `DIScopeAttr` while in llvm, the
`DISubprogram` inherits from `DILocalScope`. I am going to fix this
separately and then we could use `FusedLocWith<LLVM::DILocalScopeAttr>`
and cast to `DILocalScope` will be much safer.
As the output remains the same, the existing tests cover this change. I
also ran the `GDB` tests with flang and there was no regression.
---------
Co-authored-by: Tobias Gysi <tobias.gysi@nextsilicon.com>
Remove "approx-func-fp-math" attribute and related command line option,
users should always use afn flag in IR.
Resolve FIXME in `TargetMachine::resetTargetOptions` partially.
…(… (#151099)
This reverts commit 2780b8f22058b35a8e70045858b87a1966df8df3 and relands
b7bfbc0c4c7b20d6623a5b0b4a7fea8ae08a62da.
Adds the following fixes compared to the original PR
(https://github.com/llvm/llvm-project/pull/150783):
- A bazel fix
- Use `let methods` instead of `list<InterfaceMethod> methods`
The missing forward declaration has been added in meantime:
9164d206b3.
Reverts llvm/llvm-project#151125
Broke the gcc-7 build:
include/mlir/Target/LLVMIR/ModuleTranslation.h:318:34: error: no type
named 'CallBase' in namespace 'llvm'
llvm::CallBase *call,
~~~~~~^
…… (#151099)
This reverts commit 2780b8f22058b35a8e70045858b87a1966df8df3 to reland
59013d44058ef423a117f95092150e16e16fdb09.
In addition to the original commit this one includes:
- This includes a bazel fix
- Use `let methods` instead of `list<InterfaceMethod> methods`
The original commit message was:
This patch extends the LLVM dialect's intrinsic infra to support
argument and result attributes. Initial support is added for the memory
intrinsics llvm.intr.memcpy, llvm.intr.memmove, and llvm.intr.memset.
Additionally, an ArgAndResultAttrsOpInterface is factored out of
CallOpInterface and CallableOpInterface, enabling operations to have
argument and result attributes without requiring them to be a call or a
callable operation.
This patch extends the LLVM dialect's intrinsic infra to support
argument and result attributes. Initial support is added for the memory
intrinsics `llvm.intr.memcpy`, `llvm.intr.memmove`, and
`llvm.intr.memset`.
Additionally, an ArgAndResultAttrsOpInterface is factored out of
CallOpInterface and CallableOpInterface, enabling operations to have
argument and result attributes without requiring them to be a call or a
callable operation.
These are identified by misc-include-cleaner. I've filtered out those
that break builds. Also, I'm staying away from llvm-config.h,
config.h, and Compiler.h, which likely cause platform- or
compiler-specific build failures.
ArrayRef now has a new constructor that takes a parameter whose type
has data() and size(). This patch migrates:
ArrayRef<T>(X.data(), X.size()
to:
ArrayRef<T>(X)
ArrayRef has a constructor that accepts std::nullopt. This
constructor dates back to the days when we still had llvm::Optional.
Since the use of std::nullopt outside the context of std::optional is
kind of abuse and not intuitive to new comers, I would like to move
away from the constructor and eventually remove it.
This patch replaces {} with std::nullopt.
CodeExtractor can currently erroneously insert an alloca into a
different function than it inserts its users into, in cases where code
is being extracted out of a function that has already been outlined. Add
an assertion that the two blocks being inserted into are actually in the
same function.
Add a check to findAllocaInsertPoint in OpenMP to LLVMIR translation to
prevent the aforementioned scenario from happening.
OpenMPIRBuilder relies on a callback mechanism to fix-up a module later
on during the finaliser step. In some cases this results in the module
being invalid prior to the finalise step running. Remove calls to
verifyModule wrapped in LLVM_DEBUG from CodeExtractor, as the presence
of those results in the compiler crashing with -mllvm -debug due to
premature module verification where it would not crash without -debug.
Call ompBuilder->finalize() the end of mlir::translateModuleToLLVMIR, in
order to make sure the module has actually been finalized prior to
trying to verify it.
Resolves https://github.com/llvm/llvm-project/issues/138102.
---------
Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
The new interfaces provide getters and setters for the weight
information about the branches of BranchOpInterface and
RegionBranchOpInterface operations.
These interfaces are done the same way as LLVM dialect's
BranchWeightOpInterface.
The plan is to produce this information in Flang, e.g. mark
most probably "cold" code as such and allow LLVM to order
basic blocks accordingly. An example of such a code is
copy loops generated for arrays repacking - we can mark it
as "cold" assuming that the copy will not happen dynamically.
If the copy actually happens the overhead of the copy is probably high
enough so that we may not care about the little overhead
of jumping to the "cold" code and fetching it.
This flag was used to let us incrementally introduce debug records
into LLVM, however everything is now using records. It serves no
purpose now, so delete it.
This patch adds support for the -mrecip command line option. The parsing
of this options is equivalent to Clang's and it is implemented by
setting the "reciprocal-estimates" function attribute.
Also move the ParseMRecip(...) function to CommonArgs, so that Flang is
able to make use of it as well.
---------
Co-authored-by: Cameron McInally <cmcinally@nvidia.com>
Start removing debug intrinsics support -- starting with the flag that
controls production of their replacement, debug records. This patch
removes the command-line-flag and with it the ability to switch back to
intrinsics. The module / function / block level "IsNewDbgInfoFormat"
flags get hardcoded to true, I'll to incrementally remove things that
depend on those flags.
This patch adds support for the -mprefer-vector-width= command line
option. The parsing of this options is equivalent to Clang's and it is
implemented by setting the "prefer-vector-width" function attribute.
Co-authored-by: Cameron McInally <cmcinally@nvidia.com>
While LLVM IR dialect has a way to represent arbitrary LLVM constant
array of structs via an insert chain, it is in practice very expensive
for the compilation time as soon as the array is bigger than a couple
hundred elements. This is because generating and later folding such
insert chain is really not cheap.
This patch allows representing array of struct constants via ArrayAttr in
the LLVM dialect.
After each function is translated, both value and block maps are erased,
which makes the current mapping of blockaddresses to llvm blocks broken
- the patching happens only after *all* functions are translated.
Simplify the overall mapping, update comments, variable names and fix
the bug.
---------
Co-authored-by: Christian Ulmann <christianulmann@gmail.com>
Fix msan issue that caused revert in
https://github.com/llvm/llvm-project/pull/135695
### Original message
Now that LLVM dialect has `blockaddress` support, introduce
import/translation for `indirectbr` instruction.