Skip to content

Commit d6bc6d5

Browse files
committed
Merge main into amd-gfx
2 parents 9c12bfd + e24a212 commit d6bc6d5

File tree

122 files changed

+15387
-2379
lines changed

Some content is hidden

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

122 files changed

+15387
-2379
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 77 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5422,16 +5422,85 @@ The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets.
54225422
The second parameter is the library name (without the traditional Unix prefix of
54235423
``lib``). This allows you to provide an implicit link of dependent libraries.
54245424
5425-
Evaluating Object Size Dynamically
5426-
==================================
5425+
Evaluating Object Size
5426+
======================
5427+
5428+
Clang supports the builtins ``__builtin_object_size`` and
5429+
``__builtin_dynamic_object_size``. The semantics are compatible with GCC's
5430+
builtins of the same names, but the details are slightly different.
5431+
5432+
.. code-block:: c
5433+
5434+
size_t __builtin_[dynamic_]object_size(const void *ptr, int type)
5435+
5436+
Returns the number of accessible bytes ``n`` past ``ptr``. The value returned
5437+
depends on ``type``, which is required to be an integer constant between 0 and
5438+
3:
5439+
5440+
* If ``type & 2 == 0``, the least ``n`` is returned such that accesses to
5441+
``(const char*)ptr + n`` and beyond are known to be out of bounds. This is
5442+
``(size_t)-1`` if no better bound is known.
5443+
* If ``type & 2 == 2``, the greatest ``n`` is returned such that accesses to
5444+
``(const char*)ptr + i`` are known to be in bounds, for 0 <= ``i`` < ``n``.
5445+
This is ``(size_t)0`` if no better bound is known.
54275446
5428-
Clang supports the builtin ``__builtin_dynamic_object_size``, the semantics are
5429-
the same as GCC's ``__builtin_object_size`` (which Clang also supports), but
5430-
``__builtin_dynamic_object_size`` can evaluate the object's size at runtime.
5431-
``__builtin_dynamic_object_size`` is meant to be used as a drop-in replacement
5432-
for ``__builtin_object_size`` in libraries that support it.
5447+
.. code-block:: c
5448+
5449+
char small[10], large[100];
5450+
bool cond;
5451+
// Returns 100: writes of more than 100 bytes are known to be out of bounds.
5452+
int n100 = __builtin_object_size(cond ? small : large, 0);
5453+
// Returns 10: writes of 10 or fewer bytes are known to be in bounds.
5454+
int n10 = __builtin_object_size(cond ? small : large, 2);
5455+
5456+
* If ``type & 1 == 0``, pointers are considered to be in bounds if they point
5457+
into the same storage as ``ptr`` -- that is, the same stack object, global
5458+
variable, or heap allocation.
5459+
* If ``type & 1 == 1``, pointers are considered to be in bounds if they point
5460+
to the same subobject that ``ptr`` points to. If ``ptr`` points to an array
5461+
element, other elements of the same array, but not of enclosing arrays, are
5462+
considered in bounds.
5463+
5464+
.. code-block:: c
5465+
5466+
struct X { char a, b, c; } x;
5467+
static_assert(__builtin_object_size(&x, 0) == 3);
5468+
static_assert(__builtin_object_size(&x.b, 0) == 2);
5469+
static_assert(__builtin_object_size(&x.b, 1) == 1);
5470+
5471+
.. code-block:: c
54335472
5434-
For instance, here is a program that ``__builtin_dynamic_object_size`` will make
5473+
char a[10][10][10];
5474+
static_assert(__builtin_object_size(&a, 1) == 1000);
5475+
static_assert(__builtin_object_size(&a[1], 1) == 900);
5476+
static_assert(__builtin_object_size(&a[1][1], 1) == 90);
5477+
static_assert(__builtin_object_size(&a[1][1][1], 1) == 9);
5478+
5479+
The values returned by this builtin are a best effort conservative approximation
5480+
of the correct answers. When ``type & 2 == 0``, the true value is less than or
5481+
equal to the value returned by the builtin, and when ``type & 2 == 1``, the true
5482+
value is greater than or equal to the value returned by the builtin.
5483+
5484+
For ``__builtin_object_size``, the value is determined entirely at compile time.
5485+
With optimization enabled, better results will be produced, especially when the
5486+
call to ``__builtin_object_size`` is in a different function from the formation
5487+
of the pointer. Unlike in GCC, enabling optimization in Clang does not allow
5488+
more information about subobjects to be determined, so the ``type & 1 == 1``
5489+
case will often give imprecise results when used across a function call boundary
5490+
even when optimization is enabled.
5491+
5492+
`The pass_object_size and pass_dynamic_object_size attributes <https://clang.llvm.org/docs/AttributeReference.html#pass-object-size-pass-dynamic-object-size>`_
5493+
can be used to invisibly pass the object size for a pointer parameter alongside
5494+
the pointer in a function call. This allows more precise object sizes to be
5495+
determined both when building without optimizations and in the ``type & 1 == 1``
5496+
case.
5497+
5498+
For ``__builtin_dynamic_object_size``, the result is not limited to being a
5499+
compile time constant. Instead, a small amount of runtime evaluation is
5500+
permitted to determine the size of the object, in order to give a more precise
5501+
result. ``__builtin_dynamic_object_size`` is meant to be used as a drop-in
5502+
replacement for ``__builtin_object_size`` in libraries that support it. For
5503+
instance, here is a program that ``__builtin_dynamic_object_size`` will make
54355504
safer:
54365505
54375506
.. code-block:: c

clang/include/clang/Analysis/FlowSensitive/ASTOps.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,11 @@ class AnalysisASTVisitor : public RecursiveASTVisitor<Derived> {
113113
// nevertheless it appears in the Clang CFG, so we don't exclude it here.
114114
bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) { return true; }
115115
bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) { return true; }
116-
bool TraverseCXXTypeidExpr(CXXTypeidExpr *) { return true; }
116+
bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) {
117+
if (TIE->isPotentiallyEvaluated())
118+
return RecursiveASTVisitor<Derived>::TraverseCXXTypeidExpr(TIE);
119+
return true;
120+
}
117121
bool TraverseUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *) {
118122
return true;
119123
}

clang/include/clang/Basic/arm_sme.td

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,4 +764,27 @@ let SMETargetGuard = "sme-f16f16" in {
764764
[ImmCheck<0, ImmCheck0_1>]>;
765765
}
766766

767+
768+
multiclass ZAReadz<string n_suffix, string vg_num, string t, string i_prefix, list<ImmCheck> ch> {
769+
let SMETargetGuard = "sme2p1" in {
770+
def NAME # _H : SInst<"svreadz_hor_" # n_suffix # "_{d}_vg" # vg_num, vg_num # "im", t,
771+
MergeNone, i_prefix # "_horiz_x" # vg_num,
772+
[IsStreaming, IsInOutZA], ch>;
773+
774+
def NAME # _V : SInst<"svreadz_ver_" # n_suffix # "_{d}_vg" # vg_num, vg_num # "im", t,
775+
MergeNone, i_prefix # "_vert_x" #vg_num,
776+
[IsStreaming, IsInOutZA], ch>;
777+
}
778+
}
779+
780+
defm SVREADZ_ZA8_X2 : ZAReadz<"za8", "2", "cUc", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_0>]>;
781+
defm SVREADZ_ZA16_X2 : ZAReadz<"za16", "2", "sUshb", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_1>]>;
782+
defm SVREADZ_ZA32_X2 : ZAReadz<"za32", "2", "iUif", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_3>]>;
783+
defm SVREADZ_ZA64_X2 : ZAReadz<"za64", "2", "lUld", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_7>]>;
784+
785+
defm SVREADZ_ZA8_X4 : ZAReadz<"za8", "4", "cUc", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_0>]>;
786+
defm SVREADZ_ZA16_X4 : ZAReadz<"za16", "4", "sUshb", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_1>]>;
787+
defm SVREADZ_ZA32_X4 : ZAReadz<"za32", "4", "iUif", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_3>]>;
788+
defm SVREADZ_ZA64_X4 : ZAReadz<"za64", "4", "lUld", "aarch64_sme_readz", [ImmCheck<0, ImmCheck0_7>]>;
789+
767790
} // let SVETargetGuard = InvalidMode

clang/include/clang/Parse/Parser.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3511,6 +3511,19 @@ class Parser : public CodeCompletionHandler {
35113511
/// metadirective and therefore ends on the closing paren.
35123512
StmtResult ParseOpenMPDeclarativeOrExecutableDirective(
35133513
ParsedStmtContext StmtCtx, bool ReadDirectiveWithinMetadirective = false);
3514+
3515+
/// Parses executable directive.
3516+
///
3517+
/// \param StmtCtx The context in which we're parsing the directive.
3518+
/// \param DKind The kind of the executable directive.
3519+
/// \param Loc Source location of the beginning of the directive.
3520+
/// \param ReadDirectiveWithinMetadirective true if directive is within a
3521+
/// metadirective and therefore ends on the closing paren.
3522+
StmtResult
3523+
ParseOpenMPExecutableDirective(ParsedStmtContext StmtCtx,
3524+
OpenMPDirectiveKind DKind, SourceLocation Loc,
3525+
bool ReadDirectiveWithinMetadirective);
3526+
35143527
/// Parses clause of kind \a CKind for directive of a kind \a Kind.
35153528
///
35163529
/// \param DKind Kind of current directive.

clang/lib/AST/Interp/Interp.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,9 @@ bool CheckNull(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
341341
if (!Ptr.isZero())
342342
return true;
343343
const SourceInfo &Loc = S.Current->getSource(OpPC);
344-
S.FFDiag(Loc, diag::note_constexpr_null_subobject) << CSK;
344+
S.FFDiag(Loc, diag::note_constexpr_null_subobject)
345+
<< CSK << S.Current->getRange(OpPC);
346+
345347
return false;
346348
}
347349

@@ -350,7 +352,8 @@ bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
350352
if (!Ptr.isOnePastEnd())
351353
return true;
352354
const SourceInfo &Loc = S.Current->getSource(OpPC);
353-
S.FFDiag(Loc, diag::note_constexpr_access_past_end) << AK;
355+
S.FFDiag(Loc, diag::note_constexpr_access_past_end)
356+
<< AK << S.Current->getRange(OpPC);
354357
return false;
355358
}
356359

@@ -359,7 +362,8 @@ bool CheckRange(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
359362
if (!Ptr.isElementPastEnd())
360363
return true;
361364
const SourceInfo &Loc = S.Current->getSource(OpPC);
362-
S.FFDiag(Loc, diag::note_constexpr_past_end_subobject) << CSK;
365+
S.FFDiag(Loc, diag::note_constexpr_past_end_subobject)
366+
<< CSK << S.Current->getRange(OpPC);
363367
return false;
364368
}
365369

@@ -369,7 +373,8 @@ bool CheckSubobject(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
369373
return true;
370374

371375
const SourceInfo &Loc = S.Current->getSource(OpPC);
372-
S.FFDiag(Loc, diag::note_constexpr_past_end_subobject) << CSK;
376+
S.FFDiag(Loc, diag::note_constexpr_past_end_subobject)
377+
<< CSK << S.Current->getRange(OpPC);
373378
return false;
374379
}
375380

clang/lib/AST/Interp/Pointer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,8 @@ class Pointer {
513513
unsigned getByteOffset() const {
514514
if (isIntegralPointer())
515515
return asIntPointer().Value + Offset;
516+
if (isOnePastEnd())
517+
return PastEndMark;
516518
return Offset;
517519
}
518520

clang/lib/Analysis/FlowSensitive/Transfer.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -391,17 +391,22 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
391391
}
392392
case UO_PreInc:
393393
case UO_PreDec:
394-
// Propagate the storage location, but don't create a new value; to
395-
// avoid generating unnecessary values, we leave it to the specific
396-
// analysis to do this if desired.
394+
// Propagate the storage location and clear out any value associated with
395+
// it (to represent the fact that the value has definitely changed).
396+
// To avoid generating unnecessary values, we leave it to the specific
397+
// analysis to create a new value if desired.
397398
propagateStorageLocation(*S->getSubExpr(), *S, Env);
399+
if (StorageLocation *Loc = Env.getStorageLocation(*S->getSubExpr()))
400+
Env.clearValue(*Loc);
398401
break;
399402
case UO_PostInc:
400403
case UO_PostDec:
401-
// Propagate the old value, but don't create a new value; to avoid
402-
// generating unnecessary values, we leave it to the specific analysis
403-
// to do this if desired.
404+
// Propagate the old value, then clear out any value associated with the
405+
// storage location (to represent the fact that the value has definitely
406+
// changed). See above for rationale.
404407
propagateValue(*S->getSubExpr(), *S, Env);
408+
if (StorageLocation *Loc = Env.getStorageLocation(*S->getSubExpr()))
409+
Env.clearValue(*Loc);
405410
break;
406411
default:
407412
break;

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18479,6 +18479,16 @@ Value *CodeGenFunction::EmitAMDGPUBuiltinExpr(unsigned BuiltinID,
1847918479
CGM.getIntrinsic(Intrinsic::amdgcn_update_dpp, Args[0]->getType());
1848018480
return Builder.CreateCall(F, Args);
1848118481
}
18482+
case AMDGPU::BI__builtin_amdgcn_permlane16:
18483+
case AMDGPU::BI__builtin_amdgcn_permlanex16:
18484+
return emitBuiltinWithOneOverloadedType<6>(
18485+
*this, E,
18486+
BuiltinID == AMDGPU::BI__builtin_amdgcn_permlane16
18487+
? Intrinsic::amdgcn_permlane16
18488+
: Intrinsic::amdgcn_permlanex16);
18489+
case AMDGPU::BI__builtin_amdgcn_permlane64:
18490+
return emitBuiltinWithOneOverloadedType<1>(*this, E,
18491+
Intrinsic::amdgcn_permlane64);
1848218492
case AMDGPU::BI__builtin_amdgcn_readlane:
1848318493
return emitBuiltinWithOneOverloadedType<2>(*this, E,
1848418494
Intrinsic::amdgcn_readlane);

0 commit comments

Comments
 (0)