459 Commits

Author SHA1 Message Date
Fangrui Song
71cf592191 [IR] Fix -Wunused-but-set-variable 2025-03-31 20:23:34 -07:00
Matt Arsenault
f77f2b9c56
llvm-reduce: Try to preserve instruction metadata as argument attributes (#133557)
Fixes #131825
2025-04-01 07:34:31 +07:00
Antonio Frighetto
ff585feacf [IR][ModRef] Introduce errno memory location
Model C/C++ `errno` macro by adding a corresponding `errno`
memory location kind to the IR. Preliminary work to separate
`errno` writes from other memory accesses, to the benefit of
alias analyses and optimization correctness.

Previous discussion: https://discourse.llvm.org/t/rfc-modelling-errno-memory-effects/82972.
2025-02-13 12:13:39 +01:00
Nikita Popov
29441e4f5f
[IR] Convert from nocapture to captures(none) (#123181)
This PR removes the old `nocapture` attribute, replacing it with the new
`captures` attribute introduced in #116990. This change is
intended to be essentially NFC, replacing existing uses of `nocapture`
with `captures(none)` without adding any new analysis capabilities.
Making use of non-`none` values is left for a followup.

Some notes:
* `nocapture` will be upgraded to `captures(none)` by the bitcode
   reader.
* `nocapture` will also be upgraded by the textual IR reader. This is to
   make it easier to use old IR files and somewhat reduce the test churn in
   this PR.
* Helper APIs like `doesNotCapture()` will check for `captures(none)`.
* MLIR import will convert `captures(none)` into an `llvm.nocapture`
   attribute. The representation in the LLVM IR dialect should be updated
   separately.
2025-01-29 16:56:47 +01:00
Nikita Popov
22e9024c9f
[IR] Introduce captures attribute (#116990)
This introduces the `captures` attribute as described in:
https://discourse.llvm.org/t/rfc-improvements-to-capture-tracking/81420

This initial patch only introduces the IR/bitcode support for the
attribute and its in-memory representation as `CaptureInfo`. This will
be followed by a patch to upgrade and remove the `nocapture` attribute,
and then by actual inference/analysis support.

Based on the RFC feedback, I've used a syntax similar to the `memory`
attribute, though the only "location" that can be specified is `ret`.

I've added some pretty extensive documentation to LangRef on the
semantics. One non-obvious bit here is that using ptrtoint will not
result in a "return-only" capture, even if the ptrtoint result is only
used in the return value. Without this requirement we wouldn't be able
to continue ordinary capture analysis on the return value.
2025-01-13 14:40:25 +01:00
goldsteinn
69a798a996
Reapply "[Inliner] Propagate more attributes to params when inlining (#91101)" (2nd Attempt) (#112749)
Root cause of the bug was code hanging onto `range` attr after
changing BitWidth. This was fixed in PR #112633.
2024-10-17 20:28:47 -05:00
goldsteinn
c85611e858
[SimplifyLibCall][Attribute] Fix bug where we may keep range attr with incompatible type (#112649)
In a variety of places we change the bitwidth of a parameter but don't
update the attributes.

The issue in this case is from the `range` attribute when inlining
`__memset_chk`. `optimizeMemSetChk` will replace an `i32` with an
`i8`, and if the `i32` had a `range` attr assosiated it will cause an
error.

Fixes #112633
2024-10-17 10:32:55 -05:00
Arthur Eubanks
9e6d24f61f Revert "[Inliner] Propagate more attributes to params when inlining (#91101)"
This reverts commit ae778ae7ce72219270c30d5c8b3d88c9a4803f81.

Creates broken IR, see comments in #91101.
2024-10-16 21:21:34 +00:00
goldsteinn
ae778ae7ce
[Inliner] Propagate more attributes to params when inlining (#91101)
- **[Inliner] Add tests for propagating more parameter attributes; NFC**
- **[Inliner] Propagate more attributes to params when inlining**

Add support for propagating:
        - `derefereancable`
        - `derefereancable_or_null`
        - `align`
        - `nonnull`
        - `range`
    
These are only propagated if the parameter to the to-be-inlined callsite
match the exact parameter used in the to-be-inlined function.
2024-10-16 11:53:21 -05:00
Michael Liao
765d7e7a47 [IR] Fix '-Wparentheses' warnings. NFC 2024-10-04 20:19:39 -04:00
Noah Goldstein
e343af777e [SimplifyCFG][Attributes] Enabling sinking calls with differing number of attrsets
Prior impl would fail if the number of attribute sets on the two calls
wasn't the same which is unnecessary as long as we aren't throwing
away and must-preserve attrs.

Closes #110896
2024-10-02 15:15:07 -05:00
Benjamin Maxwell
95f00a63ce
[IR] Allow fast math flags on calls with homogeneous FP struct types (#110506)
This extends FPMathOperator to allow calls that return literal structs
of homogeneous floating-point or vector-of-floating-point types.

The intended use case for this is to support FP intrinsics that return
multiple values (such as `llvm.sincos`).
2024-10-02 10:05:09 +01:00
goldsteinn
afc0557a04
[IR][Attribute] Add support for intersecting AttributeLists; NFC (#109719)
Add support for taking the intersection of two AttributeLists s.t the
result list contains attributes that are valid in the context of both
inputs.

i.e if we have `nonnull align(32) noundef` intersected with `nonnull
align(16) dereferenceable(10)`, the result is `nonnull align(16)`.

Further it handles attributes that are not-droppable. For example
dropping `byval` can change the nature of a callsite/function so its
impossible to correct a correct intersection if its dropped from the
result. i.e `nonnull byval(i64)` intersected with `nonnull` is
invalid.

The motivation for the infrastructure is to enable sinking/hoisting
callsites with differing attributes.
2024-10-01 11:45:32 -05:00
Noah Goldstein
29168e80ba [IR][Attribute] Add missing const def on addAllocSizeParamAttr(); NFC 2024-09-23 22:33:35 -05:00
Andreas Jonson
04da77308f
Allow empty range attribute and add assert for full range (#100601)
fix #99619
2024-08-08 18:07:09 +02:00
Kazu Hirata
7df9da7d78
[llvm] Construct SmallVector with ArrayRef (NFC) (#101872) 2024-08-04 08:54:23 -07:00
Haopeng Liu
5ece35df85
Add the 'initializes' attribute langref and support (#84803)
We propose adding a new LLVM attribute,
`initializes((Lo1,Hi1),(Lo2,Hi2),...)`, which expresses the notion of
memory space (i.e., intervals, in bytes) that the argument pointing to
is initialized in the function.

Will commit the attribute inferring in the follow-up PRs.


https://discourse.llvm.org/t/rfc-llvm-new-initialized-parameter-attribute-for-improved-interprocedural-dse/77337
2024-06-21 12:09:00 -07:00
Joshua Cao
ab08df2292
[IR] Do not set none for function uwtable (#93387)
This avoids the pitfall where we set the uwtable to none:
```
func.setUWTableKind(llvm::UWTableKind::None)
```
`Attribute::getAsString()` would see an unknown attribute and fail an
assertion. In this patch, we assert that we do not see a None uwtable
kind.

This also skips the check of `UWTableKind::Async`. It is dominated by
the check of `UWTableKind::Default`, which has the same enum value
(nfc).
2024-06-02 15:02:11 -07:00
Andreas Jonson
3d65bd935a
[NFC] Reduce copies created of ConstantRange when getting ConstantRangeAttributes (#90335)
Think that it can be good to reduce the number of copies created when
working with ConstantRangeAttributes.
2024-05-02 10:48:23 +09:00
Kazu Hirata
4e6f6fda8b
[IR] Use StringRef::operator== instead of StringRef::equals (NFC) (#90550)
I'm planning to remove StringRef::equals in favor of
StringRef::operator==.

- StringRef::operator== outnumbers StringRef::equals by a factor of 22
  under llvm/ in terms of their usage.

- The elimination of StringRef::equals brings StringRef closer to
  std::string_view, which has operator== but not equals.

- S == "foo" is more readable than S.equals("foo"), especially for
  !Long.Expression.equals("str") vs Long.Expression != "str".
2024-04-30 12:23:31 -07:00
Andreas Jonson
9a1386e5fa
[NFC] Remove method from FoldingSet that already existed in APInt. (#90486)
Noticed that there already was a function in APInt that updated a
FoldingSet so there was no need for me to add it in
https://github.com/llvm/llvm-project/pull/84617.
2024-04-30 09:42:31 +09:00
Andreas Jonson
b8f3024a31
[InstCombine] Swap out range metadata to range attribute for cttz/ctlz/ctpop (#88776)
Since all optimizations that use range metadata now also handle range attribute, this patch replaces writes of
range metadata for call instructions to range attributes.
2024-04-25 01:45:50 +08:00
Andreas Jonson
40282674e9
Reapply [IR] Add new Range attribute using new ConstantRange Attribute type (#84617)
The only change from https://github.com/llvm/llvm-project/pull/83171 is the
change of the allocator so the destructor is called for
ConstantRangeAttributeImpl.

reverts https://github.com/llvm/llvm-project/pull/84549
2024-03-09 19:47:43 +08:00
Florian Mayer
0861755e59
Revert "[IR] Add new Range attribute using new ConstantRange Attribute type" (#84549)
Reverts llvm/llvm-project#83171

broke sanitizer buildbot
https://lab.llvm.org/buildbot/#/builders/168/builds/19110/steps/10/logs/stdio
2024-03-08 12:12:35 -08:00
Andreas Jonson
e0d49066c1
[IR] Add new Range attribute using new ConstantRange Attribute type (#83171)
implementation as discussed in
https://discourse.llvm.org/t/rfc-metadata-attachments-for-function-arguments/76420
2024-03-08 23:20:04 +08:00
Dani
8eb6757564
[NFC] Turn the StrictFP attribute check to a CompatRule. (#82600) 2024-02-25 15:50:05 +01:00
Dani
6fae3e7844
[llvm][AArch64] Do not inline a function with different signing scheme. (#80642)
If the signing scheme is different that maybe the functions assumes
different behaviours and dangerous to inline them without analysing
them. This should be a rare case.
2024-02-23 09:30:36 +01:00
Nikita Popov
bf5d96c96c
[IR] Add dead_on_unwind attribute (#74289)
Add the `dead_on_unwind` attribute, which states that the caller will
not read from this argument if the call unwinds. This allows eliding
stores that could otherwise be visible on the unwind path, for example:

```
declare void @may_unwind()

define void @src(ptr noalias dead_on_unwind %out) {
    store i32 0, ptr %out
    call void @may_unwind()
    store i32 1, ptr %out
    ret void
}

define void @tgt(ptr noalias dead_on_unwind %out) {
    call void @may_unwind()
    store i32 1, ptr %out
    ret void
}
```

The optimization is not valid without `dead_on_unwind`, because the `i32
0` value might be read if `@may_unwind` unwinds.

This attribute is primarily intended to be used on sret arguments. In
fact, I previously wanted to change the semantics of sret to include
this "no read after unwind" property (see D116998), but based on the
feedback there it is better to keep these attributes orthogonal (sret is
an ABI attribute, dead_on_unwind is an optimization attribute). This is
a reboot of that change with a separate attribute.
2023-12-14 09:58:14 +01:00
Nikita Popov
6b8ed78719 [IR] Add writable attribute
This adds a writable attribute, which in conjunction with
dereferenceable(N) states that a spurious store of N bytes is
introduced on function entry. This implies that this many bytes
are writable without trapping or introducing data races. See
https://llvm.org/docs/Atomics.html#optimization-outside-atomic for
why the second point is important.

This attribute can be added to sret arguments. I believe Rust will
also be able to use it for by-value (moved) arguments. Rust likely
won't be able to use it for &mut arguments (tree borrows does not
appear to allow spurious stores).

In this patch the new attribute is only used by LICM scalar promotion.
However, the actual motivation for this is to fix a correctness issue
in call slot optimization, which needs this attribute to avoid
optimization regressions.

Followup to the discussion on D157499.

Differential Revision: https://reviews.llvm.org/D158081
2023-11-01 10:46:31 +01:00
Johannes Doerfert
a90ac20c52 [MemoryEffects][NFCI] Make the MemoryEffects class reusable
In a follow up we will reuse the logic in MemoryEffectsBase to merge
AAMemoryLocation and AAMemoryBehavior without duplicating all the bit
fiddling code already available in MemoryEffectsBase.

Reviewed By: nikic

Differential Revision: https://reviews.llvm.org/D153305
2023-07-03 10:07:03 -07:00
Elliot Goodrich
f0fa2d7c29 [llvm] Move AttributeMask to a separate header
Move `AttributeMask` out of `llvm/IR/Attributes.h` to a new file
`llvm/IR/AttributeMask.h`.  After doing this we can remove the
`#include <bitset>` and `#include <set>` directives from `Attributes.h`.
Since there are many headers including `Attributes.h`, but not needing
the definition of `AttributeMask`, this causes unnecessary bloating of
the translation units and slows down compilation.

This commit adds in the include directive for `llvm/IR/AttributeMask.h`
to the handful of source files that need to see the definition.

This reduces the total number of preprocessing tokens across the LLVM
source files in lib from (roughly) 1,917,509,187 to 1,902,982,273 - a
reduction of ~0.76%. This should result in a small improvement in
compilation time.

Differential Revision: https://reviews.llvm.org/D153728
2023-06-27 15:26:17 +01:00
Matt Arsenault
19293b82c1 Inline: Fix case of not inlining with denormal-fp-math-f32
This was failing to inline the opencl libraries with daz enabled. As a
modifier to the base mode, denormal-fp-mode-f32 is weird and has no
meaning if it's missing.
2023-06-09 19:09:48 -04:00
Matt Arsenault
bc37be1855 LangRef: Add "dynamic" option to "denormal-fp-math"
This is stricter than the default "ieee", and should probably be the
default. This patch leaves the default alone. I can change this in a
future patch.

There are non-reversible transforms I would like to perform which are
legal under IEEE denormal handling, but illegal with flushing zero
behavior. Namely, conversions between llvm.is.fpclass and fcmp with
zeroes.

Under "ieee" handling, it is legal to translate between
llvm.is.fpclass(x, fcZero) and fcmp x, 0.

Under "preserve-sign" handling, it is legal to translate between
llvm.is.fpclass(x, fcSubnormal|fcZero) and fcmp x, 0.

I would like to compile and distribute some math library functions in
a mode where it's callable from code with and without denormals
enabled, which requires not changing the compares with denormals or
zeroes.

If an IEEE function transforms an llvm.is.fpclass call into an fcmp 0,
it is no longer possible to call the function from code with denormals
enabled, or write an optimization to move the function into a denormal
flushing mode. For the original function, if x was a denormal, the
class would evaluate to false. If the function compiled with denormal
handling was converted to or called from a preserve-sign function, the
fcmp now evaluates to true.

This could also be of use for strictfp handling, where code may be
changing the denormal mode.

Alternative name could be "unknown".

Replaces the old AMDGPU custom inlining logic with more conservative
logic which tries to permit inlining for callees with dynamic handling
and avoids inlining other mismatched modes.
2023-04-29 08:44:59 -04:00
Matt Arsenault
dd81810554 clang: Emit nofpclass(nan inf) for -ffinite-math-only
Set this on any source level floating-point type argument,
return value, call return or outgoing parameter which is lowered
to a valid IR type for the attribute. Currently this isn't
applied to emitted intrinsics since those don't go through
ABI code.
2023-03-15 01:13:08 -04:00
Matt Arsenault
0eb59cab95 ADT: Move FPClassTest printing functions to common place 2023-03-03 18:20:47 -04:00
Matt Arsenault
5da674492a IR: Add nofpclass parameter attribute
This carries a bitmask indicating forbidden floating-point value kinds
in the argument or return value. This will enable interprocedural
-ffinite-math-only optimizations. This is primarily to cover the
no-nans and no-infinities cases, but also covers the other floating
point classes for free. Textually, this provides a number of names
corresponding to bits in FPClassTest, e.g.

  call nofpclass(nan inf) @must_be_finite()
  call nofpclass(snan) @cannot_be_snan()

This is more expressive than the existing nnan and ninf fast math
flags. As an added bonus, you can represent fun things like nanf:

  declare nofpclass(inf zero sub norm) float @only_nans()

Compared to nnan/ninf:
  - Can be applied to individual call operands as well as the return value
  - Can distinguish signaling and quiet nans
  - Distinguishes the sign of infinities
  - Can be safely propagated since it doesn't imply anything about
    other operands.
  - Does not apply to FP instructions; it's not a flag

This is one step closer to being able to retire "no-nans-fp-math" and
"no-infs-fp-math". The one remaining situation where we have no way to
represent no-nans/infs is for loads (if we wanted to solve this we
could introduce !nofpclass metadata, following along with
noundef/!noundef).

This is to help simplify the GPU builtin math library
distribution. Currently the library code has explicit finite math only
checks, read from global constants the compiler driver needs to set
based on the compiler flags during linking. We end up having to
internalize the library into each translation unit in case different
linked modules have different math flags. By propagating known-not-nan
and known-not-infinity information, we can automatically prune the
edge case handling in most functions if the function is only reached
from fast math uses.
2023-02-24 07:41:29 -04:00
Nikita Popov
9afb6360fc [Attributes] Avoid duplicate hasAttribute() query (NFC)
removeAttribute() already performs a hasAttribute() check, so no
need to also do it in the caller. Instead check whether the
attribute set was changed.

This makes the implementations in line with removeAttributesAtIndex().
2023-01-09 12:59:16 +01:00
Nikita Popov
b24909c4c7 [Attributes] Avoid repeated attribute set lookup (NFC)
Perform the hasAttribute() check on the AttributeSet we need to
fetch anyway, rather than going through hasAttributeAtIndex().
2023-01-09 11:58:06 +01:00
Nikita Popov
66dcb86b8b [Attributes] Remove trailing empty attribute sets (PR59746)
In setAttributesAtIndex(), remove any trailing empty attribute sets.
Also make sure that all the different attribute removal APIs go
through that method.

Fixes https://github.com/llvm/llvm-project/issues/59746.
2023-01-05 17:14:37 +01:00
serge-sans-paille
38818b60c5
Move from llvm::makeArrayRef to ArrayRef deduction guides - llvm/ part
Use deduction guides instead of helper functions.

The only non-automatic changes have been:

1. ArrayRef(some_uint8_pointer, 0) needs to be changed into ArrayRef(some_uint8_pointer, (size_t)0) to avoid an ambiguous call with ArrayRef((uint8_t*), (uint8_t*))
2. CVSymbol sym(makeArrayRef(symStorage)); needed to be rewritten as CVSymbol sym{ArrayRef(symStorage)}; otherwise the compiler is confused and thinks we have a (bad) function prototype. There was a few similar situation across the codebase.
3. ADL doesn't seem to work the same for deduction-guides and functions, so at some point the llvm namespace must be explicitly stated.
4. The "reference mode" of makeArrayRef(ArrayRef<T> &) that acts as no-op is not supported (a constructor cannot achieve that).

Per reviewers' comment, some useless makeArrayRef have been removed in the process.

This is a follow-up to https://reviews.llvm.org/D140896 that introduced
the deduction guides.

Differential Revision: https://reviews.llvm.org/D140955
2023-01-05 14:11:08 +01:00
Kazu Hirata
e842c06c2d [IR] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-02 20:05:20 -08:00
Krzysztof Parzyszek
26424c96c0 Attributes: convert Optional to std::optional 2022-12-02 08:15:45 -06:00
Kazu Hirata
589725f6e8 [llvm] Use std::size (NFC)
std::size, introduced in C++17, allows us to directly obtain the
number of elements of an array.
2022-11-26 13:47:32 -08:00
Nikita Popov
feda983ff8 [TableGen] Use MemoryEffects to represent intrinsic memory effects (NFCI)
The TableGen implementation was using a homegrown implementation of
FunctionModRefInfo. This switches it to use MemoryEffects instead.
This makes the code simpler, and will allow exposing the full
representational power of MemoryEffects in the future. Among other
things, this will allow us to map IntrHasSideEffects to an
inaccessiblemem readwrite, rather than just ignoring it entirely
in most cases.

To avoid layering issues, this moves the ModRef.h header from IR
to Support, so that it can be included in the TableGen layer.

Differential Revision: https://reviews.llvm.org/D137641
2022-11-14 10:52:04 +01:00
Nikita Popov
a2ab8fc46c [Attributes] Add additional MemoryEffects APIs (NFC)
This adds the usual complement of APIs for creating and fetching
a non-trivial attribute.

Split out from D135780.
2022-10-31 10:44:51 +01:00
Nikita Popov
e9754f0211 [IR] Add support for memory attribute
This implements IR and bitcode support for the memory attribute,
as specified in https://reviews.llvm.org/D135597.

The new attribute is not used for anything yet (and as such, the
old memory attributes are unaffected).

Differential Revision: https://reviews.llvm.org/D135592
2022-10-21 12:11:25 +02:00
Nikita Popov
ac47db6aca [Attributes] Return Optional from getAllocSizeArgs() (NFC)
As suggested on D135572, return Optional<> from getAllocSizeArgs()
rather than the peculiar pair(0, 0) sentinel.

The method on Attribute itself does not return Optional, because
the attribute must exist in that case.
2022-10-11 11:05:21 +02:00
Nikita Popov
256976774f [Attributes] Support int attributes with zero value
This regularly comes up as a stumbling stone when adding int
attributes: They currently need to be encoded in a way to avoids
the zero value.

This adds support for zero-value int attributes by a) making the
ctor determine int/enum attribute based on attribute kind, not
whether the value is non-zero and b) switching getRawIntAttr()
to return an Optional, so that it's possible to distinguish a zero
value from non-existence.

Differential Revision: https://reviews.llvm.org/D135572
2022-10-11 10:38:27 +02:00
Nikita Popov
24b1340ff9 [AttrBuilder] Remove unused vscale accessors (NFC)
These accessors are not used. Generally, nowadays it is preferable
to perform queries on AttributeSets/Lists, rather than the
AttrBuilder, which is optimized towards attribute construction now.
2022-10-11 10:33:33 +02:00
Nikita Popov
454722745b [Attributes] Remove AttrBuilder::hasAlignmentAttr() method (NFC)
This was the odd one out, with similar methods not existing for
any other attributes. In the places where it is used, it is best
replaced by AttrBuilder::getAttribute(), which allows us to both
test for presence of the attribute and retrieve its value at the
same time. (To just check for presence, contains() could be used.)
2022-10-11 09:56:37 +02:00