[clang] [llvm] [AMDGPU] Emit a waitcnt instruction after each memory instruction (PR #79236)
https://github.com/Pierre-vh approved this pull request. LGTM, but wait for @t-tye or @jayfoad to approve as well https://github.com/llvm/llvm-project/pull/79236 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/83108 >From 59e1880df74434e3c446705788d92b5949d99536 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Sun, 7 Jan 2018 15:16:11 +0200 Subject: [PATCH 1/3] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. --- clang/include/clang/AST/DeclTemplate.h| 36 - clang/lib/AST/DeclTemplate.cpp| 96 +-- clang/lib/AST/ODRHash.cpp | 15 clang/lib/Serialization/ASTReader.cpp | 25 -- clang/lib/Serialization/ASTReaderDecl.cpp | 36 ++--- clang/lib/Serialization/ASTWriter.cpp | 21 - clang/lib/Serialization/ASTWriterDecl.cpp | 74 ++--- 7 files changed, 242 insertions(+), 61 deletions(-) diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index e3b6a7efb1127a..4ed9b58d4ff609 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -256,6 +256,9 @@ class TemplateArgumentList final TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// Create hash for the given arguments. + static unsigned ComputeODRHash(ArrayRef Args); + /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, @@ -730,6 +733,26 @@ class RedeclarableTemplateDecl : public TemplateDecl, } void anchor() override; + struct LazySpecializationInfo { +uint32_t DeclID = ~0U; +unsigned ODRHash = ~0U; +bool IsPartial = false; +LazySpecializationInfo(uint32_t ID, unsigned Hash = ~0U, + bool Partial = false) + : DeclID(ID), ODRHash(Hash), IsPartial(Partial) { } +LazySpecializationInfo() { } +bool operator<(const LazySpecializationInfo &Other) const { + return DeclID < Other.DeclID; +} +bool operator==(const LazySpecializationInfo &Other) const { + assert((DeclID != Other.DeclID || ODRHash == Other.ODRHash) && + "Hashes differ!"); + assert((DeclID != Other.DeclID || IsPartial == Other.IsPartial) && + "Both must be the same kinds!"); + return DeclID == Other.DeclID; +} + }; + protected: template struct SpecEntryTraits { using DeclType = EntryType; @@ -770,7 +793,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + void loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; + + Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const; template typename SpecEntryTraits::DeclType* @@ -797,7 +825,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// /// The first value in the array is the number of specializations/partial /// specializations that follow. -uint32_t *LazySpecializations = nullptr; +LazySpecializationInfo *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -2268,7 +2296,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { @@ -3039,7 +3067,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { friend class ASTDeclWriter; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 3c217d6a6a5ae3..1babe39ee2a7e5 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -20,6 +20,8 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" +#include "clang/AST/ODRHash.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/LLVM.h" @@ -331,16 +333,43 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c return Common; } -void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { +void RedeclarableTemplateDecl::loadLazySpecializationsImpl( + bool Onl
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
vgvassilev wrote: > Weird. I only see two failures in my local environment: > > ``` > Failed Tests (2): > Clang :: Modules/cxx-templates.cpp > Clang :: Modules/odr_hash.cpp > ``` > > And I saw both of them in my patch. It is simply order mismatches. Ha, ok. I know that my system constantly have some tests that fail even fro the master but I thought these were real. If we don't see them in the bots then that's probably a problem only on my side... https://github.com/llvm/llvm-project/pull/83108 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Support local-dynamic TLS relocation on AIX (PR #66316)
orcguru wrote: > A question: For `PPCTLSDynamicCall.cpp`, would it be better if we instead > reworded some of the sentences and not use `Load*@toc`? > > I thought about this for a bit and I think the full sentences may be a bit > better, so I added some sample comment suggestions, but if you think keeping > the `Load*@toc` in the comments is better and more clear, then I think you > can feel free to disregard the suggestion. However, if we are keeping the > `Load*@toc`, it might be better to capitalize `TOC` instead. Updated according to the suggestions. Thank you! https://github.com/llvm/llvm-project/pull/66316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Fix `cppcoreguidelines-missing-std-forward` false positive for deleted functions (PR #83055)
@@ -134,6 +134,10 @@ Changes in existing checks ` check by ignoring local variable with ``[maybe_unused]`` attribute. +- Fixed :doc:`cppcoreguidelines-missing-std-forward + ` check giving false + positives for deleted functions. + AMS21 wrote: Sure looks more consistent :) https://github.com/llvm/llvm-project/pull/83055 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Fix `cppcoreguidelines-missing-std-forward` false positive for deleted functions (PR #83055)
https://github.com/AMS21 updated https://github.com/llvm/llvm-project/pull/83055 >From 821fbb9c197982d929cced2ad2ad4bbde8195889 Mon Sep 17 00:00:00 2001 From: AMS21 Date: Mon, 26 Feb 2024 21:45:12 +0100 Subject: [PATCH] [clang-tidy] Fix `cppcoreguidelines-missing-std-forward` false positive for deleted functions A definition like this: ```cpp template void f(T &&) = delete; ``` would previously generate the the following output: ```sh :2:12: warning: forwarding reference parameter '' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward] 2 | void f(T &&) = delete; |^ 1 warning generated. ``` [godbolt](https://godbolt.org/z/9d4Y9qeWW) which is obviously not correct and this simple patch fixes that. --- .../cppcoreguidelines/MissingStdForwardCheck.cpp | 3 ++- clang-tools-extra/docs/ReleaseNotes.rst | 4 .../cppcoreguidelines/missing-std-forward.cpp | 15 +++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp index 370de12999aceb..c633683570f748 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/MissingStdForwardCheck.cpp @@ -127,7 +127,8 @@ void MissingStdForwardCheck::registerMatchers(MatchFinder *Finder) { hasAncestor(functionDecl().bind("func")), hasAncestor(functionDecl( isDefinition(), equalsBoundNode("func"), ToParam, - unless(hasDescendant(std::move(ForwardCallMatcher)), + unless(anyOf(isDeleted(), hasDescendant(std::move( +ForwardCallMatcher))), this); } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index 69537964f9bce0..3f90e7d63d6b23 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -134,6 +134,10 @@ Changes in existing checks ` check by ignoring local variable with ``[maybe_unused]`` attribute. +- Improved :doc:`cppcoreguidelines-missing-std-forward + ` check by no longer + giving false positives for deleted functions. + - Cleaned up :doc:`cppcoreguidelines-prefer-member-initializer ` by removing enforcement of rule `C.48 diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/missing-std-forward.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/missing-std-forward.cpp index 443f338ba2046a..20e43f04180ff3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/missing-std-forward.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/missing-std-forward.cpp @@ -173,3 +173,18 @@ void lambda_value_reference_auxiliary_var(T&& t) { } } // namespace negative_cases + +namespace deleted_functions { + +template +void f(T &&) = delete; + +struct S { +template +S(T &&) = delete; + +template +void operator&(T &&) = delete; +}; + +} // namespace deleted_functions ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Handle placeholders in '.*' expressions (PR #83103)
Sirraide wrote: Lastly, it also seems weird to me that a function called `CreateOverloadedBinOp()` is called to handle `.*`—an operator that can’t be overloaded—but seeing as this function has apparently been handling this case for over a decade now, I’m probably not going to question this any further. https://github.com/llvm/llvm-project/pull/83103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
ChuanqiXu9 wrote: Weird. I only see two failures in my local environment: ``` Failed Tests (2): Clang :: Modules/cxx-templates.cpp Clang :: Modules/odr_hash.cpp ``` And I saw both of them in my patch. It is simply order mismatches. https://github.com/llvm/llvm-project/pull/83108 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
vgvassilev wrote: > Personally I feel this patch is good and the testing result from our workload > shows it is good too. But it looks like the performance testing results from > google @zygoloid @ilya-biryukov is not good. So maybe we need to wait for > landing this. (It will be great if @ilya-biryukov would like to test again) Thanks for putting this up. I was planning to do so, however, locally I got: ``` Clang :: CXX/module/basic/basic.link/p2.cppm Clang :: Driver/clang_f_opts.c Clang :: Driver/darwin-header-search-libcxx.cpp Clang :: Index/crash-recovery-modules.m Clang :: Modules/ExtDebugInfo.cpp Clang :: Modules/cxx-templates.cpp Clang :: Modules/odr_hash.cpp Clang :: Modules/using-directive-redecl.cpp Clang :: Modules/using-directive.cpp Clang :: PCH/chain-late-anonymous-namespace.cpp Clang :: PCH/cxx-namespaces.cpp Clang :: PCH/namespaces.cpp ``` I believe some tests require just adjusting the reference files, but others may need some debugging. https://github.com/llvm/llvm-project/pull/83108 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 1ecbab56dcbb78268c8d19af34a50591f90b12a0 59e1880df74434e3c446705788d92b5949d99536 -- clang/include/clang/AST/DeclTemplate.h clang/lib/AST/DeclTemplate.cpp clang/lib/AST/ODRHash.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/ASTWriterDecl.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 4ed9b58d4f..51caef54ba 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -739,8 +739,8 @@ class RedeclarableTemplateDecl : public TemplateDecl, bool IsPartial = false; LazySpecializationInfo(uint32_t ID, unsigned Hash = ~0U, bool Partial = false) - : DeclID(ID), ODRHash(Hash), IsPartial(Partial) { } -LazySpecializationInfo() { } +: DeclID(ID), ODRHash(Hash), IsPartial(Partial) {} +LazySpecializationInfo() {} bool operator<(const LazySpecializationInfo &Other) const { return DeclID < Other.DeclID; } diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 1babe39ee2..aa2368783d 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -16,12 +16,12 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/ODRHash.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" -#include "clang/AST/ODRHash.h" -#include "clang/AST/ExprCXX.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/LLVM.h" @@ -334,7 +334,7 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c } void RedeclarableTemplateDecl::loadLazySpecializationsImpl( - bool OnlyPartial/*=false*/) const { +bool OnlyPartial /*=false*/) const { // Grab the most recent declaration to ensure we've loaded any lazy // redeclarations of this template. CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); @@ -343,16 +343,16 @@ void RedeclarableTemplateDecl::loadLazySpecializationsImpl( CommonBasePtr->LazySpecializations = nullptr; for (uint32_t I = 0, N = Specs[0].DeclID; I != N; ++I) { // Skip over already loaded specializations. - if (!Specs[I+1].ODRHash) + if (!Specs[I + 1].ODRHash) continue; - if (!OnlyPartial || Specs[I+1].IsPartial) -(void)loadLazySpecializationImpl(Specs[I+1]); + if (!OnlyPartial || Specs[I + 1].IsPartial) +(void)loadLazySpecializationImpl(Specs[I + 1]); } } } Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl( - LazySpecializationInfo &LazySpecInfo) const { +LazySpecializationInfo &LazySpecInfo) const { uint32_t ID = LazySpecInfo.DeclID; assert(ID && "Loading already loaded specialization!"); // Note that we loaded the specialization. @@ -360,16 +360,14 @@ Decl *RedeclarableTemplateDecl::loadLazySpecializationImpl( return getASTContext().getExternalSource()->GetExternalDecl(ID); } -void -RedeclarableTemplateDecl::loadLazySpecializationsImpl(ArrayRef - Args, - TemplateParameterList *TPL) const { +void RedeclarableTemplateDecl::loadLazySpecializationsImpl( +ArrayRef Args, TemplateParameterList *TPL) const { CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); if (auto *Specs = CommonBasePtr->LazySpecializations) { unsigned Hash = TemplateArgumentList::ComputeODRHash(Args); for (uint32_t I = 0, N = Specs[0].DeclID; I != N; ++I) - if (Specs[I+1].ODRHash && Specs[I+1].ODRHash == Hash) -(void)loadLazySpecializationImpl(Specs[I+1]); + if (Specs[I + 1].ODRHash && Specs[I + 1].ODRHash == Hash) +(void)loadLazySpecializationImpl(Specs[I + 1]); } } @@ -546,7 +544,7 @@ ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, } void ClassTemplateDecl::LoadLazySpecializations( - bool OnlyPartial/*=false*/) const { +bool OnlyPartial /*=false*/) const { loadLazySpecializationsImpl(OnlyPartial); } @@ -1275,7 +1273,7 @@ VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, } void VarTemplateDecl::LoadLazySpecializations( - bool OnlyPartial/*=false*/) const { +bool OnlyPartial /*=false*/) const {
[clang] [Serialization] Load Specializations Lazily (PR #76774)
ChuanqiXu9 wrote: Oh, I didn't notice you've removed D153003 already. But the branch name looks not good. So I've created a pr in https://github.com/llvm/llvm-project/pull/83108 https://github.com/llvm/llvm-project/pull/76774 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
ChuanqiXu9 wrote: Personally I feel this patch is good and the testing result from our workload shows it is good too. But it looks like the performance testing results from google @zygoloid @ilya-biryukov is not good. So maybe we need to wait for landing this. (It will be great if @ilya-biryukov would like to test again) https://github.com/llvm/llvm-project/pull/83108 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Chuanqi Xu (ChuanqiXu9) Changes This from https://reviews.llvm.org/D41416. And we plan to introduce on disk hash table based on this. See https://github.com/llvm/llvm-project/pull/76774. Following off are cited from https://reviews.llvm.org/D41416: Currently, we load all lazy template specializations when we search whether there is a suitable template specialization for a template. This is especially suboptimal with modules. If module B specializes a template from module A the ASTReader would only read the specialization DeclID. This is observed to be especially pathological when module B is stl. However, the template instantiator (almost immediately after) will call findSpecialization. In turn, findSpecialization will load all lazy specializations to give an answer. This patch teaches findSpecialization to work with lazy specializations without having to deserialize their full content. It provides along with the DeclID an cross-TU stable ODRHash of the template arguments which is enough to decide if we have already specialization and which are the exact ones (we load all decls with the same hash to avoid potential collisions) to deserialize. While we make finding a template specialization more memory-efficient we are far from being done. There are still a few places which trigger eager deserialization of template specializations: the places where we require completion of the redeclaration chain. --- Patch is 26.57 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/83108.diff 7 Files Affected: - (modified) clang/include/clang/AST/DeclTemplate.h (+32-4) - (modified) clang/lib/AST/DeclTemplate.cpp (+74-22) - (modified) clang/lib/AST/ODRHash.cpp (+15) - (modified) clang/lib/Serialization/ASTReader.cpp (+17-8) - (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+23-13) - (modified) clang/lib/Serialization/ASTWriter.cpp (+19-2) - (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+62-12) ``diff diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index e3b6a7efb1127a..4ed9b58d4ff609 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -256,6 +256,9 @@ class TemplateArgumentList final TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// Create hash for the given arguments. + static unsigned ComputeODRHash(ArrayRef Args); + /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, @@ -730,6 +733,26 @@ class RedeclarableTemplateDecl : public TemplateDecl, } void anchor() override; + struct LazySpecializationInfo { +uint32_t DeclID = ~0U; +unsigned ODRHash = ~0U; +bool IsPartial = false; +LazySpecializationInfo(uint32_t ID, unsigned Hash = ~0U, + bool Partial = false) + : DeclID(ID), ODRHash(Hash), IsPartial(Partial) { } +LazySpecializationInfo() { } +bool operator<(const LazySpecializationInfo &Other) const { + return DeclID < Other.DeclID; +} +bool operator==(const LazySpecializationInfo &Other) const { + assert((DeclID != Other.DeclID || ODRHash == Other.ODRHash) && + "Hashes differ!"); + assert((DeclID != Other.DeclID || IsPartial == Other.IsPartial) && + "Both must be the same kinds!"); + return DeclID == Other.DeclID; +} + }; + protected: template struct SpecEntryTraits { using DeclType = EntryType; @@ -770,7 +793,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + void loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; + + Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const; template typename SpecEntryTraits::DeclType* @@ -797,7 +825,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// /// The first value in the array is the number of specializations/partial /// specializations that follow. -uint32_t *LazySpecializations = nullptr; +LazySpecializationInfo *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -2268,7 +2296,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying class declara
[clang] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. (PR #83108)
https://github.com/ChuanqiXu9 created https://github.com/llvm/llvm-project/pull/83108 This from https://reviews.llvm.org/D41416. And we plan to introduce on disk hash table based on this. See https://github.com/llvm/llvm-project/pull/76774. Following off are cited from https://reviews.llvm.org/D41416: Currently, we load all lazy template specializations when we search whether there is a suitable template specialization for a template. This is especially suboptimal with modules. If module B specializes a template from module A the ASTReader would only read the specialization DeclID. This is observed to be especially pathological when module B is stl. However, the template instantiator (almost immediately after) will call findSpecialization. In turn, findSpecialization will load all lazy specializations to give an answer. This patch teaches findSpecialization to work with lazy specializations without having to deserialize their full content. It provides along with the DeclID an cross-TU stable ODRHash of the template arguments which is enough to decide if we have already specialization and which are the exact ones (we load all decls with the same hash to avoid potential collisions) to deserialize. While we make finding a template specialization more memory-efficient we are far from being done. There are still a few places which trigger eager deserialization of template specializations: the places where we require completion of the redeclaration chain. >From 59e1880df74434e3c446705788d92b5949d99536 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Sun, 7 Jan 2018 15:16:11 +0200 Subject: [PATCH] D41416: [modules] [pch] Do not deserialize all lazy template specializations when looking for one. --- clang/include/clang/AST/DeclTemplate.h| 36 - clang/lib/AST/DeclTemplate.cpp| 96 +-- clang/lib/AST/ODRHash.cpp | 15 clang/lib/Serialization/ASTReader.cpp | 25 -- clang/lib/Serialization/ASTReaderDecl.cpp | 36 ++--- clang/lib/Serialization/ASTWriter.cpp | 21 - clang/lib/Serialization/ASTWriterDecl.cpp | 74 ++--- 7 files changed, 242 insertions(+), 61 deletions(-) diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index e3b6a7efb1127a..4ed9b58d4ff609 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -256,6 +256,9 @@ class TemplateArgumentList final TemplateArgumentList(const TemplateArgumentList &) = delete; TemplateArgumentList &operator=(const TemplateArgumentList &) = delete; + /// Create hash for the given arguments. + static unsigned ComputeODRHash(ArrayRef Args); + /// Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, @@ -730,6 +733,26 @@ class RedeclarableTemplateDecl : public TemplateDecl, } void anchor() override; + struct LazySpecializationInfo { +uint32_t DeclID = ~0U; +unsigned ODRHash = ~0U; +bool IsPartial = false; +LazySpecializationInfo(uint32_t ID, unsigned Hash = ~0U, + bool Partial = false) + : DeclID(ID), ODRHash(Hash), IsPartial(Partial) { } +LazySpecializationInfo() { } +bool operator<(const LazySpecializationInfo &Other) const { + return DeclID < Other.DeclID; +} +bool operator==(const LazySpecializationInfo &Other) const { + assert((DeclID != Other.DeclID || ODRHash == Other.ODRHash) && + "Hashes differ!"); + assert((DeclID != Other.DeclID || IsPartial == Other.IsPartial) && + "Both must be the same kinds!"); + return DeclID == Other.DeclID; +} + }; + protected: template struct SpecEntryTraits { using DeclType = EntryType; @@ -770,7 +793,12 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + void loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; + + Decl *loadLazySpecializationImpl(LazySpecializationInfo &LazySpecInfo) const; template typename SpecEntryTraits::DeclType* @@ -797,7 +825,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// /// The first value in the array is the number of specializations/partial /// specializations that follow. -uint32_t *LazySpecializations = nullptr; +LazySpecializationInfo *LazySpecializations = nullptr; /// The set of "injected" template arguments used within this /// template. @@ -2268,7 +2296,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external sourc
[clang] [Clang] [Sema] Handle placeholders in '.*' expressions (PR #83103)
Sirraide wrote: In my opinion, we ought to get `.*` ought of the way early—as I’m currently doing in this pr—as it makes little sense to do overloading-specific placeholder handling on an operator that isn’t even overloadable—we should instead just handle all placeholders immediately. https://github.com/llvm/llvm-project/pull/83103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Handle placeholders in '.*' expressions (PR #83103)
Sirraide wrote: Yeah, it seems the change that ultimately caused this to break was made in 2011, which moved the handling of placeholders for this code path up into `SemaOverload.cpp`, and from what I can tell, the case of either operand of `.*` potentially being an overload set when `.*` is not overloadable was simply overlooked (i.e. the `assert()` is there because this case *was* being handled before, but this commit removed that): https://github.com/llvm/llvm-project/commit/526ab47a5573422765ac6c55147dfad00f1d703d#diff-3c28567b5e0c77d68f174541a0b77f5a85d093f58b89cd3675ee04a550a44880L7784-L7800 https://github.com/llvm/llvm-project/pull/83103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [OpenMP][Clang] Enable inscan modifier for generic datatypes (PR #82220)
https://github.com/animeshk-amd updated https://github.com/llvm/llvm-project/pull/82220 >From b891329e49972c15941f2d15408ff32cfe3995f3 Mon Sep 17 00:00:00 2001 From: Animesh Kumar Date: Mon, 19 Feb 2024 00:28:39 -0600 Subject: [PATCH] [OpenMP][Clang] Enable inscan modifier for generic datatypes This patch fixes the #67002 ([OpenMP][Clang] Scan Directive not supported for Generic types). It disables the Sema checks/analysis that are run on the helper arrays which go into the implementation of the `omp scan` directive until the template instantiation happens. --- clang/lib/Sema/SemaOpenMP.cpp| 3 ++- clang/test/OpenMP/scan_ast_print.cpp | 18 ++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index 7f75cfc5b54f35..f4364a259ad57f 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -4962,7 +4962,8 @@ StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, if (RC->getModifier() != OMPC_REDUCTION_inscan) continue; for (Expr *E : RC->copy_array_temps()) -MarkDeclarationsReferencedInExpr(E); +if (E) + MarkDeclarationsReferencedInExpr(E); } if (auto *AC = dyn_cast(C)) { for (Expr *E : AC->varlists()) diff --git a/clang/test/OpenMP/scan_ast_print.cpp b/clang/test/OpenMP/scan_ast_print.cpp index 3bbd3b60c3e8c4..82cb13eb6e70f7 100644 --- a/clang/test/OpenMP/scan_ast_print.cpp +++ b/clang/test/OpenMP/scan_ast_print.cpp @@ -17,6 +17,10 @@ T tmain(T argc) { static T a; #pragma omp for reduction(inscan, +: a) for (int i = 0; i < 10; ++i) { +#pragma omp scan inclusive(a) + } +#pragma omp parallel for reduction(inscan, +:a) + for (int i = 0; i < 10; ++i) { #pragma omp scan inclusive(a) } return a + argc; @@ -25,15 +29,29 @@ T tmain(T argc) { // CHECK-NEXT: #pragma omp for reduction(inscan, +: a) // CHECK-NEXT: for (int i = 0; i < 10; ++i) { // CHECK-NEXT: #pragma omp scan inclusive(a){{$}} + +// CHECK: #pragma omp parallel for reduction(inscan, +: a) +// CHECK-NEXT: for (int i = 0; i < 10; ++i) { +// CHECK-NEXT: #pragma omp scan inclusive(a){{$}} + // CHECK: static int a; // CHECK-NEXT: #pragma omp for reduction(inscan, +: a) // CHECK-NEXT: for (int i = 0; i < 10; ++i) { // CHECK-NEXT: #pragma omp scan inclusive(a) + +// CHECK: #pragma omp parallel for reduction(inscan, +: a) +// CHECK-NEXT: for (int i = 0; i < 10; ++i) { +// CHECK-NEXT: #pragma omp scan inclusive(a) + // CHECK: static char a; // CHECK-NEXT: #pragma omp for reduction(inscan, +: a) // CHECK-NEXT: for (int i = 0; i < 10; ++i) { // CHECK-NEXT: #pragma omp scan inclusive(a) +// CHECK: #pragma omp parallel for reduction(inscan, +: a) +// CHECK-NEXT: for (int i = 0; i < 10; ++i) { +// CHECK-NEXT: #pragma omp scan inclusive(a) + int main(int argc, char **argv) { static int a; // CHECK: static int a; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Handle placeholders in '.*' expressions (PR #83103)
Sirraide wrote: It seems like the assertion has been in Clang since 2011, and back then, we *were* checking for placeholders in `CreateBuiltinBinOp()`, so at that point it made sense, but this check seems to have been removed since then. https://github.com/llvm/llvm-project/pull/83103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm (PR #82968)
https://github.com/ecnelises updated https://github.com/llvm/llvm-project/pull/82968 >From a06fa5e18313ad50019d50006e34a6b8249d95cd Mon Sep 17 00:00:00 2001 From: Qiu Chaofan Date: Mon, 26 Feb 2024 16:32:28 +0800 Subject: [PATCH 1/3] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm These builtins are already there in Clang, however current codegen may produce suboptimal results due to their complex behavior. Implement them as intrinsics to ensure expected instructions are emitted. --- clang/lib/CodeGen/CGBuiltin.cpp | 29 ++--- .../PowerPC/builtins-ppc-xlcompat-rotate.c| 24 ++-- llvm/include/llvm/IR/IntrinsicsPowerPC.td | 12 ++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 52 llvm/test/CodeGen/PowerPC/rldimi.ll | 15 +++ llvm/test/CodeGen/PowerPC/rlwimi.ll | 123 -- llvm/test/CodeGen/PowerPC/rlwinm.ll | 108 ++- 7 files changed, 259 insertions(+), 104 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..5d55be6e9e99df 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -17080,37 +17080,24 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, } return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, ""); } - // Rotate and insert under mask operation. - // __rldimi(rs, is, shift, mask) - // (rotl64(rs, shift) & mask) | (is & ~mask) - // __rlwimi(rs, is, shift, mask) - // (rotl(rs, shift) & mask) | (is & ~mask) case PPC::BI__builtin_ppc_rldimi: case PPC::BI__builtin_ppc_rlwimi: { Value *Op0 = EmitScalarExpr(E->getArg(0)); Value *Op1 = EmitScalarExpr(E->getArg(1)); Value *Op2 = EmitScalarExpr(E->getArg(2)); Value *Op3 = EmitScalarExpr(E->getArg(3)); -llvm::Type *Ty = Op0->getType(); -Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty); -if (BuiltinID == PPC::BI__builtin_ppc_rldimi) - Op2 = Builder.CreateZExt(Op2, Int64Ty); -Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op2}); -Value *X = Builder.CreateAnd(Shift, Op3); -Value *Y = Builder.CreateAnd(Op1, Builder.CreateNot(Op3)); -return Builder.CreateOr(X, Y); - } - // Rotate and insert under mask operation. - // __rlwnm(rs, shift, mask) - // rotl(rs, shift) & mask +return Builder.CreateCall( +CGM.getIntrinsic(BuiltinID == PPC::BI__builtin_ppc_rldimi + ? Intrinsic::ppc_rldimi + : Intrinsic::ppc_rlwimi), +{Op0, Op1, Op2, Op3}); + } case PPC::BI__builtin_ppc_rlwnm: { Value *Op0 = EmitScalarExpr(E->getArg(0)); Value *Op1 = EmitScalarExpr(E->getArg(1)); Value *Op2 = EmitScalarExpr(E->getArg(2)); -llvm::Type *Ty = Op0->getType(); -Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty); -Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op1}); -return Builder.CreateAnd(Shift, Op2); +return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_rlwnm), + {Op0, Op1, Op2}); } case PPC::BI__builtin_ppc_poppar4: case PPC::BI__builtin_ppc_poppar8: { diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c index d96bfb4621421e..b218547c00d931 100644 --- a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c +++ b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c @@ -16,11 +16,8 @@ void test_builtin_ppc_rldimi() { // CHECK: %res = alloca i64, align 8 // CHECK-NEXT: [[RA:%[0-9]+]] = load i64, ptr @ull, align 8 // CHECK-NEXT: [[RB:%[0-9]+]] = load i64, ptr @ull, align 8 - // CHECK-NEXT: [[RC:%[0-9]+]] = call i64 @llvm.fshl.i64(i64 [[RA]], i64 [[RA]], i64 63) - // CHECK-NEXT: [[RD:%[0-9]+]] = and i64 [[RC]], 72057593769492480 - // CHECK-NEXT: [[RE:%[0-9]+]] = and i64 [[RB]], -72057593769492481 - // CHECK-NEXT: [[RF:%[0-9]+]] = or i64 [[RD]], [[RE]] - // CHECK-NEXT: store i64 [[RF]], ptr %res, align 8 + // CHECK-NEXT: [[RC:%[0-9]+]] = call i64 @llvm.ppc.rldimi(i64 [[RA]], i64 [[RB]], i32 63, i64 72057593769492480) + // CHECK-NEXT: store i64 [[RC]], ptr %res, align 8 // CHECK-NEXT: ret void /*shift = 63, mask = 0x00FFF000 = 72057593769492480, ~mask = 0xFF000FFF = -72057593769492481*/ @@ -32,11 +29,8 @@ void test_builtin_ppc_rlwimi() { // CHECK: %res = alloca i32, align 4 // CHECK-NEXT: [[RA:%[0-9]+]] = load i32, ptr @ui, align 4 // CHECK-NEXT: [[RB:%[0-9]+]] = load i32, ptr @ui, align 4 - // CHECK-NEXT: [[RC:%[0-9]+]] = call i32 @llvm.fshl.i32(i32 [[RA]], i32 [[RA]], i32 31) - // CHECK-NEXT: [[RD:%[0-9]+]] = and i32 [[RC]], 16776960 - // CHECK-NEXT: [[RE:%[0-9]+]] = and i32 [[RB]], -16776961 - // CHECK-NEXT: [[RF:%[0-9]+]] = or i32 [[RD]], [[RE]] - // CHECK-NEXT: store i32 [[RF]], ptr %res, align 4 + // CHECK-NEXT: [[RC:%[0-9]+]] = call i32 @llvm.ppc.rlwimi(i32 [[RA]], i32 [[R
[clang] [llvm] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm (PR #82968)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff c67a4ae47c86f1f390db7ba0ea9c021abff130f8 d9c9b4eb91ca3cec0bc469364914706b89ab1eeb -- clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c llvm/lib/Target/PowerPC/PPCISelLowering.cpp `` View the diff from clang-format here. ``diff diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 178904d1e3..7a9b1520ec 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -10741,8 +10741,7 @@ SDValue PPCTargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, case Intrinsic::ppc_rldimi: { uint64_t SH = Op.getConstantOperandVal(3); unsigned MB = 0, ME = 0; -if (!isRunOfOnes64(Op.getConstantOperandVal(4), MB, ME) || -ME != 63 - SH) +if (!isRunOfOnes64(Op.getConstantOperandVal(4), MB, ME) || ME != 63 - SH) report_fatal_error("invalid rldimi mask!"); return SDValue(DAG.getMachineNode( PPC::RLDIMI, dl, MVT::i64, `` https://github.com/llvm/llvm-project/pull/82968 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm (PR #82968)
https://github.com/ecnelises updated https://github.com/llvm/llvm-project/pull/82968 >From a06fa5e18313ad50019d50006e34a6b8249d95cd Mon Sep 17 00:00:00 2001 From: Qiu Chaofan Date: Mon, 26 Feb 2024 16:32:28 +0800 Subject: [PATCH 1/2] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm These builtins are already there in Clang, however current codegen may produce suboptimal results due to their complex behavior. Implement them as intrinsics to ensure expected instructions are emitted. --- clang/lib/CodeGen/CGBuiltin.cpp | 29 ++--- .../PowerPC/builtins-ppc-xlcompat-rotate.c| 24 ++-- llvm/include/llvm/IR/IntrinsicsPowerPC.td | 12 ++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 52 llvm/test/CodeGen/PowerPC/rldimi.ll | 15 +++ llvm/test/CodeGen/PowerPC/rlwimi.ll | 123 -- llvm/test/CodeGen/PowerPC/rlwinm.ll | 108 ++- 7 files changed, 259 insertions(+), 104 deletions(-) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..5d55be6e9e99df 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -17080,37 +17080,24 @@ Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID, } return Builder.CreateCall(CGM.getIntrinsic(ID), Ops, ""); } - // Rotate and insert under mask operation. - // __rldimi(rs, is, shift, mask) - // (rotl64(rs, shift) & mask) | (is & ~mask) - // __rlwimi(rs, is, shift, mask) - // (rotl(rs, shift) & mask) | (is & ~mask) case PPC::BI__builtin_ppc_rldimi: case PPC::BI__builtin_ppc_rlwimi: { Value *Op0 = EmitScalarExpr(E->getArg(0)); Value *Op1 = EmitScalarExpr(E->getArg(1)); Value *Op2 = EmitScalarExpr(E->getArg(2)); Value *Op3 = EmitScalarExpr(E->getArg(3)); -llvm::Type *Ty = Op0->getType(); -Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty); -if (BuiltinID == PPC::BI__builtin_ppc_rldimi) - Op2 = Builder.CreateZExt(Op2, Int64Ty); -Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op2}); -Value *X = Builder.CreateAnd(Shift, Op3); -Value *Y = Builder.CreateAnd(Op1, Builder.CreateNot(Op3)); -return Builder.CreateOr(X, Y); - } - // Rotate and insert under mask operation. - // __rlwnm(rs, shift, mask) - // rotl(rs, shift) & mask +return Builder.CreateCall( +CGM.getIntrinsic(BuiltinID == PPC::BI__builtin_ppc_rldimi + ? Intrinsic::ppc_rldimi + : Intrinsic::ppc_rlwimi), +{Op0, Op1, Op2, Op3}); + } case PPC::BI__builtin_ppc_rlwnm: { Value *Op0 = EmitScalarExpr(E->getArg(0)); Value *Op1 = EmitScalarExpr(E->getArg(1)); Value *Op2 = EmitScalarExpr(E->getArg(2)); -llvm::Type *Ty = Op0->getType(); -Function *F = CGM.getIntrinsic(Intrinsic::fshl, Ty); -Value *Shift = Builder.CreateCall(F, {Op0, Op0, Op1}); -return Builder.CreateAnd(Shift, Op2); +return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::ppc_rlwnm), + {Op0, Op1, Op2}); } case PPC::BI__builtin_ppc_poppar4: case PPC::BI__builtin_ppc_poppar8: { diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c index d96bfb4621421e..b218547c00d931 100644 --- a/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c +++ b/clang/test/CodeGen/PowerPC/builtins-ppc-xlcompat-rotate.c @@ -16,11 +16,8 @@ void test_builtin_ppc_rldimi() { // CHECK: %res = alloca i64, align 8 // CHECK-NEXT: [[RA:%[0-9]+]] = load i64, ptr @ull, align 8 // CHECK-NEXT: [[RB:%[0-9]+]] = load i64, ptr @ull, align 8 - // CHECK-NEXT: [[RC:%[0-9]+]] = call i64 @llvm.fshl.i64(i64 [[RA]], i64 [[RA]], i64 63) - // CHECK-NEXT: [[RD:%[0-9]+]] = and i64 [[RC]], 72057593769492480 - // CHECK-NEXT: [[RE:%[0-9]+]] = and i64 [[RB]], -72057593769492481 - // CHECK-NEXT: [[RF:%[0-9]+]] = or i64 [[RD]], [[RE]] - // CHECK-NEXT: store i64 [[RF]], ptr %res, align 8 + // CHECK-NEXT: [[RC:%[0-9]+]] = call i64 @llvm.ppc.rldimi(i64 [[RA]], i64 [[RB]], i32 63, i64 72057593769492480) + // CHECK-NEXT: store i64 [[RC]], ptr %res, align 8 // CHECK-NEXT: ret void /*shift = 63, mask = 0x00FFF000 = 72057593769492480, ~mask = 0xFF000FFF = -72057593769492481*/ @@ -32,11 +29,8 @@ void test_builtin_ppc_rlwimi() { // CHECK: %res = alloca i32, align 4 // CHECK-NEXT: [[RA:%[0-9]+]] = load i32, ptr @ui, align 4 // CHECK-NEXT: [[RB:%[0-9]+]] = load i32, ptr @ui, align 4 - // CHECK-NEXT: [[RC:%[0-9]+]] = call i32 @llvm.fshl.i32(i32 [[RA]], i32 [[RA]], i32 31) - // CHECK-NEXT: [[RD:%[0-9]+]] = and i32 [[RC]], 16776960 - // CHECK-NEXT: [[RE:%[0-9]+]] = and i32 [[RB]], -16776961 - // CHECK-NEXT: [[RF:%[0-9]+]] = or i32 [[RD]], [[RE]] - // CHECK-NEXT: store i32 [[RF]], ptr %res, align 4 + // CHECK-NEXT: [[RC:%[0-9]+]] = call i32 @llvm.ppc.rlwimi(i32 [[RA]], i32 [[R
[clang] [llvm] MIPS: Fix asm constraints "f" and "r" for softfloat (PR #79116)
https://github.com/MaskRay closed https://github.com/llvm/llvm-project/pull/79116 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] c88beb4 - MIPS: Fix asm constraints "f" and "r" for softfloat (#79116)
Author: YunQiang Su Date: 2024-02-26T22:08:36-08:00 New Revision: c88beb4112d5bbf07d76a615ab7f13ba2ba023e6 URL: https://github.com/llvm/llvm-project/commit/c88beb4112d5bbf07d76a615ab7f13ba2ba023e6 DIFF: https://github.com/llvm/llvm-project/commit/c88beb4112d5bbf07d76a615ab7f13ba2ba023e6.diff LOG: MIPS: Fix asm constraints "f" and "r" for softfloat (#79116) This include 2 fixes: 1. Disallow 'f' for softfloat. 2. Allow 'r' for softfloat. Currently, 'f' is accpeted by clang, then LLVM meets an internal error. 'r' is rejected by LLVM by: couldn't allocate input reg for constraint 'r'. Fixes: #64241, #63632 - Co-authored-by: Fangrui Song Added: clang/test/CodeGen/Mips/inline-asm-constraints.c clang/test/Sema/inline-asm-validate-mips.c llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll Modified: clang/lib/Basic/Targets/Mips.h llvm/lib/Target/Mips/MipsISelLowering.cpp Removed: diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index f46b95abfd75c7..23d4e1b598fa1e 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -237,12 +237,14 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { case 'r': // CPU registers. case 'd': // Equivalent to "r" unless generating MIPS16 code. case 'y': // Equivalent to "r", backward compatibility only. -case 'f': // floating-point registers. case 'c': // $25 for indirect jumps case 'l': // lo register case 'x': // hilo register pair Info.setAllowsRegister(); return true; +case 'f': // floating-point registers. + Info.setAllowsRegister(); + return FloatABI != SoftFloat; case 'I': // Signed 16-bit constant case 'J': // Integer 0 case 'K': // Unsigned 16-bit constant diff --git a/clang/test/CodeGen/Mips/inline-asm-constraints.c b/clang/test/CodeGen/Mips/inline-asm-constraints.c new file mode 100644 index 00..88afe8735083b4 --- /dev/null +++ b/clang/test/CodeGen/Mips/inline-asm-constraints.c @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -emit-llvm -triple mips -target-feature +soft-float %s -o - | FileCheck %s --check-prefix=SOFT_FLOAT + +// SOFT_FLOAT: call void asm sideeffect "", "r,~{$1}"(float %1) +void read_float(float *p) { + __asm__("" ::"r"(*p)); +} + +// SOFT_FLOAT: call void asm sideeffect "", "r,~{$1}"(double %1) +void read_double(double *p) { + __asm__("" :: "r"(*p)); +} diff --git a/clang/test/Sema/inline-asm-validate-mips.c b/clang/test/Sema/inline-asm-validate-mips.c new file mode 100644 index 00..7da248fe417b5c --- /dev/null +++ b/clang/test/Sema/inline-asm-validate-mips.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple mips64 -fsyntax-only -verify %s +// RUN: %clang_cc1 -triple mips64 -target-feature +soft-float -fsyntax-only -verify=softfloat %s + +// expected-no-diagnostics + +void test_f(float p) { + float result = p; + __asm__("" :: "f"(result)); // softfloat-error{{invalid input constraint 'f' in asm}} +} diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index b2812f87914df7..97e830cec27cad 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -4128,14 +4128,18 @@ MipsTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, case 'd': // Address register. Same as 'r' unless generating MIPS16 code. case 'y': // Same as 'r'. Exists for compatibility. case 'r': - if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 || VT == MVT::i1) { + if ((VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 || + VT == MVT::i1) || + (VT == MVT::f32 && Subtarget.useSoftFloat())) { if (Subtarget.inMips16Mode()) return std::make_pair(0U, &Mips::CPU16RegsRegClass); return std::make_pair(0U, &Mips::GPR32RegClass); } - if (VT == MVT::i64 && !Subtarget.isGP64bit()) + if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat())) && + !Subtarget.isGP64bit()) return std::make_pair(0U, &Mips::GPR32RegClass); - if (VT == MVT::i64 && Subtarget.isGP64bit()) + if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat())) && + Subtarget.isGP64bit()) return std::make_pair(0U, &Mips::GPR64RegClass); // This will generate an error message return std::make_pair(0U, nullptr); diff --git a/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll b/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll new file mode 100644 index 00..705570f808ce00 --- /dev/null +++ b/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll @@ -0,0 +1,48 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 +; RUN: llc -march=mips < %s | FileCheck
[clang] [llvm] MIPS: Fix asm constraints "f" and "r" for softfloat (PR #79116)
https://github.com/MaskRay edited https://github.com/llvm/llvm-project/pull/79116 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] MIPS/clang: Fix asm constraint for softfloat (PR #79116)
https://github.com/MaskRay edited https://github.com/llvm/llvm-project/pull/79116 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] MIPS/clang: Fix asm constraint for softfloat (PR #79116)
https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/79116 >From 14ea44a352d547f3c2736f16a47f3dad449446f5 Mon Sep 17 00:00:00 2001 From: YunQiang Su Date: Tue, 23 Jan 2024 18:14:48 +0800 Subject: [PATCH 1/2] MIPS/clang: Fix asm constraint for softfloat This include 2 fixes: 1. Disallow 'f' for softfloat. 2. Allow 'r' for softfloat. Currently, 'f' is accpeted by clang, then LLVM meet an internal error. 'r' is rejected by LLVM by: couldn't allocate input reg for constraint 'r' Fixes: #64241 --- clang/lib/Basic/Targets/Mips.h| 3 +++ .../CodeGen/Mips/inline-asm-constraints.c | 18 + clang/test/Sema/inline-asm-validate-mips.c| 8 ++ llvm/lib/Target/Mips/MipsISelLowering.cpp | 10 +--- .../Mips/inlineasm-constraints-softfloat.ll | 25 +++ 5 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 clang/test/CodeGen/Mips/inline-asm-constraints.c create mode 100644 clang/test/Sema/inline-asm-validate-mips.c create mode 100644 llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll diff --git a/clang/lib/Basic/Targets/Mips.h b/clang/lib/Basic/Targets/Mips.h index f46b95abfd75c7..2b8ad6645e605f 100644 --- a/clang/lib/Basic/Targets/Mips.h +++ b/clang/lib/Basic/Targets/Mips.h @@ -238,6 +238,9 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { case 'd': // Equivalent to "r" unless generating MIPS16 code. case 'y': // Equivalent to "r", backward compatibility only. case 'f': // floating-point registers. + if (*Name == 'f' && FloatABI == SoftFloat) +return false; + LLVM_FALLTHROUGH; case 'c': // $25 for indirect jumps case 'l': // lo register case 'x': // hilo register pair diff --git a/clang/test/CodeGen/Mips/inline-asm-constraints.c b/clang/test/CodeGen/Mips/inline-asm-constraints.c new file mode 100644 index 00..0a4cb0b34570e6 --- /dev/null +++ b/clang/test/CodeGen/Mips/inline-asm-constraints.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -triple mips -target-feature +soft-float \ +// RUN:-DSOFT_FLOAT_CONSTRAINT_R \ +// RUN:-DFLOAT=float -emit-llvm -o - \ +// RUN: | FileCheck %s --check-prefix SOFT_FLOAT_CONSTRAINT_R_SINGLE + +// RUN: %clang_cc1 %s -triple mips -target-feature +soft-float \ +// RUN:-DSOFT_FLOAT_CONSTRAINT_R \ +// RUN:-DFLOAT=double -emit-llvm -o - \ +// RUN: | FileCheck %s --check-prefix SOFT_FLOAT_CONSTRAINT_R_DOUBLE + +#ifdef SOFT_FLOAT_CONSTRAINT_R +// SOFT_FLOAT_CONSTRAINT_R_SINGLE: call void asm sideeffect "", "r,~{$1}"(float %2) #1, !srcloc !2 +// SOFT_FLOAT_CONSTRAINT_R_DOUBLE: call void asm sideeffect "", "r,~{$1}"(double %2) #1, !srcloc !2 +void read_float(FLOAT* p) { +FLOAT result = *p; +__asm__("" ::"r"(result)); +} +#endif // SOFT_FLOAT_CONSTRAINT_R diff --git a/clang/test/Sema/inline-asm-validate-mips.c b/clang/test/Sema/inline-asm-validate-mips.c new file mode 100644 index 00..5a123cc5fa79c3 --- /dev/null +++ b/clang/test/Sema/inline-asm-validate-mips.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -triple mips -target-feature +soft-float -DSOFT_FLOAT_NO_CONSTRAINT_F -fsyntax-only -verify %s + +#ifdef SOFT_FLOAT_NO_CONSTRAINT_F +void read_float(float p) { +float result = p; +__asm__("" ::"f"(result)); // expected-error{{invalid input constraint 'f' in asm}} +} +#endif // SOFT_FLOAT_NO_CONSTRAINT_F diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index b2812f87914df7..97e830cec27cad 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -4128,14 +4128,18 @@ MipsTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, case 'd': // Address register. Same as 'r' unless generating MIPS16 code. case 'y': // Same as 'r'. Exists for compatibility. case 'r': - if (VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 || VT == MVT::i1) { + if ((VT == MVT::i32 || VT == MVT::i16 || VT == MVT::i8 || + VT == MVT::i1) || + (VT == MVT::f32 && Subtarget.useSoftFloat())) { if (Subtarget.inMips16Mode()) return std::make_pair(0U, &Mips::CPU16RegsRegClass); return std::make_pair(0U, &Mips::GPR32RegClass); } - if (VT == MVT::i64 && !Subtarget.isGP64bit()) + if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat())) && + !Subtarget.isGP64bit()) return std::make_pair(0U, &Mips::GPR32RegClass); - if (VT == MVT::i64 && Subtarget.isGP64bit()) + if ((VT == MVT::i64 || (VT == MVT::f64 && Subtarget.useSoftFloat())) && + Subtarget.isGP64bit()) return std::make_pair(0U, &Mips::GPR64RegClass); // This will generate an error message return std::make_pair(0U, nullptr); diff --git a/llvm/test/CodeGen/Mips/inlineasm-constraints-softfloat.ll b/llvm/test/CodeGen/Mi
[clang] [Clang] [Sema] Handle placeholders in '.*' expressions (PR #83103)
Sirraide wrote: One more thing: this code seems to not crash and issue a diagnostic just fine if we simply remove the assertion, so that would also be an option, but I didn’t simply want to remove an assertion without fully knowing why it’s there, so I’ve gone with this as an alternative for now (it should be noted that the code path here is shared with `->*`, which of course is overloadable). Alternatively, we could also handle placeholders then and there instead of asserting on them. Thinking about this now, I’m not entirely sure what the best solution would be. https://github.com/llvm/llvm-project/pull/83103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] MIPS/clang: Fix asm constraint for softfloat (PR #79116)
https://github.com/MaskRay approved this pull request. https://github.com/llvm/llvm-project/pull/79116 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] MIPS/clang: Fix asm constraint for softfloat (PR #79116)
@@ -238,6 +238,9 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { case 'd': // Equivalent to "r" unless generating MIPS16 code. case 'y': // Equivalent to "r", backward compatibility only. case 'f': // floating-point registers. + if (*Name == 'f' && FloatABI == SoftFloat) MaskRay wrote: It's better to move 'd' and 'y' below. I'll fix it. https://github.com/llvm/llvm-project/pull/79116 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] MIPS/clang: Fix asm constraint for softfloat (PR #79116)
@@ -0,0 +1,25 @@ +; RUN: llc -march=mips < %s | FileCheck %s --check-prefix=MIPS32 +; RUN: llc -march=mips64 < %s | FileCheck %s --check-prefix=MIPS64 + +define dso_local void @read_double(ptr nocapture noundef readonly %0) local_unnamed_addr #0 { + %2 = load double, ptr %0, align 8 +; MIPS32-LABEL: read_double: +; MIPS32: lw $2, 4($4) MaskRay wrote: Ensure that `lw` is indented by 2 compared with `read_double:` https://github.com/llvm/llvm-project/pull/79116 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Handle placeholders in '.*' expressions (PR #83103)
Sirraide wrote: CC @AaronBallman, @cor3ntin https://github.com/llvm/llvm-project/pull/83103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] MIPS/clang: Fix asm constraint for softfloat (PR #79116)
brad0 wrote: @MaskRay https://github.com/llvm/llvm-project/pull/79116 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Handle placeholders in '.*' expressions (PR #83103)
llvmbot wrote: @llvm/pr-subscribers-clang Author: None (Sirraide) Changes When analysing whether we should handle a binary expression as an overloaded operator call or a builtin operator, we were calling `checkPlaceholderForOverload()`, which takes care of any placeholders that are not overload sets—which would usually make sense since those need to be handled as part of overload resolution. Unfortunately, we were also doing that for `.*`, which is not overloadable, and then proceeding to create a builtin operator anyway, which would crash if the RHS happened to be an unresolved overload set (due hitting an assertion in `CreateBuiltinBinOp()`—specifically, in one of its callees—in the `.*` case that makes sure its arguments aren’t placeholders). This pr instead makes it so we check for *all* placeholders early if the operator is `.*`. It’s worth noting that, 1. In the `.*` case, we now additionally also check for *any* placeholders (not just non-overload-sets) in the LHS; this shouldn’t make a difference, however—at least I couldn’t think of a way to trigger the assertion with an overload set as the LHS of `.*`; it is worth noting that the assertion in question would also complain if the LHS happened to be of placeholder type, though. 2. There is another case in which we also don’t perform overload resolution—namely `=` if the LHS is not of class or enumeration type after handling non-overload-set placeholders—as in the `.*` case, but similarly to 1., I first couldn’t think of a way of getting this case to crash, and secondly, `CreateBuiltinBinOp()` doesn’t seem to care about placeholders in the LHS or RHS in the `=` case (from what I can tell, it, or rather one of its callees, only checks that the LHS is not a pseudo-object type, but those will have already been handled by the call to `checkPlaceholderForOverload()` by the time we get to this function), so I don’t think this case suffers from the same problem. This fixes #53815. --- Full diff: https://github.com/llvm/llvm-project/pull/83103.diff 2 Files Affected: - (modified) clang/lib/Sema/SemaOverload.cpp (+17-5) - (added) clang/test/SemaCXX/gh53815.cpp (+21) ``diff diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c46f6338a5a125..f4b67e7b469418 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -14474,6 +14474,23 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, CurFPFeatureOverrides()); } + // If this is the .* operator, which is not overloadable, just + // create a built-in binary operator. + if (Opc == BO_PtrMemD) { +auto CheckPlaceholder = [&](Expr *&Arg) { + ExprResult Res = CheckPlaceholderExpr(Arg); + if (!Res.isInvalid()) +Arg = Res.get(); + return Res.isInvalid(); +}; + +// CreateBuiltinBinOp() doesn't like it if we tell it to create a '.*' +// expression that contains placeholders (in either the LHS or RHS). +if (CheckPlaceholder(Args[0]) || CheckPlaceholder(Args[1])) + return ExprError(); +return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); + } + // Always do placeholder-like conversions on the RHS. if (checkPlaceholderForOverload(*this, Args[1])) return ExprError(); @@ -14493,11 +14510,6 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType()) return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); - // If this is the .* operator, which is not overloadable, just - // create a built-in binary operator. - if (Opc == BO_PtrMemD) -return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); - // Build the overload set. OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator, OverloadCandidateSet::OperatorRewriteInfo( diff --git a/clang/test/SemaCXX/gh53815.cpp b/clang/test/SemaCXX/gh53815.cpp new file mode 100644 index 00..326c911c7bfaf5 --- /dev/null +++ b/clang/test/SemaCXX/gh53815.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s +// expected-no-diagnostics + +// Check that we don't crash due to forgetting to check for placeholders +// in the RHS of '.*'. + +template +static bool has_explicitly_named_overload() { + return requires { Fn().*&Fn::operator(); }; +} + +int main() { + has_explicitly_named_overload(); +} + +template +constexpr bool has_explicitly_named_overload_2() { + return requires { Fn().*&Fn::operator(); }; +} + +static_assert(!has_explicitly_named_overload_2()); `` https://github.com/llvm/llvm-project/pull/83103 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [Sema] Handle placeholders in '.*' expressions (PR #83103)
https://github.com/Sirraide created https://github.com/llvm/llvm-project/pull/83103 When analysing whether we should handle a binary expression as an overloaded operator call or a builtin operator, we were calling `checkPlaceholderForOverload()`, which takes care of any placeholders that are not overload sets—which would usually make sense since those need to be handled as part of overload resolution. Unfortunately, we were also doing that for `.*`, which is not overloadable, and then proceeding to create a builtin operator anyway, which would crash if the RHS happened to be an unresolved overload set (due hitting an assertion in `CreateBuiltinBinOp()`—specifically, in one of its callees—in the `.*` case that makes sure its arguments aren’t placeholders). This pr instead makes it so we check for *all* placeholders early if the operator is `.*`. It’s worth noting that, 1. In the `.*` case, we now additionally also check for *any* placeholders (not just non-overload-sets) in the LHS; this shouldn’t make a difference, however—at least I couldn’t think of a way to trigger the assertion with an overload set as the LHS of `.*`; it is worth noting that the assertion in question would also complain if the LHS happened to be of placeholder type, though. 2. There is another case in which we also don’t perform overload resolution—namely `=` if the LHS is not of class or enumeration type after handling non-overload-set placeholders—as in the `.*` case, but similarly to 1., I first couldn’t think of a way of getting this case to crash, and secondly, `CreateBuiltinBinOp()` doesn’t seem to care about placeholders in the LHS or RHS in the `=` case (from what I can tell, it, or rather one of its callees, only checks that the LHS is not a pseudo-object type, but those will have already been handled by the call to `checkPlaceholderForOverload()` by the time we get to this function), so I don’t think this case suffers from the same problem. This fixes #53815. >From 071b6287e89e4601d9e441978f0b4bd53e757c26 Mon Sep 17 00:00:00 2001 From: Sirraide Date: Tue, 27 Feb 2024 06:19:05 +0100 Subject: [PATCH] [Clang] [Sema] Handle placeholders in '.*' expressions --- clang/lib/Sema/SemaOverload.cpp | 22 +- clang/test/SemaCXX/gh53815.cpp | 21 + 2 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 clang/test/SemaCXX/gh53815.cpp diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c46f6338a5a125..f4b67e7b469418 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -14474,6 +14474,23 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, CurFPFeatureOverrides()); } + // If this is the .* operator, which is not overloadable, just + // create a built-in binary operator. + if (Opc == BO_PtrMemD) { +auto CheckPlaceholder = [&](Expr *&Arg) { + ExprResult Res = CheckPlaceholderExpr(Arg); + if (!Res.isInvalid()) +Arg = Res.get(); + return Res.isInvalid(); +}; + +// CreateBuiltinBinOp() doesn't like it if we tell it to create a '.*' +// expression that contains placeholders (in either the LHS or RHS). +if (CheckPlaceholder(Args[0]) || CheckPlaceholder(Args[1])) + return ExprError(); +return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); + } + // Always do placeholder-like conversions on the RHS. if (checkPlaceholderForOverload(*this, Args[1])) return ExprError(); @@ -14493,11 +14510,6 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, if (Opc == BO_Assign && !Args[0]->getType()->isOverloadableType()) return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); - // If this is the .* operator, which is not overloadable, just - // create a built-in binary operator. - if (Opc == BO_PtrMemD) -return CreateBuiltinBinOp(OpLoc, Opc, Args[0], Args[1]); - // Build the overload set. OverloadCandidateSet CandidateSet(OpLoc, OverloadCandidateSet::CSK_Operator, OverloadCandidateSet::OperatorRewriteInfo( diff --git a/clang/test/SemaCXX/gh53815.cpp b/clang/test/SemaCXX/gh53815.cpp new file mode 100644 index 00..326c911c7bfaf5 --- /dev/null +++ b/clang/test/SemaCXX/gh53815.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s +// expected-no-diagnostics + +// Check that we don't crash due to forgetting to check for placeholders +// in the RHS of '.*'. + +template +static bool has_explicitly_named_overload() { + return requires { Fn().*&Fn::operator(); }; +} + +int main() { + has_explicitly_named_overload(); +} + +template +constexpr bool has_explicitly_named_overload_2() { + return requires { Fn().*&Fn::operator(); }; +} + +static_assert(!has_explicitly_named_overload_2()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org http
[clang] [clang-format] Limit how much work guessLanguage() can do (PR #78925)
owenca wrote: > > @HighCommander4 I got a better idea. It seems that we don't need to add the > > parameter! See #82957. I think all you need to do is to call `getStyle()` > > with the default `""` for the `StringRef Code` argument to skip the > > Objective-C guesser. > > Thanks. That does seem simpler, and seems like it should work just as well > since the language guesser is the only thing that uses the `Code` argument. I've merged #82957. https://github.com/llvm/llvm-project/pull/78925 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format] Add a parameter to getStyle() and guessLanguage() (PR #82911)
https://github.com/owenca closed https://github.com/llvm/llvm-project/pull/82911 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-format][NFC] Skip ObjCHeaderStyleGuesser for empty code (PR #82957)
https://github.com/owenca closed https://github.com/llvm/llvm-project/pull/82957 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] b2a4f64 - [clang-format][NFC] Skip ObjCHeaderStyleGuesser for empty code (#82957)
Author: Owen Pan Date: 2024-02-26T20:46:46-08:00 New Revision: b2a4f64e19247d0553d3dc63af62b652664c3cd6 URL: https://github.com/llvm/llvm-project/commit/b2a4f64e19247d0553d3dc63af62b652664c3cd6 DIFF: https://github.com/llvm/llvm-project/commit/b2a4f64e19247d0553d3dc63af62b652664c3cd6.diff LOG: [clang-format][NFC] Skip ObjCHeaderStyleGuesser for empty code (#82957) Added: Modified: clang/lib/Format/Format.cpp Removed: diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp index 794e326fb1c948..13588ff705f544 100644 --- a/clang/lib/Format/Format.cpp +++ b/clang/lib/Format/Format.cpp @@ -3923,7 +3923,7 @@ FormatStyle::LanguageKind guessLanguage(StringRef FileName, StringRef Code) { auto Extension = llvm::sys::path::extension(FileName); // If there's no file extension (or it's .h), we need to check the contents // of the code to see if it contains Objective-C. -if (Extension.empty() || Extension == ".h") { +if (!Code.empty() && (Extension.empty() || Extension == ".h")) { auto NonEmptyFileName = FileName.empty() ? "guess.h" : FileName; Environment Env(Code, NonEmptyFileName, /*Ranges=*/{}); ObjCHeaderStyleGuesser Guesser(Env, getLLVMStyle()); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [ObjC] Check entire chain of superclasses to see if class layout is statically known (PR #81335)
https://github.com/rjmccall approved this pull request. Thanks, that looks great. https://github.com/llvm/llvm-project/pull/81335 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm (PR #82968)
chenzheng1030 wrote: > If you run into issues using normal integer ops, please file bugs. Most > people aren't going to hand-tune their code like this; builtins like this are > at best an ugly workaround. Yes, a user should not try to write source code(using compiler builtins) to just emit one "powerful" instruction. Instead, it is compiler's responsibility to generate these instructions according to user's source codes. I think the reason why these builtins were added is LLVM PowerPC target wants to keep its compatibility with XLC/C++ commercial compiler related to these builtins. https://github.com/llvm/llvm-project/pull/82968 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][dataflow] Remove deprecated `ValueModel::merge()` function. (PR #82602)
https://github.com/ymand approved this pull request. https://github.com/llvm/llvm-project/pull/82602 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm (PR #82968)
@@ -641,6 +641,7 @@ PPCTargetLowering::PPCTargetLowering(const PPCTargetMachine &TM, // We want to custom lower some of our intrinsics. setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom); + // setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::i64, Custom); chenzheng1030 wrote: Is this needed? https://github.com/llvm/llvm-project/pull/82968 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Add intrinsics for rldimi/rlwimi/rlwnm (PR #82968)
@@ -10722,6 +10723,20 @@ static bool getVectorCompareInfo(SDValue Intrin, int &CompareOpc, return true; } +bool isContiguousMask(const APInt &Val, unsigned &MB, unsigned &ME, chenzheng1030 wrote: Is it possible to reuse `isRunOfOnes()`/`isRunOfOnes64()` in `llvm/lib/Target/PowerPC/MCTargetDesc/PPCMCTargetDesc.h`? https://github.com/llvm/llvm-project/pull/82968 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Define SwiftInfo for RISCVTargetCodeGenInfo (PR #82152)
https://github.com/wangpc-pp approved this pull request. LGTM. https://github.com/llvm/llvm-project/pull/82152 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [C++20] [Modules] [Itanium ABI] Generate the vtable in the module unit of dynamic classes (PR #75912)
ChuanqiXu9 wrote: @rjmccall @dwblaikie https://github.com/llvm/llvm-project/pull/75912 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)
https://github.com/chapuni edited https://github.com/llvm/llvm-project/pull/82448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)
https://github.com/chapuni edited https://github.com/llvm/llvm-project/pull/82448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Issue #63106: [сlang] Representation of ellipsis in AST (PR #80976)
@@ -41,7 +41,7 @@ void TestCatch2() { try { } // CHECK-NEXT:CXXCatchStmt -// CHECK-NEXT: NULL +// CHECK-NEXT: VarDecl {{.*}} '' ChuanqiXu9 wrote: Maybe we can improve to print this. https://github.com/llvm/llvm-project/pull/80976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Issue #63106: [сlang] Representation of ellipsis in AST (PR #80976)
@@ -1053,6 +1053,10 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { LLVM_PREFERRED_TYPE(bool) unsigned ExceptionVar : 1; +/// To Check the ellipsis +LLVM_PREFERRED_TYPE(bool) +unsigned EllipsisVar : 1; ChuanqiXu9 wrote: Should we move this to `ParmVarDeclBitfields`? https://github.com/llvm/llvm-project/pull/80976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Issue #63106: [сlang] Representation of ellipsis in AST (PR #80976)
@@ -16983,7 +16983,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, /// ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch /// handler. -Decl *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D) { +Decl *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D, bool isCatchAll) { ChuanqiXu9 wrote: I am hesitate on this. IIUC, previously the `catch(...)` format is reprensented as the exception decl as nullptr? Then if yes, we should be able to reuse that. https://github.com/llvm/llvm-project/pull/80976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Issue #63106: [сlang] Representation of ellipsis in AST (PR #80976)
@@ -1053,6 +1053,10 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { LLVM_PREFERRED_TYPE(bool) unsigned ExceptionVar : 1; +/// To Check the ellipsis ChuanqiXu9 wrote: The comment is not clear https://github.com/llvm/llvm-project/pull/80976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Issue #63106: [сlang] Representation of ellipsis in AST (PR #80976)
@@ -2698,9 +2698,16 @@ StmtResult Parser::ParseCXXCatchBlock(bool FnCatch) { Declarator ExDecl(DS, Attributes, DeclaratorContext::CXXCatch); ParseDeclarator(ExDecl); ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl); - } else -ConsumeToken(); - + } + else { + CatchLoc = ConsumeToken(); + // explicitly creating a var of type no-type for '...' and marking it as catch_all + ParsedAttributes Attributes(AttrFactory); + DeclSpec DS(AttrFactory); + Declarator ExDecl(DS, Attributes, DeclaratorContext::BlockLiteral); + ParseDeclarator(ExDecl); + ExceptionDecl = Actions.ActOnExceptionDeclarator(getCurScope(), ExDecl, true); + } ChuanqiXu9 wrote: I am hesitate on this. IIUC, previously the catch(...) format is reprensented as the exception decl as nullptr? Then if yes, we should be able to reuse that. https://github.com/llvm/llvm-project/pull/80976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Issue #63106: [сlang] Representation of ellipsis in AST (PR #80976)
@@ -271,6 +271,9 @@ void TextNodeDumper::Visit(const Decl *D) { OS << " hidden"; if (D->isImplicit()) OS << " implicit"; + if (const VarDecl *ND = dyn_cast(D)) + if (ND->isEllipsisVariable()) + OS << " catch_all"; ChuanqiXu9 wrote: ditto https://github.com/llvm/llvm-project/pull/80976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Issue #63106: [сlang] Representation of ellipsis in AST (PR #80976)
@@ -115,6 +115,10 @@ void JSONNodeDumper::Visit(const Decl *D) { else if (D->isThisDeclarationReferenced()) JOS.attribute("isReferenced", true); + if (const VarDecl *ND = dyn_cast(D)) + if (ND->isEllipsisVariable()) + JOS.attribute("catch_all", true); ChuanqiXu9 wrote: Format this. https://github.com/llvm/llvm-project/pull/80976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Issue #63106: [сlang] Representation of ellipsis in AST (PR #80976)
@@ -1474,6 +1478,16 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { NonParmVarDeclBits.ExceptionVar = EV; } + /// Determine the Ellipsis (...) or not + bool isEllipsisVariable() const { +return isa(this) ? false : NonParmVarDeclBits.EllipsisVar; + } + void setEllipsisVariable(bool EV) { +assert(!isa(this)); +NonParmVarDeclBits.EllipsisVar = EV; + } ChuanqiXu9 wrote: Should we move this to ParmVarDecl? https://github.com/llvm/llvm-project/pull/80976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Issue #63106: [сlang] Representation of ellipsis in AST (PR #80976)
https://github.com/ChuanqiXu9 commented: +1 that we should reduce the impact of the patch as much as possible. Also every time we change the data member of decls and stmts, we need to update the serialization part. https://github.com/llvm/llvm-project/pull/80976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Issue #63106: [сlang] Representation of ellipsis in AST (PR #80976)
https://github.com/ChuanqiXu9 edited https://github.com/llvm/llvm-project/pull/80976 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][HTO] Add clang attribute for propagating llvm-level information (PR #83059)
https://github.com/wsmoses updated https://github.com/llvm/llvm-project/pull/83059 >From c01b559836ca62648c5f95a6441888514347a1ea Mon Sep 17 00:00:00 2001 From: "William S. Moses" Date: Mon, 26 Feb 2024 16:17:55 -0500 Subject: [PATCH 1/2] [Clang][HTO] Add clang attribute for propagating llvm-level information --- clang/include/clang/Basic/Attr.td | 7 +++ clang/include/clang/Basic/AttrDocs.td | 13 + clang/lib/CodeGen/CGCall.cpp | 16 clang/lib/CodeGen/CodeGenFunction.cpp | 19 +++ clang/test/CodeGen/attr-llvmfn.c | 14 ++ 5 files changed, 69 insertions(+) create mode 100644 clang/test/CodeGen/attr-llvmfn.c diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fa191c7378dba4..044f4fada3590f 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2211,6 +2211,13 @@ def AllocAlign : InheritableAttr { let Documentation = [AllocAlignDocs]; } +def LLVMFuncAttr : InheritableAttr { + let Spellings = [Clang<"llvm_fn_attr">]; + let Args = [StringArgument<"LLVMAttrName">, StringArgument<"LLVMAttrValue">]; + let Documentation = [LLVMFuncAttrDocs]; + let InheritEvenIfAlreadyPresent = 1; +} + def NoReturn : InheritableAttr { let Spellings = [GCC<"noreturn">, Declspec<"noreturn">]; // FIXME: Does GCC allow this on the function instead? diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index b96fbddd51154c..3f93bb6d6fc648 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -781,6 +781,19 @@ pointer is not sufficiently aligned. }]; } +def LLVMFuncAttrDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Use ``__attribute__((llvm_fn_attr(attr_name, attr_value)))`` on a function to specify an LLVM function attribute that will be added to this function. + +Note that uses of this attribute are highly compiler specific as the meaning and availability of LLVM attributes may change between compiler versions. + +This attribute is only intended for advanced users who need to specify specific information only available in LLVM attributes. Use of attributes which are not tied to a specific version of Clang (e.g. pure) should be preferred when available. + +The first arugment is a string representing the name of the LLVM attribute to be applied and the second arugment is a string representing its value. + }]; +} + def EnableIfDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index d05cf1c6e1814e..4725dce607eee9 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2465,6 +2465,22 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, if (TargetDecl->hasAttr()) FuncAttrs.addAttribute("aarch64_pstate_sm_body"); + +for (auto Attr : TargetDecl->specific_attrs()) { + auto name = Attr->getLLVMAttrName(); + auto value = Attr->getLLVMAttrValue(); + + Attribute Attr; + auto EnumAttr = llvm::Attribute::getAttrKindFromName(name); + if (EnumAttr == llvm::Attribute::None) +Attr = llvm::Attribute::get(getLLVMContext(), name, value); + else { +assert(value.size() == 0 && + "enum attribute does not support value yet"); +Attr = llvm::Attribute::get(getLLVMContext(), EnumAttr); + } + FuncAttrs.addAttribute(Attr); +} } // Attach "no-builtins" attributes to: diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 1ad905078d349c..5d0edd4bbf83c7 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -831,6 +831,25 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass) SanOpts.Mask &= ~SanitizerKind::Null; + if (D) { +for (auto Attr : + template TargetDecl->specific_attrs()) { + auto name = Attr->getLLVMAttrName(); + auto value = Attr->getLLVMAttrValue(); + + Attribute Attr; + auto EnumAttr = llvm::Attribute::getAttrKindFromName(name); + if (EnumAttr == llvm::Attribute::None) +Attr = llvm::Attribute::get(getLLVMContext(), name, value); + else { +assert(value.size() == 0 && + "enum attribute does not support value yet"); +Attr = llvm::Attribute::get(getLLVMContext(), EnumAttr); + } + Fn->addFnAttr(Attr); +} + } + // Apply xray attributes to the function (as a string, for now) bool AlwaysXRayAttr = false; if (const auto *XRayAttr = D ? D->getAttr() : nullptr) { diff --git a/clang/test/CodeGen/attr-llvmfn.c b/clang/test/CodeGen/attr-llvmfn.c new file mode 100644 index 00..72f14a726f795e --- /dev/null +++ b/clang/test/CodeGen/attr
[clang] [llvm] [Driver] Default -msmall-data-limit= to 0 and clean up code (PR #83093)
llvmbot wrote: @llvm/pr-subscribers-clang-driver @llvm/pr-subscribers-clang @llvm/pr-subscribers-backend-risc-v Author: Fangrui Song (MaskRay) Changes D57497 added -msmall-data-limit= as an alias for -G and defaulted it to 8 for -fno-pic/-fpie. The behavior is already different from GCC in a few ways: * GCC doesn't accept -G. * GCC -fpie doesn't seem to use -msmall-data-limit=. * GCC emits .srodata.cst* that we don't use (#82214). Writable contents caused confusion (https://bugs.chromium.org/p/llvm/issues/detail?id=61) In addition, * claiming `-shared` means we don't get a desired `-Wunused-command-line-argument` for `clang --target=riscv64-linux-gnu -fpic -c -shared a.c`. * -mcmodel=large doesn't work for RISC-V yet, so the special case is strange. * It's quite unusual to emit a warning when an option (unrelated to relocation model) is used with -fpic. * We don't want future configurations (Android) to continue adding customization to `SetRISCVSmallDataLimit`. I believe the extra code just doesn't pull its weight and should be cleaned up. This patch also changes the default to 0. GP relaxation users are encouraged to specify these customization options explicitly. --- Full diff: https://github.com/llvm/llvm-project/pull/83093.diff 5 Files Affected: - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+4-37) - (modified) clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c (+2-2) - (removed) clang/test/Driver/riscv-sdata-warning.c (-4) - (added) clang/test/Driver/riscv-sdata.c (+5) - (modified) llvm/lib/Target/RISCV/RISCVTargetObjectFile.h (+1-1) ``diff diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 6e1b7e8657d0dc..9b9eab3990607f 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2029,42 +2029,6 @@ void Clang::AddPPCTargetArgs(const ArgList &Args, } } -static void SetRISCVSmallDataLimit(const ToolChain &TC, const ArgList &Args, - ArgStringList &CmdArgs) { - const Driver &D = TC.getDriver(); - const llvm::Triple &Triple = TC.getTriple(); - // Default small data limitation is eight. - const char *SmallDataLimit = "8"; - // Get small data limitation. - if (Args.getLastArg(options::OPT_shared, options::OPT_fpic, - options::OPT_fPIC)) { -// Not support linker relaxation for PIC. -SmallDataLimit = "0"; -if (Args.hasArg(options::OPT_G)) { - D.Diag(diag::warn_drv_unsupported_sdata); -} - } else if (Args.getLastArgValue(options::OPT_mcmodel_EQ) - .equals_insensitive("large") && - (Triple.getArch() == llvm::Triple::riscv64)) { -// Not support linker relaxation for RV64 with large code model. -SmallDataLimit = "0"; -if (Args.hasArg(options::OPT_G)) { - D.Diag(diag::warn_drv_unsupported_sdata); -} - } else if (Triple.isAndroid()) { -// GP relaxation is not supported on Android. -SmallDataLimit = "0"; -if (Args.hasArg(options::OPT_G)) { - D.Diag(diag::warn_drv_unsupported_sdata); -} - } else if (Arg *A = Args.getLastArg(options::OPT_G)) { -SmallDataLimit = A->getValue(); - } - // Forward the -msmall-data-limit= option. - CmdArgs.push_back("-msmall-data-limit"); - CmdArgs.push_back(SmallDataLimit); -} - void Clang::AddRISCVTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { const llvm::Triple &Triple = getToolChain().getTriple(); @@ -2073,7 +2037,10 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args, CmdArgs.push_back("-target-abi"); CmdArgs.push_back(ABIName.data()); - SetRISCVSmallDataLimit(getToolChain(), Args, CmdArgs); + if (Arg *A = Args.getLastArg(options::OPT_G)) { +CmdArgs.push_back("-msmall-data-limit"); +CmdArgs.push_back(A->getValue()); + } if (!Args.hasFlag(options::OPT_mimplicit_float, options::OPT_mno_implicit_float, true)) diff --git a/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c b/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c index 9bd69e7995877e..e91b2e7f225f52 100644 --- a/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c +++ b/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c @@ -30,14 +30,14 @@ void test(void) {} -// RV32-DEFAULT: !{i32 8, !"SmallDataLimit", i32 8} +// RV32-DEFAULT: !{i32 8, !"SmallDataLimit", i32 0} // RV32-G4: !{i32 8, !"SmallDataLimit", i32 4} // RV32-S0: !{i32 8, !"SmallDataLimit", i32 0} // RV32-S2G4:!{i32 8, !"SmallDataLimit", i32 4} // RV32-T16: !{i32 8, !"SmallDataLimit", i32 16} // RV32-PIC: !{i32 8, !"SmallDataLimit", i32 0} -// RV64-DEFAULT: !{i32 8, !"SmallDataLimit", i32 8} +// RV64-DEFAULT: !{i32 8, !"SmallDataLimit", i32 0} // RV64-G4: !{i32 8, !"SmallDataLimit", i32 4} // RV64-S0: !{i32 8, !"SmallDataLimit", i32 0} // RV64-S2G4:!{i32 8, !"SmallDataLimit", i32 4} diff --git a/clang/test/Driver/riscv-sdata-warni
[clang] [llvm] [Driver] Default -msmall-data-limit= to 0 and clean up code (PR #83093)
https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/83093 D57497 added -msmall-data-limit= as an alias for -G and defaulted it to 8 for -fno-pic/-fpie. The behavior is already different from GCC in a few ways: * GCC doesn't accept -G. * GCC -fpie doesn't seem to use -msmall-data-limit=. * GCC emits .srodata.cst* that we don't use (#82214). Writable contents caused confusion (https://bugs.chromium.org/p/llvm/issues/detail?id=61) In addition, * claiming `-shared` means we don't get a desired `-Wunused-command-line-argument` for `clang --target=riscv64-linux-gnu -fpic -c -shared a.c`. * -mcmodel=large doesn't work for RISC-V yet, so the special case is strange. * It's quite unusual to emit a warning when an option (unrelated to relocation model) is used with -fpic. * We don't want future configurations (Android) to continue adding customization to `SetRISCVSmallDataLimit`. I believe the extra code just doesn't pull its weight and should be cleaned up. This patch also changes the default to 0. GP relaxation users are encouraged to specify these customization options explicitly. >From dbc9ddd9a9b1b73d56f8aab5265db36a44e6fcaf Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 26 Feb 2024 17:58:55 -0800 Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?= =?UTF-8?q?l=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.4 --- clang/lib/Driver/ToolChains/Clang.cpp | 41 ++- .../CodeGen/RISCV/riscv-sdata-module-flag.c | 4 +- clang/test/Driver/riscv-sdata-warning.c | 4 -- clang/test/Driver/riscv-sdata.c | 5 +++ llvm/lib/Target/RISCV/RISCVTargetObjectFile.h | 2 +- 5 files changed, 12 insertions(+), 44 deletions(-) delete mode 100644 clang/test/Driver/riscv-sdata-warning.c create mode 100644 clang/test/Driver/riscv-sdata.c diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 6e1b7e8657d0dc..9b9eab3990607f 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -2029,42 +2029,6 @@ void Clang::AddPPCTargetArgs(const ArgList &Args, } } -static void SetRISCVSmallDataLimit(const ToolChain &TC, const ArgList &Args, - ArgStringList &CmdArgs) { - const Driver &D = TC.getDriver(); - const llvm::Triple &Triple = TC.getTriple(); - // Default small data limitation is eight. - const char *SmallDataLimit = "8"; - // Get small data limitation. - if (Args.getLastArg(options::OPT_shared, options::OPT_fpic, - options::OPT_fPIC)) { -// Not support linker relaxation for PIC. -SmallDataLimit = "0"; -if (Args.hasArg(options::OPT_G)) { - D.Diag(diag::warn_drv_unsupported_sdata); -} - } else if (Args.getLastArgValue(options::OPT_mcmodel_EQ) - .equals_insensitive("large") && - (Triple.getArch() == llvm::Triple::riscv64)) { -// Not support linker relaxation for RV64 with large code model. -SmallDataLimit = "0"; -if (Args.hasArg(options::OPT_G)) { - D.Diag(diag::warn_drv_unsupported_sdata); -} - } else if (Triple.isAndroid()) { -// GP relaxation is not supported on Android. -SmallDataLimit = "0"; -if (Args.hasArg(options::OPT_G)) { - D.Diag(diag::warn_drv_unsupported_sdata); -} - } else if (Arg *A = Args.getLastArg(options::OPT_G)) { -SmallDataLimit = A->getValue(); - } - // Forward the -msmall-data-limit= option. - CmdArgs.push_back("-msmall-data-limit"); - CmdArgs.push_back(SmallDataLimit); -} - void Clang::AddRISCVTargetArgs(const ArgList &Args, ArgStringList &CmdArgs) const { const llvm::Triple &Triple = getToolChain().getTriple(); @@ -2073,7 +2037,10 @@ void Clang::AddRISCVTargetArgs(const ArgList &Args, CmdArgs.push_back("-target-abi"); CmdArgs.push_back(ABIName.data()); - SetRISCVSmallDataLimit(getToolChain(), Args, CmdArgs); + if (Arg *A = Args.getLastArg(options::OPT_G)) { +CmdArgs.push_back("-msmall-data-limit"); +CmdArgs.push_back(A->getValue()); + } if (!Args.hasFlag(options::OPT_mimplicit_float, options::OPT_mno_implicit_float, true)) diff --git a/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c b/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c index 9bd69e7995877e..e91b2e7f225f52 100644 --- a/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c +++ b/clang/test/CodeGen/RISCV/riscv-sdata-module-flag.c @@ -30,14 +30,14 @@ void test(void) {} -// RV32-DEFAULT: !{i32 8, !"SmallDataLimit", i32 8} +// RV32-DEFAULT: !{i32 8, !"SmallDataLimit", i32 0} // RV32-G4: !{i32 8, !"SmallDataLimit", i32 4} // RV32-S0: !{i32 8, !"SmallDataLimit", i32 0} // RV32-S2G4:!{i32 8, !"SmallDataLimit", i32 4} // RV32-T16: !{i32 8, !"SmallDataLimit", i32 16} // RV32-PIC: !{i32 8, !"SmallDataLimit"
[clang] [clang] reject to capture variable in `RequiresExprBodyDecl` (PR #78598)
zyn0217 wrote: Could you please explain why you're closing the PR? https://github.com/llvm/llvm-project/pull/78598 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] reject to capture variable in `RequiresExprBodyDecl` (PR #78598)
https://github.com/HerrCai0907 closed https://github.com/llvm/llvm-project/pull/78598 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [PowerPC] Support local-dynamic TLS relocation on AIX (PR #66316)
@@ -370,11 +370,22 @@ namespace llvm { /// G8RC = TLSGD_AIX, TOC_ENTRY, TOC_ENTRY /// Op that combines two register copies of TOC entries /// (region handle into R3 and variable offset into R4) followed by a -/// GET_TLS_ADDR node which will be expanded to a call to __get_tls_addr. +/// GET_TLS_ADDR node which will be expanded to a call to .__tls_get_addr. /// This node is used in 64-bit mode as well (in which case the result is /// G8RC and inputs are X3/X4). TLSGD_AIX, +/// %x3 = GET_TLS_MOD_AIX _$TLSML - For the AIX local-dynamic TLS model, +/// produces a call to .__tls_get_mod(_$TLSML\@ml). +GET_TLS_MOD_AIX, + +/// [GP|G8]RC = TLSLD_AIX, TOC_ENTRY(module handle) +/// Op that with single input of module handle TOC entry in R3, and orcguru wrote: Sure. This is better. Thank you! https://github.com/llvm/llvm-project/pull/66316 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [CLANG][DWARF] Do not emit -ggnu-pubnames for split dwarf version 5. (PR #82840)
https://github.com/dwblaikie approved this pull request. https://github.com/llvm/llvm-project/pull/82840 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][HTO] Add clang attribute for propagating llvm-level information (PR #83059)
@@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm -o - | FileCheck %s + +void t1() __attribute__((llvm_fn_attr("custom_attr", "custom_value"), llvm_fn_attr("second_attr", "second_value"))); + +void t1() +{ +} + +void t2(); + +void t3() { + t2() attribute__((llvm_fn_attr("custom_attr", "custom_value"), llvm_fn_attr("second_attr", "second_value"))); +} + wsmoses wrote: @jdoerfert okay tests added and appear working, ready for review https://github.com/llvm/llvm-project/pull/83059 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][HTO] Add clang attribute for propagating llvm-level information (PR #83059)
https://github.com/wsmoses updated https://github.com/llvm/llvm-project/pull/83059 >From c01b559836ca62648c5f95a6441888514347a1ea Mon Sep 17 00:00:00 2001 From: "William S. Moses" Date: Mon, 26 Feb 2024 16:17:55 -0500 Subject: [PATCH 1/2] [Clang][HTO] Add clang attribute for propagating llvm-level information --- clang/include/clang/Basic/Attr.td | 7 +++ clang/include/clang/Basic/AttrDocs.td | 13 + clang/lib/CodeGen/CGCall.cpp | 16 clang/lib/CodeGen/CodeGenFunction.cpp | 19 +++ clang/test/CodeGen/attr-llvmfn.c | 14 ++ 5 files changed, 69 insertions(+) create mode 100644 clang/test/CodeGen/attr-llvmfn.c diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fa191c7378dba4..044f4fada3590f 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2211,6 +2211,13 @@ def AllocAlign : InheritableAttr { let Documentation = [AllocAlignDocs]; } +def LLVMFuncAttr : InheritableAttr { + let Spellings = [Clang<"llvm_fn_attr">]; + let Args = [StringArgument<"LLVMAttrName">, StringArgument<"LLVMAttrValue">]; + let Documentation = [LLVMFuncAttrDocs]; + let InheritEvenIfAlreadyPresent = 1; +} + def NoReturn : InheritableAttr { let Spellings = [GCC<"noreturn">, Declspec<"noreturn">]; // FIXME: Does GCC allow this on the function instead? diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index b96fbddd51154c..3f93bb6d6fc648 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -781,6 +781,19 @@ pointer is not sufficiently aligned. }]; } +def LLVMFuncAttrDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Use ``__attribute__((llvm_fn_attr(attr_name, attr_value)))`` on a function to specify an LLVM function attribute that will be added to this function. + +Note that uses of this attribute are highly compiler specific as the meaning and availability of LLVM attributes may change between compiler versions. + +This attribute is only intended for advanced users who need to specify specific information only available in LLVM attributes. Use of attributes which are not tied to a specific version of Clang (e.g. pure) should be preferred when available. + +The first arugment is a string representing the name of the LLVM attribute to be applied and the second arugment is a string representing its value. + }]; +} + def EnableIfDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index d05cf1c6e1814e..4725dce607eee9 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2465,6 +2465,22 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, if (TargetDecl->hasAttr()) FuncAttrs.addAttribute("aarch64_pstate_sm_body"); + +for (auto Attr : TargetDecl->specific_attrs()) { + auto name = Attr->getLLVMAttrName(); + auto value = Attr->getLLVMAttrValue(); + + Attribute Attr; + auto EnumAttr = llvm::Attribute::getAttrKindFromName(name); + if (EnumAttr == llvm::Attribute::None) +Attr = llvm::Attribute::get(getLLVMContext(), name, value); + else { +assert(value.size() == 0 && + "enum attribute does not support value yet"); +Attr = llvm::Attribute::get(getLLVMContext(), EnumAttr); + } + FuncAttrs.addAttribute(Attr); +} } // Attach "no-builtins" attributes to: diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 1ad905078d349c..5d0edd4bbf83c7 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -831,6 +831,25 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass) SanOpts.Mask &= ~SanitizerKind::Null; + if (D) { +for (auto Attr : + template TargetDecl->specific_attrs()) { + auto name = Attr->getLLVMAttrName(); + auto value = Attr->getLLVMAttrValue(); + + Attribute Attr; + auto EnumAttr = llvm::Attribute::getAttrKindFromName(name); + if (EnumAttr == llvm::Attribute::None) +Attr = llvm::Attribute::get(getLLVMContext(), name, value); + else { +assert(value.size() == 0 && + "enum attribute does not support value yet"); +Attr = llvm::Attribute::get(getLLVMContext(), EnumAttr); + } + Fn->addFnAttr(Attr); +} + } + // Apply xray attributes to the function (as a string, for now) bool AlwaysXRayAttr = false; if (const auto *XRayAttr = D ? D->getAttr() : nullptr) { diff --git a/clang/test/CodeGen/attr-llvmfn.c b/clang/test/CodeGen/attr-llvmfn.c new file mode 100644 index 00..72f14a726f795e --- /dev/null +++ b/clang/test/CodeGen/attr
[clang] [APINotes] Fix a few accidental refactoring artifacts (PR #83057)
https://github.com/egorzhdan closed https://github.com/llvm/llvm-project/pull/83057 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 5e4c436 - [APINotes] Fix a few accidental refactoring artifacts
Author: Egor Zhdan Date: 2024-02-27T00:37:15Z New Revision: 5e4c4365f89b7b31ee3868114dd0f6c5d483e42b URL: https://github.com/llvm/llvm-project/commit/5e4c4365f89b7b31ee3868114dd0f6c5d483e42b DIFF: https://github.com/llvm/llvm-project/commit/5e4c4365f89b7b31ee3868114dd0f6c5d483e42b.diff LOG: [APINotes] Fix a few accidental refactoring artifacts This fixes a few breakages introduced during upstreaming. Added: Modified: clang/lib/APINotes/APINotesReader.cpp clang/lib/APINotes/APINotesWriter.cpp Removed: diff --git a/clang/lib/APINotes/APINotesReader.cpp b/clang/lib/APINotes/APINotesReader.cpp index ff9b95d9bf75e3..55ea4bae81e6e8 100644 --- a/clang/lib/APINotes/APINotesReader.cpp +++ b/clang/lib/APINotes/APINotesReader.cpp @@ -81,9 +81,9 @@ class VersionedTableInfo { auto version = ReadVersionTuple(Data); const auto *DataBefore = Data; (void)DataBefore; + auto UnversionedData = Derived::readUnversioned(Key, Data); assert(Data != DataBefore && "Unversioned data reader didn't move pointer"); - auto UnversionedData = Derived::readUnversioned(Key, Data); Result.push_back({version, UnversionedData}); } return Result; @@ -148,7 +148,7 @@ class IdentifierTableInfo { external_key_type GetExternalKey(internal_key_type Key) { return Key; } hash_value_type ComputeHash(internal_key_type Key) { -return llvm::hash_value(Key); +return llvm::djbHash(Key); } static bool EqualKey(internal_key_type LHS, internal_key_type RHS) { @@ -1797,8 +1797,8 @@ APINotesReader::Create(std::unique_ptr InputBuffer, template APINotesReader::VersionedInfo::VersionedInfo( llvm::VersionTuple Version, -llvm::SmallVector, 1> Results) -: Results(std::move(Results)) { +llvm::SmallVector, 1> R) +: Results(std::move(R)) { assert(!Results.empty()); assert(std::is_sorted( diff --git a/clang/lib/APINotes/APINotesWriter.cpp b/clang/lib/APINotes/APINotesWriter.cpp index 62a2ab1799913a..76fd24ccfae984 100644 --- a/clang/lib/APINotes/APINotesWriter.cpp +++ b/clang/lib/APINotes/APINotesWriter.cpp @@ -128,6 +128,7 @@ class APINotesWriter::Implementation { SelectorID getSelector(ObjCSelectorRef SelectorRef) { // Translate the selector reference into a stored selector. StoredObjCSelector Selector; +Selector.NumArgs = SelectorRef.NumArgs; Selector.Identifiers.reserve(SelectorRef.Identifiers.size()); for (auto piece : SelectorRef.Identifiers) Selector.Identifiers.push_back(getIdentifier(piece)); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Update -Wformat warnings for fixed-point format specifiers (PR #82855)
https://github.com/PiJoules updated https://github.com/llvm/llvm-project/pull/82855 >From 42d128e1a2bc6b00a8aa5393c763de4f17935068 Mon Sep 17 00:00:00 2001 From: Leonard Chan Date: Fri, 23 Feb 2024 16:57:58 -0800 Subject: [PATCH] [clang] Update -Wformat warnings for fixed-point format specifiers ISO/IEC TR 18037 defines %r, %R, %k, and %K for fixed point format specifiers. -Wformat should not warn on these when they are provided. --- clang/include/clang/AST/ASTContext.h | 4 + clang/include/clang/AST/FormatString.h | 11 ++ clang/lib/AST/ASTContext.cpp | 36 +++ clang/lib/AST/FormatString.cpp | 25 + clang/lib/AST/PrintfFormatString.cpp | 87 ++- clang/test/Sema/format-fixed-point.c | 142 + 6 files changed, 302 insertions(+), 3 deletions(-) create mode 100644 clang/test/Sema/format-fixed-point.c diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 12ce9af1e53f63..ff6b64c7f72d57 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2981,6 +2981,10 @@ class ASTContext : public RefCountedBase { // corresponding saturated type for a given fixed point type. QualType getCorrespondingSaturatedType(QualType Ty) const; + // Per ISO N1169, this method accepts fixed point types and returns the + // corresponding non-saturated type for a given fixed point type. + QualType getCorrespondingUnsaturatedType(QualType Ty) const; + // This method accepts fixed point types and returns the corresponding signed // type. Unlike getCorrespondingUnsignedType(), this only accepts unsigned // fixed point types because there are unsigned integer types like bool and diff --git a/clang/include/clang/AST/FormatString.h b/clang/include/clang/AST/FormatString.h index 5c4ad9baaef608..e2232fb4a47153 100644 --- a/clang/include/clang/AST/FormatString.h +++ b/clang/include/clang/AST/FormatString.h @@ -171,6 +171,14 @@ class ConversionSpecifier { ZArg, // MS extension +// ISO/IEC TR 18037 (fixed-point) specific specifiers. +kArg, // %k for signed accum types +KArg, // %K for unsigned accum types +rArg, // %r for signed fract types +RArg, // %R for unsigned fract types +FixedPointArgBeg = kArg, +FixedPointArgEnd = RArg, + // Objective-C specific specifiers. ObjCObjArg, // '@' ObjCBeg = ObjCObjArg, @@ -237,6 +245,9 @@ class ConversionSpecifier { bool isDoubleArg() const { return kind >= DoubleArgBeg && kind <= DoubleArgEnd; } + bool isFixedPointArg() const { +return kind >= FixedPointArgBeg && kind <= FixedPointArgEnd; + } const char *toString() const; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index c475c841233c59..5a8fae76a43a4d 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -13314,6 +13314,42 @@ QualType ASTContext::getCommonSugaredType(QualType X, QualType Y, return R; } +QualType ASTContext::getCorrespondingUnsaturatedType(QualType Ty) const { + assert(Ty->isFixedPointType()); + + if (Ty->isUnsaturatedFixedPointType()) +return Ty; + + switch (Ty->castAs()->getKind()) { + default: +llvm_unreachable("Not a saturated fixed point type!"); + case BuiltinType::SatShortAccum: +return ShortAccumTy; + case BuiltinType::SatAccum: +return AccumTy; + case BuiltinType::SatLongAccum: +return LongAccumTy; + case BuiltinType::SatUShortAccum: +return UnsignedShortAccumTy; + case BuiltinType::SatUAccum: +return UnsignedAccumTy; + case BuiltinType::SatULongAccum: +return UnsignedLongAccumTy; + case BuiltinType::SatShortFract: +return ShortFractTy; + case BuiltinType::SatFract: +return FractTy; + case BuiltinType::SatLongFract: +return LongFractTy; + case BuiltinType::SatUShortFract: +return UnsignedShortFractTy; + case BuiltinType::SatUFract: +return UnsignedFractTy; + case BuiltinType::SatULongFract: +return UnsignedLongFractTy; + } +} + QualType ASTContext::getCorrespondingSaturatedType(QualType Ty) const { assert(Ty->isFixedPointType()); diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp index c5d14b4af7ff15..0c80ad109ccbb2 100644 --- a/clang/lib/AST/FormatString.cpp +++ b/clang/lib/AST/FormatString.cpp @@ -403,6 +403,10 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const { else if (ETy->isUnscopedEnumerationType()) argTy = ETy->getDecl()->getIntegerType(); } + + if (argTy->isSaturatedFixedPointType()) +argTy = C.getCorrespondingUnsaturatedType(argTy); + argTy = C.getCanonicalType(argTy).getUnqualifiedType(); if (T == argTy) @@ -761,6 +765,16 @@ const char *ConversionSpecifier::toString() const { // MS specific specifiers. case ZArg: return "Z"; + + // ISO/IEC TR 18037 (fixed-point) specific specifiers. + case rArg: +return "r"; + case RArg: +
[clang] [clang] Update -Wformat warnings for fixed-point format specifiers (PR #82855)
PiJoules wrote: > This patch looks fine from my end, but I was wondering: Does clang do > warnings for printf flags that don't apply to a specific conversion? As an > example, in the format specifier `"%+R"` is technically undefined since the > `+` flag only applies to signed conversions. In practice it's not a big deal > (we just ignore irrelevant flags) but it could be an area of further > development. Oh, that's a good point. Since `+` is used for signed types, I'll also emit a warning for `+` with unsigned types similar to how clang does it with unsigned ints. https://github.com/llvm/llvm-project/pull/82855 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add -Wmissing-designated-field-initializers (PR #81364)
@@ -120,6 +120,10 @@ Non-comprehensive list of changes in this release New Compiler Flags -- +- ``-Wmissing-designated-field-initializers``, grouped under ``-Wmissing-designated-field-initializers``. shafik wrote: CC @AaronBallman https://github.com/llvm/llvm-project/pull/81364 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Update -Wformat warnings for fixed-point format specifiers (PR #82855)
michaelrj-google wrote: This patch looks fine from my end, but I was wondering: Does clang do warnings for printf flags that don't apply to a specific conversion? As an example, in the format specifier `"%+R"` is technically undefined since the `+` flag only applies to signed conversions. In practice it's not a big deal (we just ignore irrelevant flags) but it could be an area of further development. https://github.com/llvm/llvm-project/pull/82855 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Update -Wformat warnings for fixed-point format specifiers (PR #82855)
PiJoules wrote: > > Do you know a libc implementation that actually implements `%k` `%r` and > > who are the potential users? From a quick glance, gcc avr supports > > fixed-point types but avr-libc doesn't seem to support %k %r. > > LLVM-libc will support them soon, PR should be coming next week. We have > internal customers at Google that are starting to use fixed-point types in > their embedded products. https://github.com/llvm/llvm-project/pull/82707 is the libc PR https://github.com/llvm/llvm-project/pull/82855 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement __builtin_popcountg (PR #82359)
overmighty wrote: Thanks. I plan to fix it soon, so I will probably just open a PR then. https://github.com/llvm/llvm-project/pull/82359 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] implementation of lerp intrinsic (PR #83077)
@@ -24,4 +24,9 @@ def int_dx_dot : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>], [IntrNoMem, IntrWillReturn, Commutative] >; + +def int_dx_lerp : +Intrinsic<[LLVMMatchType<0>], +[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>], python3kgae wrote: Should it be LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>> like dot? https://github.com/llvm/llvm-project/pull/83077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Trim license header comments to 81 characters (PR #82919)
dwblaikie wrote: +1 to @pogo59's comment about pruning complete paths - I suspect they're in the minority. Might be worth checking whether the `===` at the start and end is markup for any particular thing (I /think/ the `-*- C++ -*-` is load bearing for some editors to inform them this `.h` file is C++ not C, so I'm not sure about some other features of those top-of-file comments). https://github.com/llvm/llvm-project/pull/82919 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [TBAA] Handle bitfields when generating !tbaa.struct metadata. (PR #82922)
https://github.com/efriedma-quic commented: Whitespace is weird in a few places; otherwise looks fine. https://github.com/llvm/llvm-project/pull/82922 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-tidy] Unsafe CRTP check (PR #82403)
@@ -0,0 +1,167 @@ +//===--- UnsafeCrtpCheck.cpp - clang-tidy -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "UnsafeCrtpCheck.h" +#include "../utils/LexerUtils.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +using namespace clang::ast_matchers; + +namespace clang::tidy::bugprone { + +namespace { +// Finds a node if it's already a bound node. +AST_MATCHER_P(CXXRecordDecl, isBoundNode, std::string, ID) { + return Builder->removeBindings( + [&](const ast_matchers::internal::BoundNodesMap &Nodes) { +const auto *BoundRecord = Nodes.getNodeAs(ID); +return BoundRecord != &Node; + }); +} + +bool hasPrivateConstructor(const CXXRecordDecl *RD) { + for (auto &&Ctor : RD->ctors()) { +if (Ctor->getAccess() == AS_private) + return true; + } + + return false; +} + +bool isDerivedParameterBefriended(const CXXRecordDecl *CRTP, + const NamedDecl *Param) { + for (auto &&Friend : CRTP->friends()) { +const auto *TTPT = +dyn_cast(Friend->getFriendType()->getType()); + +if (TTPT && TTPT->getDecl() == Param) + return true; + } + + return false; +} + +bool isDerivedClassBefriended(const CXXRecordDecl *CRTP, + const CXXRecordDecl *Derived) { + for (auto &&Friend : CRTP->friends()) { +if (Friend->getFriendType()->getType()->getAsCXXRecordDecl() == Derived) + return true; + } + + return false; +} + +std::optional +getDerivedParameter(const ClassTemplateSpecializationDecl *CRTP, +const CXXRecordDecl *Derived) { + size_t Idx = 0; + bool Found = false; + for (auto &&TemplateArg : CRTP->getTemplateArgs().asArray()) { +if (TemplateArg.getKind() == TemplateArgument::Type && +TemplateArg.getAsType()->getAsCXXRecordDecl() == Derived) { + Found = true; + break; +} +++Idx; + } + + if (!Found) +return std::nullopt; + + return CRTP->getSpecializedTemplate()->getTemplateParameters()->getParam(Idx); +} + +std::vector hintMakeCtorPrivate(const CXXConstructorDecl *Ctor, + const std::string &OriginalAccess, + const SourceManager &SM, + const LangOptions &LangOpts) { + std::vector Hints; + + Hints.emplace_back(FixItHint::CreateInsertion( + Ctor->getBeginLoc().getLocWithOffset(-1), "private:\n")); + + SourceLocation CtorEndLoc = + Ctor->isExplicitlyDefaulted() + ? utils::lexer::findNextTerminator(Ctor->getEndLoc(), SM, LangOpts) + : Ctor->getEndLoc(); + Hints.emplace_back(FixItHint::CreateInsertion( + CtorEndLoc.getLocWithOffset(1), '\n' + OriginalAccess + ':' + '\n')); + + return Hints; +} +} // namespace + +void UnsafeCrtpCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + classTemplateSpecializationDecl( + decl().bind("crtp"), + hasAnyTemplateArgument(refersToType(recordType(hasDeclaration( + cxxRecordDecl(isDerivedFrom(cxxRecordDecl(isBoundNode("crtp" + .bind("derived")), + this); +} + +void UnsafeCrtpCheck::check(const MatchFinder::MatchResult &Result) { + const auto *CRTPInstantiation = + Result.Nodes.getNodeAs("crtp"); + const auto *DerivedRecord = Result.Nodes.getNodeAs("derived"); + const CXXRecordDecl *CRTPDeclaration = + CRTPInstantiation->getSpecializedTemplate()->getTemplatedDecl(); + + if (!CRTPDeclaration->hasUserDeclaredConstructor()) { +bool IsStruct = CRTPDeclaration->isStruct(); + +diag(CRTPDeclaration->getLocation(), + "the implicit default constructor of the CRTP is publicly accessible") +<< CRTPDeclaration +<< FixItHint::CreateInsertion( + CRTPDeclaration->getBraceRange().getBegin().getLocWithOffset(1), + (IsStruct ? "\nprivate:\n" : "\n") + + CRTPDeclaration->getNameAsString() + "() = default;\n" + + (IsStruct ? "public:\n" : "")); isuckatcs wrote: For now I'd leave it as it is and if later we get some feedback, we can change it accordingly. https://github.com/llvm/llvm-project/pull/82403 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement __builtin_popcountg (PR #82359)
efriedma-quic wrote: Oh, I should have caught that when reviewing. (I thought I checked the test was doing the right thing when I looked at it, but I guess I'm misremembering.) Probably need to mark the intrinsic CustomTypeChecking, then make the code in SemaChecking explicitly perform lvalue-to-rvalue conversions, to match gcc. Yes, please open an issue... or if you're planning to look at it, feel free to just post a fix. https://github.com/llvm/llvm-project/pull/82359 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)
@@ -1201,19 +1197,22 @@ void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S, // Extract the ID of the condition we are setting in the bitmap. const auto &Branch = BranchStateIter->second; assert(Branch.ID >= 0 && "Condition has no ID!"); + assert(Branch.DecisionStmt); - auto *I8PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext()); + // Cancel the emission if the Decision is erased after the allocation. + const auto DecisionIter = + RegionMCDCState->DecisionByStmt.find(Branch.DecisionStmt); + if (DecisionIter == RegionMCDCState->DecisionByStmt.end()) +return; - // Emit intrinsic that updates a dedicated temporary value on the stack after - // a condition is evaluated. After the set of conditions has been updated, - // the resulting value is used to update the boolean expression's bitmap. - llvm::Value *Args[5] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy), - Builder.getInt64(FunctionHash), - Builder.getInt32(Branch.ID), - MCDCCondBitmapAddr.getPointer(), Val}; - Builder.CreateCall( - CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_condbitmap_update), - Args); + const auto &TVIdxs = DecisionIter->second.Indices[Branch.ID]; + + auto *CurTV = Builder.CreateLoad(MCDCCondBitmapAddr, + "mcdc." + Twine(Branch.ID + 1) + ".cur"); + auto *NewTV = Builder.CreateAdd(CurTV, Builder.getInt32(TVIdxs[true])); + NewTV = Builder.CreateSelect( + Val, NewTV, Builder.CreateAdd(CurTV, Builder.getInt32(TVIdxs[false]))); + Builder.CreateStore(NewTV, MCDCCondBitmapAddr); chapuni wrote: I don't think it wouldn't make sense to make this as the intrinsic, because this doesn't operate special operations. I'd like to create cleanups later to prune `condbitmap_update` since pruning is not the prerequisite of this change. In contrast, I think `tvbitmap` may be left, because it could emit atomic operations as options. https://github.com/llvm/llvm-project/pull/82448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [MC/DC][Coverage] Loosen the limit of NumConds from 6 (PR #82448)
@@ -1128,9 +1122,11 @@ void CodeGenPGO::emitMCDCParameters(CGBuilderTy &Builder) { // Emit intrinsic representing MCDC bitmap parameters at function entry. // This is used by the instrumentation pass, but it isn't actually lowered to // anything. - llvm::Value *Args[3] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy), - Builder.getInt64(FunctionHash), - Builder.getInt32(RegionMCDCState->BitmapBytes)}; + llvm::Value *Args[3] = { + llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy), + Builder.getInt64(FunctionHash), + Builder.getInt32(llvm::alignTo(RegionMCDCState->BitmapBits, CHAR_BIT) / + CHAR_BIT)}; chapuni wrote: @evodius96 Could we change it with bitcount as well, for the consistency? https://github.com/llvm/llvm-project/pull/82448 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement __builtin_popcountg (PR #82359)
overmighty wrote: Maybe the semantic analysis and docs should have been changed to match GCC's better. GCC's docs say their `__builtin_popcountg` takes a "type-generic unsigned integer" but that "No integral argument promotions are performed on the argument." Our builtin accepts signed integers too, but the argument goes through integer promotion, so the builtin can return an incorrect value if we give it a signed integer. For example, this program will output 32 with Clang on `x86_64-unknown-linux-gnu`: ```c #include int main(void) { char foo = -1; int pop = __builtin_popcountg(foo); printf("%d\n", pop); } ``` GCC refuses to compile it: https://godbolt.org/z/chh4WGT4v. Should I open a new issue? https://github.com/llvm/llvm-project/pull/82359 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [TBAA] Handle bitfields when generating !tbaa.struct metadata. (PR #82922)
@@ -294,18 +297,49 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, return false; const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); +const CGRecordLayout &CGRL = CGTypes.getCGRecordLayout(RD); unsigned idx = 0; -for (RecordDecl::field_iterator i = RD->field_begin(), - e = RD->field_end(); i != e; ++i, ++idx) { - if ((*i)->isZeroSize(Context) || (*i)->isUnnamedBitfield()) +for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e;) { + if ((*i)->isZeroSize(Context)) { +++i; +++idx; continue; - uint64_t Offset = BaseOffset + -Layout.getFieldOffset(idx) / Context.getCharWidth(); + } + + uint64_t Offset = + BaseOffset + Layout.getFieldOffset(idx) / Context.getCharWidth(); QualType FieldQTy = i->getType(); + // Create a single field for consecutive named bitfields using char as + // base type. + if ((*i)->isBitField() && !(*i)->isUnnamedBitfield()) { +unsigned CurrentBitFieldSize = 0; +unsigned CurrentBitFieldOffset = CGRL.getBitFieldInfo(*i).Offset; +while (i != e && (*i)->isBitField() && !(*i)->isUnnamedBitfield()) { + const CGBitFieldInfo &Info = CGRL.getBitFieldInfo(*i); + if (CurrentBitFieldSize + CurrentBitFieldOffset != Info.Offset) +break; + CurrentBitFieldSize += Info.Size; fhahn wrote: Thanks, updated the patch to add a field for the first bitfield in the run using its StorageSize, and skip bitfields where the offset in the run isn't 0 (`Offset`). https://github.com/llvm/llvm-project/pull/82922 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [TBAA] Handle bitfields when generating !tbaa.struct metadata. (PR #82922)
@@ -294,18 +297,49 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, return false; const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); +const CGRecordLayout &CGRL = CGTypes.getCGRecordLayout(RD); unsigned idx = 0; -for (RecordDecl::field_iterator i = RD->field_begin(), - e = RD->field_end(); i != e; ++i, ++idx) { - if ((*i)->isZeroSize(Context) || (*i)->isUnnamedBitfield()) +for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e;) { + if ((*i)->isZeroSize(Context)) { +++i; +++idx; continue; - uint64_t Offset = BaseOffset + -Layout.getFieldOffset(idx) / Context.getCharWidth(); + } + + uint64_t Offset = + BaseOffset + Layout.getFieldOffset(idx) / Context.getCharWidth(); QualType FieldQTy = i->getType(); + // Create a single field for consecutive named bitfields using char as + // base type. + if ((*i)->isBitField() && !(*i)->isUnnamedBitfield()) { +unsigned CurrentBitFieldSize = 0; +unsigned CurrentBitFieldOffset = CGRL.getBitFieldInfo(*i).Offset; +while (i != e && (*i)->isBitField() && !(*i)->isUnnamedBitfield()) { fhahn wrote: Yes, test showing that added in 54cff50791dec977feb0badb74919d97dff5b859, thanks! https://github.com/llvm/llvm-project/pull/82922 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [TBAA] Handle bitfields when generating !tbaa.struct metadata. (PR #82922)
https://github.com/fhahn updated https://github.com/llvm/llvm-project/pull/82922 >From 556fcefed9645aa0a0a965ff8f22d8accdf9eefc Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Sun, 25 Feb 2024 13:23:17 + Subject: [PATCH 1/6] [TBAA] Skip all bitfields when generating !tbaa.struct metadata. At the moment, clang generates what I believe are incorrect !tbaa.struct fields for named bitfields. At the moment, the base type size is used for named bifields (e.g. sizeof(int)) instead of the bifield width per field. This results in overalpping fields in !tbaa.struct metadata. This causes incorrect results when extracting individual copied fields from !tbaa.struct as in added in dc85719d5. This patch fixes that by skipping all bitfields, not only unnamed ones (note that CollectFields has a TODO to support bitfields). As bitfields specify their widths in bits, while !tbaa metadata uses bytes for sizes and offsets, I don't think we would be able to generate correct metadata for them in general. If this understanding is correct, I can also extend the verifier to check that !tbaa.struct fields aren't overlapping. Fixes https://github.com/llvm/llvm-project/issues/82586 --- clang/lib/CodeGen/CodeGenTBAA.cpp | 2 +- clang/test/CodeGen/tbaa-struct.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index dc288bc3f6157a..43a1aee3d73823 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -298,7 +298,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset, unsigned idx = 0; for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); i != e; ++i, ++idx) { - if ((*i)->isZeroSize(Context) || (*i)->isUnnamedBitfield()) + if ((*i)->isZeroSize(Context) || (*i)->isBitField()) continue; uint64_t Offset = BaseOffset + Layout.getFieldOffset(idx) / Context.getCharWidth(); diff --git a/clang/test/CodeGen/tbaa-struct.cpp b/clang/test/CodeGen/tbaa-struct.cpp index ff5521fcf3f604..17c9d6bf6a7260 100644 --- a/clang/test/CodeGen/tbaa-struct.cpp +++ b/clang/test/CodeGen/tbaa-struct.cpp @@ -130,7 +130,7 @@ void copy8(NamedBitfields *a1, NamedBitfields *a2) { // CHECK-OLD: [[TS3]] = !{i64 0, i64 8, !{{.*}}, i64 0, i64 2, !{{.*}}, i64 4, i64 8, !{{.*}}} // CHECK-OLD: [[TS4]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]]} // CHECK-OLD: [[TS5]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 4, i64 1, [[TAG_CHAR]], i64 5, i64 1, [[TAG_CHAR]]} -// CHECK-OLD: [[TS6]] = !{i64 0, i64 4, [[TAG_INT]], i64 1, i64 4, [[TAG_INT]], i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]} +// CHECK-OLD: [[TS6]] = !{i64 2, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE:!.+]]} // CHECK-OLD: [[TAG_DOUBLE]] = !{[[DOUBLE:!.+]], [[DOUBLE]], i64 0} // CHECK-OLD [[DOUBLE]] = !{!"double", [[CHAR]], i64 0} >From 32be3b7d944fc5da50add4b6fea551ba6c9d428c Mon Sep 17 00:00:00 2001 From: Florian Hahn Date: Mon, 26 Feb 2024 10:19:57 + Subject: [PATCH 2/6] WIP use CGBitFieldInfo. --- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/lib/CodeGen/CodeGenTBAA.cpp | 33 +++-- clang/lib/CodeGen/CodeGenTBAA.h | 4 +++- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 95e457bef28ed3..ed8db055723024 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -397,7 +397,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, // Enable TBAA unless it's suppressed. ThreadSanitizer needs TBAA even at O0. if (LangOpts.Sanitize.has(SanitizerKind::Thread) || (!CodeGenOpts.RelaxedAliasing && CodeGenOpts.OptimizationLevel > 0)) -TBAA.reset(new CodeGenTBAA(Context, TheModule, CodeGenOpts, getLangOpts(), +TBAA.reset(new CodeGenTBAA(Context, getTypes(), TheModule, CodeGenOpts, getLangOpts(), getCXXABI().getMangleContext())); // If debug info or coverage generation is enabled, create the CGDebugInfo diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 43a1aee3d73823..6a453bb1144582 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -14,6 +14,8 @@ // //===--===// +#include "CGRecordLayout.h" +#include "CodeGenTypes.h" #include "CodeGenTBAA.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" @@ -29,10 +31,10 @@ using namespace clang; using namespace CodeGen; -CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, llvm::Module &M, +CodeGenTBAA::CodeGenTBAA(ASTContext &Ctx, CodeGenTypes &CGTypes, llvm::Module &M, const CodeGenOptions &CGO, const LangOptions &Features, MangleContext &MContext) - : Contex
[clang] [Clang] Fix __has_cpp_attribute and C++11 attributes with arguments in C++03 (PR #83065)
AMP999 wrote: How about also enabling some existing C++11 tests for C++03 mode, too? E.g. `Preprocessor/has_attribute.cpp`, `SemaCXX/attr-declspec-ignored.cpp`, `SemaCXX/attr-gnu.cpp`, don't run in C++03 mode today but they could be made to. https://github.com/llvm/llvm-project/pull/83065 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 54cff50 - [TBAA] Add !tbaa.struct test with unnamed bitfields.
Author: Florian Hahn Date: 2024-02-26T22:50:50Z New Revision: 54cff50791dec977feb0badb74919d97dff5b859 URL: https://github.com/llvm/llvm-project/commit/54cff50791dec977feb0badb74919d97dff5b859 DIFF: https://github.com/llvm/llvm-project/commit/54cff50791dec977feb0badb74919d97dff5b859.diff LOG: [TBAA] Add !tbaa.struct test with unnamed bitfields. Extra tests with unnamed bitfields for https://github.com/llvm/llvm-project/pull/82922. Added: Modified: clang/test/CodeGen/tbaa-struct.cpp Removed: diff --git a/clang/test/CodeGen/tbaa-struct.cpp b/clang/test/CodeGen/tbaa-struct.cpp index e25fbc1a778103..28c7d396121af4 100644 --- a/clang/test/CodeGen/tbaa-struct.cpp +++ b/clang/test/CodeGen/tbaa-struct.cpp @@ -134,6 +134,23 @@ void copy9(NamedBitfields2 *a1, NamedBitfields2 *a2) { *a1 = *a2; } +// Test with unnamed bitfield at the start and in between named ones.. +struct NamedBitfields3 { + unsigned : 11; + signed f0 : 9; + char : 2; + int f1 : 2; + double f2; +}; + +void copy10(NamedBitfields3 *a1, NamedBitfields3 *a2) { +// CHECK-LABEL: _Z6copy10P15NamedBitfields3S0_ +// CHECK: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 8 dereferenceable(16) %a1, ptr noundef nonnull align 8 dereferenceable(16) %a2, i64 16, i1 false), +// CHECK-OLD-SAME: !tbaa.struct [[TS8:!.*]] +// CHECK-NEW-SAME: !tbaa [[TAG_NamedBitfields3:!.+]], !tbaa.struct + *a1 = *a2; +} + // CHECK-OLD: [[TS]] = !{i64 0, i64 2, !{{.*}}, i64 4, i64 4, !{{.*}}, i64 8, i64 1, !{{.*}}, i64 12, i64 4, !{{.*}}} // CHECK-OLD: [[CHAR:!.*]] = !{!"omnipotent char", !{{.*}}} // CHECK-OLD: [[TAG_INT:!.*]] = !{[[INT:!.*]], [[INT]], i64 0} @@ -149,6 +166,7 @@ void copy9(NamedBitfields2 *a1, NamedBitfields2 *a2) { // CHECK-OLD: [[TAG_DOUBLE]] = !{[[DOUBLE:!.+]], [[DOUBLE]], i64 0} // CHECK-OLD [[DOUBLE]] = !{!"double", [[CHAR]], i64 0} // CHECK-OLD: [[TS7]] = !{i64 0, i64 1, [[TAG_CHAR]], i64 1, i64 1, [[TAG_CHAR]], i64 2, i64 1, [[TAG_CHAR]], i64 3, i64 4, [[TAG_INT]], i64 3, i64 4, [[TAG_INT]], i64 4, i64 1, [[TAG_CHAR]], i64 8, i64 8, [[TAG_DOUBLE]], i64 16, i64 4, [[TAG_INT]]} +// CHECK-OLD: [[TS8]] = !{i64 1, i64 4, [[TAG_INT]], i64 2, i64 4, [[TAG_INT]], i64 8, i64 8, [[TAG_DOUBLE]]} // CHECK-NEW-DAG: [[TYPE_char:!.*]] = !{{{.*}}, i64 1, !"omnipotent char"} // CHECK-NEW-DAG: [[TAG_char]] = !{[[TYPE_char]], [[TYPE_char]], i64 0, i64 0} @@ -168,3 +186,5 @@ void copy9(NamedBitfields2 *a1, NamedBitfields2 *a2) { // CHECK-NEW-DAG: [[TYPE_double]] = !{[[TYPE_char]], i64 8, !"double"} // CHECK-NEW-DAG: [[TAG_NamedBitfields2]] = !{[[TYPE_NamedBitfields2:!.+]], [[TYPE_NamedBitfields2]], i64 0, i64 24} // CHECK-NEW-DAG: [[TYPE_NamedBitfields2]] = !{[[TYPE_char]], i64 24, !"_ZTS15NamedBitfields2", [[TYPE_char]], i64 0, i64 1, [[TYPE_char]], i64 1, i64 1, [[TYPE_char]], i64 2, i64 1, [[TYPE_int]], i64 3, i64 4, [[TYPE_int]], i64 3, i64 4, [[TYPE_char]], i64 4, i64 1, [[TYPE_double]], i64 8, i64 8, [[TYPE_int]], i64 16, i64 4} +// CHECK-NEW-DAG: [[TAG_NamedBitfields3]] = !{[[TYPE_NamedBitfields3:!.+]], [[TYPE_NamedBitfields3]], i64 0, i64 16} +// CHECK-NEW-DAG: [[TYPE_NamedBitfields3]] = !{[[TYPE_char]], i64 16, !"_ZTS15NamedBitfields3", [[TYPE_int]], i64 1, i64 4, [[TYPE_int]], i64 2, i64 4, [[TYPE_double]], i64 8, i64 8} ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fixes inf loop parsing fixed point literal (PR #83071)
https://github.com/PiJoules closed https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3d2a918 - [clang] Fixes inf loop parsing fixed point literal (#83071)
Author: PiJoules Date: 2024-02-26T14:47:16-08:00 New Revision: 3d2a918831e7bcf1285641ee446ac1640819819f URL: https://github.com/llvm/llvm-project/commit/3d2a918831e7bcf1285641ee446ac1640819819f DIFF: https://github.com/llvm/llvm-project/commit/3d2a918831e7bcf1285641ee446ac1640819819f.diff LOG: [clang] Fixes inf loop parsing fixed point literal (#83071) Clang was incorrectly finding the start of the exponent in a fixed point hex literal. It would unconditionally find the first `e/E/p/P` in a constant regardless of if it were hex or not and parser the remaining digits as an APInt. In a debug build, this would be caught by an assertion, but in a release build, the assertion is removed and we'd end up in an infinite loop. Fixes #83050 Added: Modified: clang/lib/Lex/LiteralSupport.cpp clang/test/Frontend/fixed_point_declarations.c Removed: diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 571a984884029d..438c6d772e6e04 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1513,8 +1513,10 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { : APFloat::opInvalidOp; } -static inline bool IsExponentPart(char c) { - return c == 'p' || c == 'P' || c == 'e' || c == 'E'; +static inline bool IsExponentPart(char c, bool isHex) { + if (isHex) +return c == 'p' || c == 'P'; + return c == 'e' || c == 'E'; } bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale) { @@ -1533,7 +1535,8 @@ bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Sc if (saw_exponent) { const char *Ptr = DigitsBegin; -while (!IsExponentPart(*Ptr)) ++Ptr; +while (!IsExponentPart(*Ptr, radix == 16)) + ++Ptr; ExponentBegin = Ptr; ++Ptr; NegativeExponent = *Ptr == '-'; diff --git a/clang/test/Frontend/fixed_point_declarations.c b/clang/test/Frontend/fixed_point_declarations.c index 04ed25d227ca52..c8045767442739 100644 --- a/clang/test/Frontend/fixed_point_declarations.c +++ b/clang/test/Frontend/fixed_point_declarations.c @@ -125,3 +125,21 @@ long _Fract long_fract_zero = 0.0lr;// CHECK-DAG: @long_fract_ unsigned short _Fract u_short_fract_zero = 0.0uhr; // CHECK-DAG: @u_short_fract_zero = {{.*}}global i8 0, align 1 unsigned _Fract u_fract_zero= 0.0ur;// CHECK-DAG: @u_fract_zero = {{.*}}global i16 0, align 2 unsigned long _Fract u_long_fract_zero = 0.0ulr; // CHECK-DAG: @u_long_fract_zero= {{.*}}global i32 0, align 4 + +// Hex exponent suffix with E in hex digit sequence. +unsigned short _Fract e1 = 0x1.e8p-1uhr; // CHECK-DAG: @e1 = {{.*}}global i8 -12 +unsigned short _Fract e2 = 0x1.8ep-1uhr; // CHECK-DAG: @e2 = {{.*}}global i8 -57 +unsigned short _Fract e3 = 0x1.ep-1uhr; // CHECK-DAG: @e3 = {{.*}}global i8 -16 +unsigned _Accum e4 = 0xep-1uk; // CHECK-DAG: @e4 = {{.*}}global i32 458752 +unsigned _Accum e5 = 0xe.1p-1uk; // CHECK-DAG: @e5 = {{.*}}global i32 460800 +unsigned _Accum e6 = 0xe.ep-1uk; // CHECK-DAG: @e6 = {{.*}}global i32 487424 +unsigned _Accum e7 = 0xe.e8p-1uk; // CHECK-DAG: @e7 = {{.*}}global i32 488448 +unsigned _Accum e8 = 0xe.8ep-1uk; // CHECK-DAG: @e8 = {{.*}}global i32 476928 +unsigned short _Fract E1 = 0x1.E8p-1uhr; // CHECK-DAG: @E1 = {{.*}}global i8 -12 +unsigned short _Fract E2 = 0x1.8Ep-1uhr; // CHECK-DAG: @E2 = {{.*}}global i8 -57 +unsigned short _Fract E3 = 0x1.Ep-1uhr; // CHECK-DAG: @E3 = {{.*}}global i8 -16 +unsigned _Accum E4 = 0xEp-1uk; // CHECK-DAG: @E4 = {{.*}}global i32 458752 +unsigned _Accum E5 = 0xE.1p-1uk; // CHECK-DAG: @E5 = {{.*}}global i32 460800 +unsigned _Accum E6 = 0xE.Ep-1uk; // CHECK-DAG: @E6 = {{.*}}global i32 487424 +unsigned _Accum E7 = 0xE.E8p-1uk; // CHECK-DAG: @E7 = {{.*}}global i32 488448 +unsigned _Accum E8 = 0xE.8Ep-1uk; // CHECK-DAG: @E8 = {{.*}}global i32 476928 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [compiler-rt] [llvm] [InstrProf] Single byte counters in coverage (PR #75425)
https://github.com/gulfemsavrun closed https://github.com/llvm/llvm-project/pull/75425 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] implementation of lerp intrinsic (PR #83077)
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/83077 This is the start of implementing the lerp intrinsic https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-lerp Builtins.td - defines the builtin hlsl_intrinsics.h - defines the lerp api DiagnosticSemaKinds.td - needed a new error to be inclusive for more than two operands. CGBuiltin.cpp - add the lerp intrinsic lowering SemaChecking.cpp - type checks for lerp builtin IntrinsicsDirectX.td - define the lerp intrinsic this change implements the first half of #70102 >From c6f533e226efbf38bfb1dc9df382342ec813cc37 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Sun, 25 Feb 2024 20:08:09 -0500 Subject: [PATCH] [HLSL] Implementation lerp intrinsic This is the start of implementing the lerp intrinsic https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-lerp Builtins.td - defines the builtin hlsl_intrinsics.h - defines the lerp api DiagnosticSemaKinds.td - needed a new error to be inclusive for more than two operands. CGBuiltin.cpp - add the lerp intrinsic lowering SemaChecking.cpp - type checks for lerp builtin IntrinsicsDirectX.td - define the lerp intrinsic this change implements the first half of #70102 --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 5 + clang/lib/CodeGen/CGBuiltin.cpp | 37 ++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 36 ++ clang/lib/Sema/SemaChecking.cpp | 79 - .../CodeGenHLSL/builtins/lerp-builtin.hlsl| 37 ++ clang/test/CodeGenHLSL/builtins/lerp.hlsl | 105 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 28 ++--- clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl | 91 +++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 388 insertions(+), 41 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl create mode 100644 clang/test/CodeGenHLSL/builtins/lerp.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index e3432f7925ba14..755ef3631b2856 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4530,6 +4530,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLLerp : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_lerp"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 57784a4ba2e388..f1a5d30858f829 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10266,6 +10266,11 @@ def err_block_on_vm : Error< def err_sizeless_nonlocal : Error< "non-local variable with sizeless type %0">; +def err_vec_builtin_non_vector_all : Error< + "all arguments to %0 must be vectors">; +def err_vec_builtin_incompatible_vector_all : Error< + "all arguments to %0 must have vectors of the same type">; + def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 54d7451a9d6221..17b7af924e5ff0 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18006,6 +18006,43 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType*/ T0->getScalarType(), Intrinsic::dx_dot, ArrayRef{Op0, Op1}, nullptr, "dx.dot"); } break; + case Builtin::BI__builtin_hlsl_lerp: { +Value *X = EmitScalarExpr(E->getArg(0)); +Value *Y = EmitScalarExpr(E->getArg(1)); +Value *S = EmitScalarExpr(E->getArg(2)); +llvm::Type *Xty = X->getType(); +llvm::Type *Yty = Y->getType(); +llvm::Type *Sty = S->getType(); +if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { + if (Xty->isFloatingPointTy()) { +auto V = Builder.CreateFSub(Y, X); +V = Builder.CreateFMul(S, V); +return Builder.CreateFAdd(X, V, "dx.lerp"); + } + llvm_unreachable("Scalar Lerp is only supported on floats."); +} +// A VectorSplat should have happened +assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && + "Lerp of vector and scalar is not supported."); + +[[maybe_unused]] auto *XVecTy = +E->getArg(0)->getType()->getAs(); +[[maybe_unused]] auto *YVecTy = +E->getArg(1)->getType()->getAs(); +[[maybe_unused]] auto *SVecTy = +E->getArg(2)->getType()->getAs(); +// A HLSLVectorTruncation should have happend +
[clang] [clang] Fixes inf loop parsing fixed point literal (PR #83071)
https://github.com/nickdesaulniers approved this pull request. https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fixes inf loop parsing fixed point literal (PR #83071)
https://github.com/PiJoules edited https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Fixes inf loop parsing fixed point literal (PR #83071)
https://github.com/PiJoules edited https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
https://github.com/PiJoules updated https://github.com/llvm/llvm-project/pull/83071 >From 306394b5e0386701f577ec2aa9a021492fbae734 Mon Sep 17 00:00:00 2001 From: Leonard Chan Date: Mon, 26 Feb 2024 14:11:45 -0800 Subject: [PATCH] [clang] Fixes inf loop parsing fixed point literal Clang was incorrectly finding the start of the exponent in a fixed point hex literal. It would unconditionally find the first `e/E/p/P` in a constant regardless of if it were hex or not and parser the remaining digits as an APInt. In a debug build, this would be caught by an assertion, but in a release build, the assertion is removed and we'd end up in an infinite loop. Fixes #83050 --- clang/lib/Lex/LiteralSupport.cpp | 9 ++--- clang/test/Frontend/fixed_point_declarations.c | 18 ++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 571a984884029d..438c6d772e6e04 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -1513,8 +1513,10 @@ NumericLiteralParser::GetFloatValue(llvm::APFloat &Result) { : APFloat::opInvalidOp; } -static inline bool IsExponentPart(char c) { - return c == 'p' || c == 'P' || c == 'e' || c == 'E'; +static inline bool IsExponentPart(char c, bool isHex) { + if (isHex) +return c == 'p' || c == 'P'; + return c == 'e' || c == 'E'; } bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale) { @@ -1533,7 +1535,8 @@ bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Sc if (saw_exponent) { const char *Ptr = DigitsBegin; -while (!IsExponentPart(*Ptr)) ++Ptr; +while (!IsExponentPart(*Ptr, radix == 16)) + ++Ptr; ExponentBegin = Ptr; ++Ptr; NegativeExponent = *Ptr == '-'; diff --git a/clang/test/Frontend/fixed_point_declarations.c b/clang/test/Frontend/fixed_point_declarations.c index 04ed25d227ca52..c8045767442739 100644 --- a/clang/test/Frontend/fixed_point_declarations.c +++ b/clang/test/Frontend/fixed_point_declarations.c @@ -125,3 +125,21 @@ long _Fract long_fract_zero = 0.0lr;// CHECK-DAG: @long_fract_ unsigned short _Fract u_short_fract_zero = 0.0uhr; // CHECK-DAG: @u_short_fract_zero = {{.*}}global i8 0, align 1 unsigned _Fract u_fract_zero= 0.0ur;// CHECK-DAG: @u_fract_zero = {{.*}}global i16 0, align 2 unsigned long _Fract u_long_fract_zero = 0.0ulr; // CHECK-DAG: @u_long_fract_zero= {{.*}}global i32 0, align 4 + +// Hex exponent suffix with E in hex digit sequence. +unsigned short _Fract e1 = 0x1.e8p-1uhr; // CHECK-DAG: @e1 = {{.*}}global i8 -12 +unsigned short _Fract e2 = 0x1.8ep-1uhr; // CHECK-DAG: @e2 = {{.*}}global i8 -57 +unsigned short _Fract e3 = 0x1.ep-1uhr; // CHECK-DAG: @e3 = {{.*}}global i8 -16 +unsigned _Accum e4 = 0xep-1uk; // CHECK-DAG: @e4 = {{.*}}global i32 458752 +unsigned _Accum e5 = 0xe.1p-1uk; // CHECK-DAG: @e5 = {{.*}}global i32 460800 +unsigned _Accum e6 = 0xe.ep-1uk; // CHECK-DAG: @e6 = {{.*}}global i32 487424 +unsigned _Accum e7 = 0xe.e8p-1uk; // CHECK-DAG: @e7 = {{.*}}global i32 488448 +unsigned _Accum e8 = 0xe.8ep-1uk; // CHECK-DAG: @e8 = {{.*}}global i32 476928 +unsigned short _Fract E1 = 0x1.E8p-1uhr; // CHECK-DAG: @E1 = {{.*}}global i8 -12 +unsigned short _Fract E2 = 0x1.8Ep-1uhr; // CHECK-DAG: @E2 = {{.*}}global i8 -57 +unsigned short _Fract E3 = 0x1.Ep-1uhr; // CHECK-DAG: @E3 = {{.*}}global i8 -16 +unsigned _Accum E4 = 0xEp-1uk; // CHECK-DAG: @E4 = {{.*}}global i32 458752 +unsigned _Accum E5 = 0xE.1p-1uk; // CHECK-DAG: @E5 = {{.*}}global i32 460800 +unsigned _Accum E6 = 0xE.Ep-1uk; // CHECK-DAG: @E6 = {{.*}}global i32 487424 +unsigned _Accum E7 = 0xE.E8p-1uk; // CHECK-DAG: @E7 = {{.*}}global i32 488448 +unsigned _Accum E8 = 0xE.8Ep-1uk; // CHECK-DAG: @E8 = {{.*}}global i32 476928 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
@@ -0,0 +1,11 @@ +/// This is the regression test for https://github.com/llvm/llvm-project/issues/83050. +/// This just needs to compile. +// RUN: %clang_cc1 -x c++ -ffixed-point -S %s -o /dev/null -triple=x86_64-linux -ffixed-point +static constexpr unsigned short _Fract SQRT_FIRST_APPROX[12][2] = { +{0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr}, +{0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr}, +{0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr}, +{0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr}, +{0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr}, +{0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr}, PiJoules wrote: Oh, no they both aren't so I'll just remove this one. https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
@@ -0,0 +1,11 @@ +/// This is the regression test for https://github.com/llvm/llvm-project/issues/83050. +/// This just needs to compile. +// RUN: %clang_cc1 -x c++ -ffixed-point -S %s -o /dev/null -triple=x86_64-linux -ffixed-point +static constexpr unsigned short _Fract SQRT_FIRST_APPROX[12][2] = { +{0x1.e8p-1uhr, 0x1.0cp-2uhr}, {0x1.bap-1uhr, 0x1.28p-2uhr}, +{0x1.94p-1uhr, 0x1.44p-2uhr}, {0x1.74p-1uhr, 0x1.6p-2uhr}, +{0x1.6p-1uhr, 0x1.74p-2uhr}, {0x1.4ep-1uhr, 0x1.88p-2uhr}, +{0x1.3ep-1uhr, 0x1.9cp-2uhr}, {0x1.32p-1uhr, 0x1.acp-2uhr}, +{0x1.22p-1uhr, 0x1.c4p-2uhr}, {0x1.18p-1uhr, 0x1.d4p-2uhr}, +{0x1.08p-1uhr, 0x1.fp-2uhr}, {0x1.04p-1uhr, 0x1.f8p-2uhr}, nickdesaulniers wrote: I think what you added to clang/test/Frontend/fixed_point_declarations.c covers the same thing as the newly added test file? Are both necessary? https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][HTO] Add clang attribute for propagating llvm-level information (PR #83059)
https://github.com/wsmoses updated https://github.com/llvm/llvm-project/pull/83059 >From c01b559836ca62648c5f95a6441888514347a1ea Mon Sep 17 00:00:00 2001 From: "William S. Moses" Date: Mon, 26 Feb 2024 16:17:55 -0500 Subject: [PATCH 1/2] [Clang][HTO] Add clang attribute for propagating llvm-level information --- clang/include/clang/Basic/Attr.td | 7 +++ clang/include/clang/Basic/AttrDocs.td | 13 + clang/lib/CodeGen/CGCall.cpp | 16 clang/lib/CodeGen/CodeGenFunction.cpp | 19 +++ clang/test/CodeGen/attr-llvmfn.c | 14 ++ 5 files changed, 69 insertions(+) create mode 100644 clang/test/CodeGen/attr-llvmfn.c diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index fa191c7378dba4..044f4fada3590f 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2211,6 +2211,13 @@ def AllocAlign : InheritableAttr { let Documentation = [AllocAlignDocs]; } +def LLVMFuncAttr : InheritableAttr { + let Spellings = [Clang<"llvm_fn_attr">]; + let Args = [StringArgument<"LLVMAttrName">, StringArgument<"LLVMAttrValue">]; + let Documentation = [LLVMFuncAttrDocs]; + let InheritEvenIfAlreadyPresent = 1; +} + def NoReturn : InheritableAttr { let Spellings = [GCC<"noreturn">, Declspec<"noreturn">]; // FIXME: Does GCC allow this on the function instead? diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index b96fbddd51154c..3f93bb6d6fc648 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -781,6 +781,19 @@ pointer is not sufficiently aligned. }]; } +def LLVMFuncAttrDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Use ``__attribute__((llvm_fn_attr(attr_name, attr_value)))`` on a function to specify an LLVM function attribute that will be added to this function. + +Note that uses of this attribute are highly compiler specific as the meaning and availability of LLVM attributes may change between compiler versions. + +This attribute is only intended for advanced users who need to specify specific information only available in LLVM attributes. Use of attributes which are not tied to a specific version of Clang (e.g. pure) should be preferred when available. + +The first arugment is a string representing the name of the LLVM attribute to be applied and the second arugment is a string representing its value. + }]; +} + def EnableIfDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index d05cf1c6e1814e..4725dce607eee9 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -2465,6 +2465,22 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, if (TargetDecl->hasAttr()) FuncAttrs.addAttribute("aarch64_pstate_sm_body"); + +for (auto Attr : TargetDecl->specific_attrs()) { + auto name = Attr->getLLVMAttrName(); + auto value = Attr->getLLVMAttrValue(); + + Attribute Attr; + auto EnumAttr = llvm::Attribute::getAttrKindFromName(name); + if (EnumAttr == llvm::Attribute::None) +Attr = llvm::Attribute::get(getLLVMContext(), name, value); + else { +assert(value.size() == 0 && + "enum attribute does not support value yet"); +Attr = llvm::Attribute::get(getLLVMContext(), EnumAttr); + } + FuncAttrs.addAttribute(Attr); +} } // Attach "no-builtins" attributes to: diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 1ad905078d349c..5d0edd4bbf83c7 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -831,6 +831,25 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass) SanOpts.Mask &= ~SanitizerKind::Null; + if (D) { +for (auto Attr : + template TargetDecl->specific_attrs()) { + auto name = Attr->getLLVMAttrName(); + auto value = Attr->getLLVMAttrValue(); + + Attribute Attr; + auto EnumAttr = llvm::Attribute::getAttrKindFromName(name); + if (EnumAttr == llvm::Attribute::None) +Attr = llvm::Attribute::get(getLLVMContext(), name, value); + else { +assert(value.size() == 0 && + "enum attribute does not support value yet"); +Attr = llvm::Attribute::get(getLLVMContext(), EnumAttr); + } + Fn->addFnAttr(Attr); +} + } + // Apply xray attributes to the function (as a string, for now) bool AlwaysXRayAttr = false; if (const auto *XRayAttr = D ? D->getAttr() : nullptr) { diff --git a/clang/test/CodeGen/attr-llvmfn.c b/clang/test/CodeGen/attr-llvmfn.c new file mode 100644 index 00..72f14a726f795e --- /dev/null +++ b/clang/test/CodeGen/attr
[clang] [clang] Add fix for GH issue 83050 (PR #83071)
nickdesaulniers wrote: For the commit message and PR description, please consider: 1. using a subject that describes more of what the patch does, such as "[clang] fixes inf loop parsing fixed point literal" 2. put "Fixes #83050" in the commit body; when merged, github will auto close the corresponding issue. https://github.com/llvm/llvm-project/pull/83071 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Implement __builtin_popcountg (PR #82359)
nickdesaulniers wrote: > @nickdesaulniers I am interested in implementing more builtins like this one. > :) Cool, I've filed: 1. https://github.com/llvm/llvm-project/issues/83075 2. https://github.com/llvm/llvm-project/issues/83076 Those would be helpful to have next, and I suspect as straight foward to implement as popcountg was. https://github.com/llvm/llvm-project/pull/82359 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits