Skip to content

Commit ebbcd09

Browse files
committed
Merge from 'main' to 'sycl-web' (69 commits)
CONFLICT (content): Merge conflict in clang/tools/clang-linker-wrapper/LinkerWrapperOpts.td
2 parents 2be03ab + b16f765 commit ebbcd09

File tree

317 files changed

+10076
-8759
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

317 files changed

+10076
-8759
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,10 @@ Attribute Changes in Clang
334334
[[clang::code_align(A)]] for(;;) { }
335335
}
336336

337+
- Clang now introduced ``[[clang::coro_lifetimebound]]`` attribute.
338+
All parameters of a function are considered to be lifetime bound if the function
339+
returns a type annotated with ``[[clang::coro_lifetimebound]]`` and ``[[clang::coro_return_type]]``.
340+
337341
Improvements to Clang's diagnostics
338342
-----------------------------------
339343
- Clang constexpr evaluator now prints template arguments when displaying

clang/include/clang/Basic/Attr.td

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,14 @@ def CoroWrapper : InheritableAttr {
11511151
let SimpleHandler = 1;
11521152
}
11531153

1154+
def CoroLifetimeBound : InheritableAttr {
1155+
let Spellings = [Clang<"coro_lifetimebound">];
1156+
let Subjects = SubjectList<[CXXRecord]>;
1157+
let LangOpts = [CPlusPlus];
1158+
let Documentation = [CoroLifetimeBoundDoc];
1159+
let SimpleHandler = 1;
1160+
}
1161+
11541162
// OSObject-based attributes.
11551163
def OSConsumed : InheritableParamAttr {
11561164
let Spellings = [Clang<"os_consumed">];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9187,7 +9187,6 @@ generation of the other destruction cases, optimizing the above `foo.destroy` to
91879187
}];
91889188
}
91899189

9190-
91919190
def CoroReturnTypeAndWrapperDoc : Documentation {
91929191
let Category = DocCatDecl;
91939192
let Content = [{
@@ -9285,3 +9284,60 @@ alignment boundary. Its value must be a power of 2, between 1 and 4096
92859284

92869285
}];
92879286
}
9287+
9288+
def CoroLifetimeBoundDoc : Documentation {
9289+
let Category = DocCatDecl;
9290+
let Content = [{
9291+
The ``[[clang::coro_lifetimebound]]`` is a class attribute which can be applied
9292+
to a `coroutine return type (CRT) <https://clang.llvm.org/docs/AttributeReference.html#coro-return-type>` _ (i.e.
9293+
it should also be annotated with ``[[clang::coro_return_type]]``).
9294+
9295+
All parameters of a function are considered to be lifetime bound. See documentation
9296+
of ``[[clang::lifetimebound]]`` for more `details <https://clang.llvm.org/docs/AttributeReference.html#lifetimebound> _`.
9297+
if the function returns a coroutine return type (CRT) annotated with ``[[clang::coro_lifetimebound]]``.
9298+
9299+
Reference parameters of a coroutine are susceptible to capturing references to temporaries or local variables.
9300+
9301+
For example,
9302+
9303+
.. code-block:: c++
9304+
9305+
task<int> coro(const int& a) { co_return a + 1; }
9306+
task<int> dangling_refs(int a) {
9307+
// `coro` captures reference to a temporary. `foo` would now contain a dangling reference to `a`.
9308+
auto foo = coro(1);
9309+
// `coro` captures reference to local variable `a` which is destroyed after the return.
9310+
return coro(a);
9311+
}
9312+
9313+
`Lifetime bound <https://clang.llvm.org/docs/AttributeReference.html#lifetimebound> _` static analysis
9314+
can be used to detect such instances when coroutines capture references which may die earlier than the
9315+
coroutine frame itself. In the above example, if the CRT `task` is annotated with
9316+
``[[clang::coro_lifetimebound]]``, then lifetime bound analysis would detect capturing reference to
9317+
temporaries or return address of a local variable.
9318+
9319+
Both coroutines and coroutine wrappers are part of this analysis.
9320+
9321+
.. code-block:: c++
9322+
9323+
template <typename T> struct [[clang::coro_return_type, clang::coro_lifetimebound]] Task {
9324+
using promise_type = some_promise_type;
9325+
};
9326+
9327+
Task<int> coro(const int& a) { co_return a + 1; }
9328+
Task<int> [[clang::coro_wrapper]] coro_wrapper(const int& a, const int& b) {
9329+
return a > b ? coro(a) : coro(b);
9330+
}
9331+
Task<int> temporary_reference() {
9332+
auto foo = coro(1); // warning: capturing reference to a temporary which would die after the expression.
9333+
9334+
int a = 1;
9335+
auto bar = coro_wrapper(a, 0); // warning: `b` captures reference to a temporary.
9336+
9337+
co_return co_await coro(1); // fine.
9338+
}
9339+
[[clang::coro_wrapper]] Task<int> stack_reference(int a) {
9340+
return coro(a); // warning: returning address of stack variable `a`.
9341+
}
9342+
}];
9343+
}

clang/include/clang/Basic/arm_sve.td

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ let TargetGuard = "sve2p1" in {
310310
def SVLD1Q_GATHER_U64BASE_OFFSET : MInst<"svld1q_gather[_{2}base]_offset_{d}", "dPgl", "cUcsUsiUilUlfhdb", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1q_gather_scalar_offset">;
311311
def SVLD1Q_GATHER_U64BASE : MInst<"svld1q_gather[_{2}base]_{d}", "dPg", "cUcsUsiUilUlfhdb", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1q_gather_scalar_offset">;
312312

313+
// Load one vector (scalar base + vector offset)
314+
def SVLD1Q_GATHER_U64OFFSET : MInst<"svld1q_gather_[{3}]offset[_{d}]", "dPcg", "cUcsUsiUilUlfhdb", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1q_gather_vector_offset">;
315+
313316
// Load N-element structure into N vectors (scalar base)
314317
defm SVLD2Q : StructLoad<"svld2q[_{2}]", "2Pc", "aarch64_sve_ld2q_sret">;
315318
defm SVLD3Q : StructLoad<"svld3q[_{2}]", "3Pc", "aarch64_sve_ld3q_sret">;
@@ -461,6 +464,9 @@ let TargetGuard = "sve2p1" in {
461464
def SVST1Q_SCATTER_U64BASE_OFFSET : MInst<"svst1q_scatter[_{2}base]_offset[_{d}]", "vPgld", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_scalar_offset">;
462465
def SVST1Q_SCATTER_U64BASE : MInst<"svst1q_scatter[_{2}base][_{d}]", "vPgd", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_scalar_offset">;
463466

467+
// Store one vector (scalar base + vector offset)
468+
def SVST1Q_SCATTER_U64OFFSET : MInst<"svst1q_scatter_[{3}]offset[_{d}]", "vPpgd", "cUcsUsiUilUlfhdb", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1q_scatter_vector_offset">;
469+
464470
// Store N vectors into N-element structure (scalar base)
465471
defm SVST2Q : StructStore<"svst2q[_{d}]", "vPc2", "aarch64_sve_st2q">;
466472
defm SVST3Q : StructStore<"svst3q[_{d}]", "vPc3", "aarch64_sve_st3q">;
@@ -2039,7 +2045,23 @@ def SVCNTP_COUNT : SInst<"svcntp_{d}", "n}i", "QcQsQiQl", MergeNone, "aarch64_sv
20392045
defm SVREVD : SInstZPZ<"svrevd", "csilUcUsUiUl", "aarch64_sve_revd">;
20402046
}
20412047

2042-
////////////////////////////////////////////////////////////////////////////////
2048+
2049+
let TargetGuard = "sve2p1,b16b16" in {
2050+
defm SVMUL_BF : SInstZPZZ<"svmul", "b", "aarch64_sve_fmul", "aarch64_sve_fmul_u">;
2051+
defm SVADD_BF : SInstZPZZ<"svadd", "b", "aarch64_sve_fadd", "aarch64_sve_fadd_u">;
2052+
defm SVSUB_BF : SInstZPZZ<"svsub", "b", "aarch64_sve_fsub", "aarch64_sve_fsub_u">;
2053+
defm SVMAXNM_BF : SInstZPZZ<"svmaxnm","b", "aarch64_sve_fmaxnm", "aarch64_sve_fmaxnm_u">;
2054+
defm SVMINNM_BF : SInstZPZZ<"svminnm","b", "aarch64_sve_fminnm", "aarch64_sve_fminnm_u">;
2055+
defm SVMAX_BF : SInstZPZZ<"svmax", "b", "aarch64_sve_fmax", "aarch64_sve_fmax_u">;
2056+
defm SVMIN_BF : SInstZPZZ<"svmin", "b", "aarch64_sve_fmin", "aarch64_sve_fmin_u">;
2057+
defm SVMLA_BF : SInstZPZZZ<"svmla", "b", "aarch64_sve_fmla", "aarch64_sve_fmla_u", []>;
2058+
defm SVMLS_BF : SInstZPZZZ<"svmls", "b", "aarch64_sve_fmls", "aarch64_sve_fmls_u", []>;
2059+
def SVMLA_LANE_BF : SInst<"svmla_lane[_{d}]", "ddddi", "b", MergeNone, "aarch64_sve_fmla_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
2060+
def SVMLS_LANE_BF : SInst<"svmls_lane[_{d}]", "ddddi", "b", MergeNone, "aarch64_sve_fmls_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>;
2061+
def SVMUL_LANE_BF : SInst<"svmul_lane[_{d}]", "dddi", "b", MergeNone, "aarch64_sve_fmul_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>;
2062+
def SVFCLAMP_BF : SInst<"svclamp[_{d}]", "dddd", "b", MergeNone, "aarch64_sve_fclamp", [], []>;
2063+
} //sve2p1,b16b16
2064+
20432065
// SME2
20442066

20452067
// SME intrinsics which operate only on vectors and do not require ZA should be added here,

clang/include/clang/Sema/Sema.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13902,10 +13902,6 @@ class Sema final {
1390213902
void maybeAddCUDAHostDeviceAttrs(FunctionDecl *FD,
1390313903
const LookupResult &Previous);
1390413904

13905-
/// May add implicit CUDAHostAttr and CUDADeviceAttr attributes to a
13906-
/// trivial cotr/dtor that does not have host and device attributes.
13907-
void maybeAddCUDAHostDeviceAttrsToTrivialCtorDtor(FunctionDecl *FD);
13908-
1390913905
/// May add implicit CUDAConstantAttr attribute to VD, depending on VD
1391013906
/// and current compilation settings.
1391113907
void MaybeAddCUDAConstantAttr(VarDecl *VD);

clang/lib/AST/ASTContext.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,14 +1685,16 @@ CharUnits ASTContext::getDeclAlign(const Decl *D, bool ForAlignof) const {
16851685
Align = std::max(Align, getPreferredTypeAlign(T.getTypePtr()));
16861686
if (BaseT.getQualifiers().hasUnaligned())
16871687
Align = Target->getCharWidth();
1688-
if (const auto *VD = dyn_cast<VarDecl>(D)) {
1689-
if (VD->hasGlobalStorage() && !ForAlignof) {
1690-
uint64_t TypeSize = getTypeSize(T.getTypePtr());
1691-
Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize));
1692-
}
1693-
}
16941688
}
16951689

1690+
// Ensure miminum alignment for global variables.
1691+
if (const auto *VD = dyn_cast<VarDecl>(D))
1692+
if (VD->hasGlobalStorage() && !ForAlignof) {
1693+
uint64_t TypeSize =
1694+
!BaseT->isIncompleteType() ? getTypeSize(T.getTypePtr()) : 0;
1695+
Align = std::max(Align, getTargetInfo().getMinGlobalAlign(TypeSize));
1696+
}
1697+
16961698
// Fields can be subject to extra alignment constraints, like if
16971699
// the field is packed, the struct is packed, or the struct has a
16981700
// a max-field-alignment constraint (#pragma pack). So calculate

clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ static constexpr int MaxCompositeValueDepth = 3;
3636
static constexpr int MaxCompositeValueSize = 1000;
3737

3838
/// Returns a map consisting of key-value entries that are present in both maps.
39-
template <typename K, typename V>
40-
llvm::DenseMap<K, V> intersectDenseMaps(const llvm::DenseMap<K, V> &Map1,
41-
const llvm::DenseMap<K, V> &Map2) {
42-
llvm::DenseMap<K, V> Result;
43-
for (auto &Entry : Map1) {
44-
auto It = Map2.find(Entry.first);
45-
if (It != Map2.end() && Entry.second == It->second)
39+
static llvm::DenseMap<const ValueDecl *, StorageLocation *> intersectDeclToLoc(
40+
const llvm::DenseMap<const ValueDecl *, StorageLocation *> &DeclToLoc1,
41+
const llvm::DenseMap<const ValueDecl *, StorageLocation *> &DeclToLoc2) {
42+
llvm::DenseMap<const ValueDecl *, StorageLocation *> Result;
43+
for (auto &Entry : DeclToLoc1) {
44+
auto It = DeclToLoc2.find(Entry.first);
45+
if (It != DeclToLoc2.end() && Entry.second == It->second)
4646
Result.insert({Entry.first, Entry.second});
4747
}
4848
return Result;
@@ -203,39 +203,37 @@ bool compareKeyToValueMaps(const llvm::MapVector<Key, Value *> &Map1,
203203
return true;
204204
}
205205

206-
// Perform a join on either `LocToVal` or `ExprToVal`. `Key` must be either
207-
// `const StorageLocation *` or `const Expr *`.
208-
template <typename Key>
209-
llvm::MapVector<Key, Value *>
210-
joinKeyToValueMap(const llvm::MapVector<Key, Value *> &Map1,
211-
const llvm::MapVector<Key, Value *> &Map2,
212-
const Environment &Env1, const Environment &Env2,
213-
Environment &JoinedEnv, Environment::ValueModel &Model) {
214-
llvm::MapVector<Key, Value *> MergedMap;
215-
for (auto &Entry : Map1) {
216-
Key K = Entry.first;
217-
assert(K != nullptr);
206+
// Perform a join on two `LocToVal` maps.
207+
static llvm::MapVector<const StorageLocation *, Value *>
208+
joinLocToVal(const llvm::MapVector<const StorageLocation *, Value *> &LocToVal,
209+
const llvm::MapVector<const StorageLocation *, Value *> &LocToVal2,
210+
const Environment &Env1, const Environment &Env2,
211+
Environment &JoinedEnv, Environment::ValueModel &Model) {
212+
llvm::MapVector<const StorageLocation *, Value *> Result;
213+
for (auto &Entry : LocToVal) {
214+
const StorageLocation *Loc = Entry.first;
215+
assert(Loc != nullptr);
218216

219217
Value *Val = Entry.second;
220218
assert(Val != nullptr);
221219

222-
auto It = Map2.find(K);
223-
if (It == Map2.end())
220+
auto It = LocToVal2.find(Loc);
221+
if (It == LocToVal2.end())
224222
continue;
225223
assert(It->second != nullptr);
226224

227225
if (areEquivalentValues(*Val, *It->second)) {
228-
MergedMap.insert({K, Val});
226+
Result.insert({Loc, Val});
229227
continue;
230228
}
231229

232230
if (Value *MergedVal = mergeDistinctValues(
233-
K->getType(), *Val, Env1, *It->second, Env2, JoinedEnv, Model)) {
234-
MergedMap.insert({K, MergedVal});
231+
Loc->getType(), *Val, Env1, *It->second, Env2, JoinedEnv, Model)) {
232+
Result.insert({Loc, MergedVal});
235233
}
236234
}
237235

238-
return MergedMap;
236+
return Result;
239237
}
240238

241239
// Perform widening on either `LocToVal` or `ExprToVal`. `Key` must be either
@@ -648,20 +646,19 @@ Environment Environment::join(const Environment &EnvA, const Environment &EnvB,
648646
else
649647
JoinedEnv.ReturnLoc = nullptr;
650648

651-
JoinedEnv.DeclToLoc = intersectDenseMaps(EnvA.DeclToLoc, EnvB.DeclToLoc);
652-
653-
JoinedEnv.ExprToLoc = intersectDenseMaps(EnvA.ExprToLoc, EnvB.ExprToLoc);
649+
JoinedEnv.DeclToLoc = intersectDeclToLoc(EnvA.DeclToLoc, EnvB.DeclToLoc);
654650

655651
// FIXME: update join to detect backedges and simplify the flow condition
656652
// accordingly.
657653
JoinedEnv.FlowConditionToken = EnvA.DACtx->joinFlowConditions(
658654
EnvA.FlowConditionToken, EnvB.FlowConditionToken);
659655

660-
JoinedEnv.ExprToVal = joinKeyToValueMap(EnvA.ExprToVal, EnvB.ExprToVal, EnvA,
661-
EnvB, JoinedEnv, Model);
656+
JoinedEnv.LocToVal =
657+
joinLocToVal(EnvA.LocToVal, EnvB.LocToVal, EnvA, EnvB, JoinedEnv, Model);
662658

663-
JoinedEnv.LocToVal = joinKeyToValueMap(EnvA.LocToVal, EnvB.LocToVal, EnvA,
664-
EnvB, JoinedEnv, Model);
659+
// We intentionally leave `JoinedEnv.ExprToLoc` and `JoinedEnv.ExprToVal`
660+
// empty, as we never need to access entries in these maps outside of the
661+
// basic block that sets them.
665662

666663
return JoinedEnv;
667664
}

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,10 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
623623
// FIXME: Revisit this once flow conditions are added to the framework. For
624624
// `a = b ? c : d` we can add `b => a == c && !b => a == d` to the flow
625625
// condition.
626+
// When we do this, we will need to retrieve the values of the operands from
627+
// the environments for the basic blocks they are computed in, in a similar
628+
// way to how this is done for short-circuited logical operators in
629+
// `getLogicOperatorSubExprValue()`.
626630
if (S->isGLValue())
627631
Env.setStorageLocation(*S, Env.createObject(S->getType()));
628632
else if (Value *Val = Env.createValue(S->getType()))

clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,12 @@ class JoinedStateBuilder {
257257
// initialize the state of each basic block differently.
258258
return {AC.Analysis.typeErasedInitialElement(), AC.InitEnv.fork()};
259259
if (All.size() == 1)
260-
return Owned.empty() ? All.front()->fork() : std::move(Owned.front());
260+
// Join the environment with itself so that we discard the entries from
261+
// `ExprToLoc` and `ExprToVal`.
262+
// FIXME: We could consider writing special-case code for this that only
263+
// does the discarding, but it's not clear if this is worth it.
264+
return {All[0]->Lattice,
265+
Environment::join(All[0]->Env, All[0]->Env, AC.Analysis)};
261266

262267
auto Result = join(*All[0], *All[1]);
263268
for (unsigned I = 2; I < All.size(); ++I)

clang/lib/Driver/ToolChains/Gnu.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,14 +2236,17 @@ void Generic_GCC::GCCInstallationDetector::init(
22362236
// The compatible GCC triples for this particular architecture.
22372237
SmallVector<StringRef, 16> CandidateTripleAliases;
22382238
SmallVector<StringRef, 16> CandidateBiarchTripleAliases;
2239+
// Add some triples that we want to check first.
2240+
CandidateTripleAliases.push_back(TargetTriple.str());
2241+
std::string TripleNoVendor = TargetTriple.getArchName().str() + "-" +
2242+
TargetTriple.getOSAndEnvironmentName().str();
2243+
if (TargetTriple.getVendor() == llvm::Triple::UnknownVendor)
2244+
CandidateTripleAliases.push_back(TripleNoVendor);
2245+
22392246
CollectLibDirsAndTriples(TargetTriple, BiarchVariantTriple, CandidateLibDirs,
22402247
CandidateTripleAliases, CandidateBiarchLibDirs,
22412248
CandidateBiarchTripleAliases);
22422249

2243-
TripleNoVendor = TargetTriple.getArchName().str() + "-" +
2244-
TargetTriple.getOSAndEnvironmentName().str();
2245-
StringRef TripleNoVendorRef(TripleNoVendor);
2246-
22472250
// If --gcc-install-dir= is specified, skip filesystem detection.
22482251
if (const Arg *A =
22492252
Args.getLastArg(clang::driver::options::OPT_gcc_install_dir_EQ);
@@ -2323,13 +2326,6 @@ void Generic_GCC::GCCInstallationDetector::init(
23232326
// Maybe filter out <libdir>/gcc and <libdir>/gcc-cross.
23242327
bool GCCDirExists = VFS.exists(LibDir + "/gcc");
23252328
bool GCCCrossDirExists = VFS.exists(LibDir + "/gcc-cross");
2326-
// Try to match the exact target triple first.
2327-
ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, TargetTriple.str(),
2328-
false, GCCDirExists, GCCCrossDirExists);
2329-
// If vendor is unknown, let's try triple without vendor.
2330-
if (TargetTriple.getVendor() == llvm::Triple::UnknownVendor)
2331-
ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, TripleNoVendorRef,
2332-
false, GCCDirExists, GCCCrossDirExists);
23332329
for (StringRef Candidate : CandidateTripleAliases)
23342330
ScanLibDirForGCCTriple(TargetTriple, Args, LibDir, Candidate, false,
23352331
GCCDirExists, GCCCrossDirExists);
@@ -3076,6 +3072,7 @@ ToolChain::UnwindTableLevel
30763072
Generic_GCC::getDefaultUnwindTableLevel(const ArgList &Args) const {
30773073
switch (getArch()) {
30783074
case llvm::Triple::aarch64:
3075+
case llvm::Triple::aarch64_be:
30793076
case llvm::Triple::ppc:
30803077
case llvm::Triple::ppcle:
30813078
case llvm::Triple::ppc64:

0 commit comments

Comments
 (0)