Add option and statement attribute for controlling emitting of
target-specific
metadata to atomicrmw instructions in IR.
The RFC for this attribute and option is
https://discourse.llvm.org/t/rfc-add-clang-atomic-control-options-and-pragmas/80641,
Originally a pragma was proposed, then it was changed to clang
attribute.
This attribute allows users to specify one, two, or all three options
and must be applied
to a compound statement. The attribute can also be nested, with inner
attributes
overriding the options specified by outer attributes or the target's
default
options. These options will then determine the target-specific metadata
added to atomic
instructions in the IR.
In addition to the attribute, three new compiler options are introduced:
`-f[no-]atomic-remote-memory`, `-f[no-]atomic-fine-grained-memory`,
`-f[no-]atomic-ignore-denormal-mode`.
These compiler options allow users to override the default options
through the
Clang driver and front end. `-m[no-]unsafe-fp-atomics` is aliased to
`-f[no-]ignore-denormal-mode`.
In terms of implementation, the atomic attribute is represented in the
AST by the
existing AttributedStmt, with minimal changes to AST and Sema.
During code generation in Clang, the CodeGenModule maintains the current
atomic options,
which are used to emit the relevant metadata for atomic instructions.
RAII is used
to manage the saving and restoring of atomic options when entering
and exiting nested AttributedStmt.
- Adding the changes from PRs:
- #116331
- #121852
- Fixes test `tools/dxil-dis/debug-info.ll`
- Address some missed comments in the previous PR
---------
Co-authored-by: joaosaffran <joao.saffran@microsoft.com>
- adding Flatten and Branch to if stmt.
- adding dxil control flow hint metadata generation
- modifing spirv OpSelectMerge to account for the specific attributes.
Closes#70112
---------
Co-authored-by: Joao Saffran <jderezende@microsoft.com>
Co-authored-by: joaosaffran <joao.saffran@microsoft.com>
By allowing AnnotateAttr to be applied to statements, users can place arbitrary information in the AST for later use.
For example, this can be used for HW-targeted language extensions that involve specialized loop annotations.
- For languages following SPMD/SIMT programming model, functions and
call sites are marked 'convergent' by default. 'noconvergent' is added
in this patch to allow developers to remove that 'convergent'
attribute when it's safe.
Reviewers:
nhaehnle, Sirraide, yxsamliu, Artem-B, ilovepi, jayfoad, ssahasra, arsenm
Reviewed By: arsenm
Pull Request: https://github.com/llvm/llvm-project/pull/100637
In 92fc1eb0c1ae3813f2ac9208e2c74207aae9d23 the HLSLLoopHint attribute
was added with an 'unroll' spelling. There is an existing LoopHint
attribute with the same spelling. These attributes have different
arguments.
The tablegen used to produce checks on arguments uses only the attribute
name, making it impossible to return correct info for attribute with
different argument types but the same name.
Improve the situation by using a 'full' name that combines the syntax,
scope, and name. This allows, for example, #pragma unroll and
[[unroll(x)]] to coexist correctly even with different argument types.
Also fix a bug in the StrictEnumParameters tablegen. If will now
correctly specify each parameter instead of only the first.
This is a followup to #81014 and #84582: Before this patch, Clang
would accept `__attribute__((assume))` and `[[clang::assume]]` as
nonstandard spellings for the `[[omp::assume]]` attribute; this
resulted in a potentially very confusing name clash with C++23’s
`[[assume]]` attribute (and GCC’s `assume` attribute with the same
semantics).
This pr replaces every usage of `__attribute__((assume))` with
`[[omp::assume]]` and makes `__attribute__((assume))` and
`[[clang::assume]]` alternative spellings for C++23’s `[[assume]]`;
this shouldn’t cause any problems due to differences in appertainment
and because almost no-one was using this variant spelling to begin
with (a use in libclc has already been changed to use a different
attribute).
PR https://github.com/llvm/llvm-project/pull/89567 fix the `#pragma
unroll N` crash issue in dependent context, but it's introduce an new
issue:
Since https://github.com/llvm/llvm-project/pull/89567, if `N` is value
dependent, 'option' and 'state' were ` (LoopHintAttr::Unroll,
LoopHintAttr::Enable)`. Therefor, clang's code generator generated
incorrect IR metadata.
For the situation `#pragma {GCC} unroll {0|1}`, before template
instantiation, this PR tweak the 'option' to `LoopHintAttr::UnrollCount`
and 'state' to `LoopHintAttr::Numeric`. During template instantiation
and if unroll count is 0 or 1 this PR tweak 'option' to
`LoopHintAttr::Unroll` and 'state' to `LoopHintAttr::Disable`. We don't
use `LoopHintAttr::UnrollCount` here because it's will emit an redundant
LLVM IR metadata `!{!"llvm.loop.unroll.count", i32 1}` when unroll count
is 1.
---------
Signed-off-by: yronglin <yronglin777@gmail.com>
https://github.com/llvm/llvm-project/pull/70762 added support for new
loop attribute [[clang::code_align()]].
This patch fixes bugs for the test cases below that misses diagnostics due to discontinue to while loop during checking duplicate vs conflicting code_align attribute values in routine CheckForDuplicateLoopAttrs().
[[clang::code_align(4)]]
[[clang::code_align(4)]]
[[clang::code_align(8)]]
for(int I=0; I<128; ++I) { bar(I); }
[[clang::code_align(4)]]
[[clang::code_align(4)]]
[[clang::code_align(8)]]
[[clang::code_align(32)]]
for(int I=0; I<128; ++I) { bar(I); }
This implements the C++23 `[[assume]]` attribute.
Assumption information is lowered to a call to `@llvm.assume`, unless the expression has side-effects, in which case it is discarded and a warning is issued to tell the user that the assumption doesn’t do anything. A failed assumption at compile time is an error (unless we are in `MSVCCompat` mode, in which case we don’t check assumptions at compile time).
Due to performance regressions in LLVM, assumptions can be disabled with the `-fno-assumptions` flag. With it, assumptions will still be parsed and checked, but no calls to `@llvm.assume` will be emitted and assumptions will not be checked at compile time.
This patch renames CheckForDuplicateCodeAlignAttrs() to
CheckForDuplicateLoopAttrs() and corresponding other functions that call
it to be used for other statement attributes in future.
The new attribute can be placed on statements in order to suppress
arbitrary warnings produced by static analysis tools at those statements.
Previously such suppressions were implemented as either informal comments
(eg. clang-tidy `// NOLINT:`) or with preprocessor macros (eg.
clang static analyzer's `#ifdef __clang_analyzer__`). The attribute
provides a universal, formal, flexible and neat-looking suppression mechanism.
Implement support for the new attribute in the clang static analyzer;
clang-tidy coming soon.
The attribute allows specifying which specific warnings to suppress,
in the form of free-form strings that are intended to be specific to
the tools, but currently none are actually supported; so this is also
going to be a future improvement.
Differential Revision: https://reviews.llvm.org/D93110
This commit introduces support for the MSVC-specific C++11-style
attribute `[[msvc::constexpr]]`, which was introduced in MSVC 14.33.
The semantics of this attribute are enabled only under
MSVC compatibility (`-fms-compatibility-version`) 14.33 and higher.
Additionally, the default value of `_MSC_VER` has been raised to 1433.
The current implementation lacks support for:
- `[[msvc::constexpr]]` constructors (see #72149);
at the time of this implementation, such support would have required
an unreasonable number of changes in Clang.
- `[[msvc::constexpr]] return ::new` (constexpr placement new) from
non-std namespaces (see #74924).
Relevant to: #57696
This patch adds support for new loop attribute:
[[clang::code_align(N)]].
This attribute applies to a loop and specifies the byte alignment for a
loop.
The attribute accepts a positive integer constant initialization
expression
indicating the number of bytes for the minimum alignment boundary.
Its value must be a power of 2, between 1 and 4096 (inclusive).
This patch adds the Parse and Sema support for RegularKeyword attributes,
following on from a previous patch that added Attr.td support.
The patch is quite large. However, nothing outside the tests is
specific to the first RegularKeyword attribute (__arm_streaming).
The patch should therefore be a one-off, up-front cost. Other
attributes just need an entry in Attr.td and the usual Sema support.
The approach taken in the patch is that the keywords can be used with
any language version. If standard attributes were added in language
version Y, the keyword rules for version X<Y are the same as they were
for version Y (to the extent possible). Any extensions beyond Y are
handled in the same way for both keywords and attributes. This ensures
that existing C++11 successors like C++17 are not treated differently
from versions that have yet to be defined.
Some notes on the implementation:
* The patch emits errors rather than warnings for diagnostics that
relate to keywords.
* Where possible, the patch drops “attribute” from diagnostics
relating to keywords.
* One exception to the previous point is that warnings about C++
extensions do still mention attributes. The use there seemed OK
since the diagnostics are noting a change in the production rules.
* If a diagnostic string needs to be different for keywords and
attributes, the patch standardizes on passing the attribute/
name/token followed by 0 for attributes and 1 for keywords.
* Although the patch updates warn_attribute_wrong_decl_type_str,
warn_attribute_wrong_decl_type, and warn_attribute_wrong_decl_type,
only the error forms of these strings are used for keywords.
* I couldn't trigger the warnings in checkUnusedDeclAttributes,
even for existing attributes. An assert on the warnings caused
no failures in the testsuite. I think in practice all standard
attributes would be diagnosed before this.
* The patch drops a call to standardAttributesAllowed in
ParseFunctionDeclarator. This is because MaybeParseCXX11Attributes
checks the same thing itself, where appropriate.
* The new tests are based on c2x-attributes.c and
cxx0x-attributes.cpp. The C++ test also incorporates a version of
cxx11-base-spec-attributes.cpp. The FIXMEs are carried across from
the originals.
Differential Revision: https://reviews.llvm.org/D148702
Reported by Coverity:
AUTO_CAUSES_COPY
Unnecessary object copies can affect performance.
1. [NFC] Fix auto keyword use without an & causes the copy of an object of type SimpleRegistryEntry in clang::getAttributePluginInstances()
2. [NFC] Fix auto keyword use without an & causes the copy of an object of type tuple in CheckStmtInlineAttr<clang::NoInlineAttr, 2>(clang::Sema &, clang::Stmt const *, clang::Stmt const *, clang::AttributeCommonInfo const &)
3. [NFC] Fix auto keyword use without an & causes the copy of an object of type QualType in <unnamed>::SystemZTargetCodeGenInfo::isVectorTypeBased(clang::Type const *, bool)
4. [NFC] Fix auto keyword use without an & causes the copy of an object of type Policy in <unnamed>::RISCVIntrinsicManagerImpl::InitIntrinsicList()
5. [NFC] Fix auto keyword use without an & causes the copy of an object of type pair in checkUndefinedButUsed(clang::Sema &)
Reviewed By: tahonermann
Differential Revision: <https://reviews.llvm.org/D147543>
D146089's author discovered that our diagnostics for always/no inline
would null-dereference when used in a template. He fixed that by
skipping in the dependent case.
This patch makes sure we diagnose these after a template instantiation.
It also adds infrastructure for other statement attributes to add
checking/transformation.
Differential Revision: https://reviews.llvm.org/D146323
Remove use of constexpr if that failed on the build bots.
Original commit message:
It's possible for `getCalleeDecl()` to return a null pointer.
This was encountered by a user of our downstream compiler.
The case involved a DependentScopeDeclRefExpr.
Since this seems to only be for a warning diagnostic, I skipped
the diagnostic check if it returned null. But mabye there's a
different way to fix this.
It's possible for `getCalleeDecl()` to return a null pointer.
This was encountered by a user of our downstream compiler.
The case involved a DependentScopeDeclRefExpr.
Since this seems to only be for a warning diagnostic, I skipped
the diagnostic check if it returned null. But mabye there's a
different way to fix this.
Reviewed By: erichkeane
Differential Revision: https://reviews.llvm.org/D146089
This change would allow extension of new categories be aware of adding
more code here.
This patch also updates the comments, which was originally missing the
vector predicate.
Reviewed By: mikerice
Differential Revision: https://reviews.llvm.org/D137570
This revision fixes typos where there are 2 consecutive words which are
duplicated. There should be no code changes in this revision (only
changes to comments and docs). Do let me know if there are any
undesirable changes in this revision. Thanks.
Move the SourceRange from the old ParsedAttributesWithRange into
ParsedAttributesView, so we have source range information available
everywhere we use attributes.
This also removes ParsedAttributesWithRange (replaced by simply using
ParsedAttributes) and ParsedAttributesVieWithRange (replaced by using
ParsedAttributesView).
Differential Revision: https://reviews.llvm.org/D121201
Motivation:
```
int test(int x, int y) {
int r = 0;
[[clang::always_inline]] r += foo(x, y); // force compiler to inline this function here
return r;
}
```
In 2018, @kuhar proposed "Introduce per-callsite inline intrinsics" in https://reviews.llvm.org/D51200 to solve this motivation case (and many others).
This patch solves this problem with call site attribute. "noinline" statement attribute already landed in D119061. Also, some LLVM Inliner fixes landed so call site attribute is stronger than function attribute.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D120717
Motivation:
```
int foo(int x, int y) { // any compiler will happily inline this function
return x / y;
}
int test(int x, int y) {
int r = 0;
[[clang::noinline]] r += foo(x, y); // for some reason we don't want any inlining here
return r;
}
```
In 2018, @kuhar proposed "Introduce per-callsite inline intrinsics" in https://reviews.llvm.org/D51200 to solve this motivation case (and many others).
This patch solves this problem with call site attribute. The implementation is "smaller" wrt approach which uses new intrinsics and thanks to https://reviews.llvm.org/D79121 (Add nomerge statement attribute to clang), we have got some basic infrastructure to deal with attrs on statements with call expressions.
GCC devs are more inclined to call attribute solution as well, as builtins are problematic for them - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104187. But they have no patch proposal yet so.. We have free hands here.
If this approach makes sense, next future steps would be support for call site attributes for always_inline / flatten.
Reviewed By: aaron.ballman, kuhar
Differential Revision: https://reviews.llvm.org/D119061
This is a Clang-only change and depends on the existing "musttail"
support already implemented in LLVM.
The [[clang::musttail]] attribute goes on a return statement, not
a function definition. There are several constraints that the user
must follow when using [[clang::musttail]], and these constraints
are verified by Sema.
Tail calls are supported on regular function calls, calls through a
function pointer, member function calls, and even pointer to member.
Future work would be to throw a warning if a users tries to pass
a pointer or reference to a local variable through a musttail call.
Reviewed By: rsmith
Differential Revision: https://reviews.llvm.org/D99517
The previous implementation was insufficient for checking statement
attribute mutual exclusion because attributed statements do not collect
their attributes one-at-a-time in the same way that declarations do. So
the design that was attempting to check for mutual exclusion as each
attribute was processed would not ever catch a mutual exclusion in a
statement. This was missed due to insufficient test coverage, which has
now been added for the [[likely]] and [[unlikely]] attributes.
The new approach is to check all of attributes that are to be applied
to the attributed statement in a group. This required generating
another DiagnoseMutualExclusions() function into AttrParsedAttrImpl.inc.
This changes our approach to processing statement attributes to be more
similar to how we process declaration attributes. Namely,
ActOnAttributedStmt() now calls ProcessStmtAttributes() instead of
vice-versa, and there is now an interface split between building an
attributed statement where you already have a list of semantic
attributes and building an attributed statement with attributes from
the parser.
This should make it easier to support statement attributes that are
dependent on a template. In that case, you would add a
TransformFooAttr() function in TreeTransform.h to perform the semantic
checking (morally similar to how Sema::InstantiateAttrs() already works
for declaration attributes) when transforming the semantic attribute at
instantiation time.
Currently, when one or more attributes are mutually exclusive, the
developer adding the attribute has to manually emit diagnostics. In
practice, this is highly error prone, especially for declaration
attributes, because such checking is not trivial. Redeclarations
require you to write a "merge" function to diagnose mutually exclusive
attributes and most attributes get this wrong.
This patch introduces a table-generated way to specify that a group of
two or more attributes are mutually exclusive:
def : MutualExclusions<[Attr1, Attr2, Attr3]>;
This works for both statement and declaration attributes (but not type
attributes) and the checking is done either from the common attribute
diagnostic checking code or from within mergeDeclAttribute() when
merging redeclarations.
Clang currently automates a fair amount of diagnostic checking for
declaration attributes based on the declarations in Attr.td. It checks
for things like subject appertainment, number of arguments, language
options, etc. This patch uses the same machinery to perform diagnostic
checking on statement attributes.
The attribute definition claimed the attribute was inheritable (which
only applies to declaration attributes) and not a statement attribute.
Further, it treats subject appertainment errors as being parse errors
rather than semantic errors, which leads to us accepting invalid code.
For instance, we currently fail to reject:
void foo() {
int i = 1000;
__attribute__((nomerge, opencl_unroll_hint(8)))
if (i) { foo(); }
}
This addresses the issues by clarifying that opencl_unroll_hint is a
statement attribute and handles its appertainment checks in the
semantic layer instead of the parsing layer. This changes the output of
the diagnostic text to be more consistent with other appertainment
errors.
This patch adds support for two new variants of the vectorize_width
pragma:
1. vectorize_width(X[, fixed|scalable]) where an optional second
parameter is passed to the vectorize_width pragma, which indicates if
the user wishes to use fixed width or scalable vectorization. For
example the user can now write something like:
#pragma clang loop vectorize_width(4, fixed)
or
#pragma clang loop vectorize_width(4, scalable)
In the absence of a second parameter it is assumed the user wants
fixed width vectorization, in order to maintain compatibility with
existing code.
2. vectorize_width(fixed|scalable) where the width is left unspecified,
but the user hints what type of vectorization they prefer, either
fixed width or scalable.
I have implemented this by making use of the LLVM loop hint attribute:
llvm.loop.vectorize.scalable.enable
Tests were added to
clang/test/CodeGenCXX/pragma-loop.cpp
for both the 'fixed' and 'scalable' optional parameter.
See this thread for context: http://lists.llvm.org/pipermail/cfe-dev/2020-November/067262.html
Differential Revision: https://reviews.llvm.org/D89031
This is the initial part of the implementation of the C++20 likelihood
attributes. It handles the attributes in an if statement.
Differential Revision: https://reviews.llvm.org/D85091
Reapply 49e5f603d40083dce9c05796e3cde3a185c3beba
which had been reverted in c94332919bd922032e979b3ae3ced5ca5bdf9650.
Originally reverted because I hadn't updated it in quite a while when I
got around to committing it, so there were a bunch of missing changes to
new code since I'd written the patch.
Reviewers: aaron.ballman
Differential Revision: https://reviews.llvm.org/D76646