Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d344624
MLIR: asan: Fix python tests under asan on Linux (#123303)
mgehre-amd Jan 29, 2025
d199732
[TableGen] Use MCRegister::id() to avoid an implicit conversion from …
topperc Jan 29, 2025
267e293
[bazel] Introduce MAX_CLANG_ABI_COMPAT_VERSION (for #123998)
chapuni Jan 29, 2025
71edfd6
[AMDGPU][NewPM] Sketch out a AMDGPUPassRegistry skeleton (#124785)
optimisan Jan 29, 2025
a3aa452
[CodeGen] RegisterCoalescer: Remove unused AliasAnalysis dependency (…
optimisan Jan 29, 2025
07efe2c
[SCEV] Check correct value for UB (#124302)
nikic Jan 29, 2025
c836b89
[LoopVectorize][NFC] Disable output for tests that don't need it (#12…
david-arm Jan 29, 2025
5d3ae51
Reapply "[mlir][python] allow DenseIntElementsAttr for index type (#1…
mgehre-amd Jan 29, 2025
9326633
[lldb] Remove PATH workaround for Android (#124682)
brad0 Jan 29, 2025
51c7338
[clang][bytecode] Fix dummy handling for p2280r4 (#124396)
tbaederr Jan 29, 2025
e811cb0
[flang] Implement !DIR$ UNROLL [N] (#123331)
JDPailleux Jan 29, 2025
5a34e6f
[flang] Implement CHDIR intrinsic (#124280)
JDPailleux Jan 29, 2025
e902cf2
[LLD][COFF] Write both native and EC export symbols to the import lib…
cjacek Jan 29, 2025
1ac3665
[clang] Restrict the use of scalar types in vector builtins (#119423)
frasercrmck Jan 29, 2025
2a1f795
[MLIR] Fix import of invokes with mismatched variadic types (#124828)
xlauko Jan 29, 2025
776ef9d
[LoopVectorize][NFC] Regenerate some early exit test CHECK lines (#12…
david-arm Jan 29, 2025
9ea64dd
[lldb] Make Python >= 3.8 required for LLDB 21 (#124735)
DavidSpickett Jan 29, 2025
db567ea
[lldb][NFC] Format part of ScriptInterpreterPython.cpp
DavidSpickett Jan 29, 2025
89e767f
[LoopIdiom] Move up atomic checks for memcpy/memmove (NFC) (#124535)
kasuga-fj Jan 29, 2025
e80d934
[MCJIT][test] Move remaining MCJIT interpreter tests to Interpreter/ …
asb Jan 29, 2025
89ca3e7
[CostModel][X86] Reduce worst case v8i16/v16i8 SSE2 shuffle costs (#1…
RKSimon Jan 29, 2025
690f251
[LoopInterchange] Handle LE and GE correctly (#124901)
kasuga-fj Jan 29, 2025
f20b8e3
[MLIR][Linalg] Fixes for Winograd decomposition and for tiling (#123675)
d-smirnov Jan 29, 2025
5e43418
[ARM] Forbid use of TLS with execute-only (#124806)
ostannard Jan 29, 2025
36b3c43
[AArch64] PAUTH_PROLOGUE should not be duplicated with PAuthLR (#124775)
ostannard Jan 29, 2025
2b55ef1
[VPlan] Add helper to run VPlan passes, verify after run (NFC). (#123…
fhahn Jan 29, 2025
ecc71de
[flang] Implement IERRNO intrinsic (#124281)
JDPailleux Jan 29, 2025
12cdf43
[libclc] Move (add|sub)_sat to CLC; optimize (#124903)
frasercrmck Jan 29, 2025
9534d27
[X86] vector-idiv-sdiv-512.ll - regenerate VPTERNLOG comments
RKSimon Jan 29, 2025
87782b2
[mlir][x86vector] AVX512-BF16 Dot op (#124800)
adam-smnk Jan 29, 2025
2f40145
[RISCV][TTI]Use processShuffleMasks for cost estimations/actual per-r…
alexey-bataev Jan 29, 2025
8d6b241
[mlir] Make `TypedStrAttr` actually enforce the string type. (#124770)
ingomueller-net Jan 29, 2025
983562d
[AMDGPU][NFC] Simplify t16/fake16 TableGen definitions. (#122693)
kosarev Jan 29, 2025
24824f0
[AutoBump] Merge with fixes of d3446240 (Jan 29)
jorickert Mar 26, 2026
d8ce88b
[AutoBump] Merge with c836b895 (Jan 29)
jorickert Mar 26, 2026
a8baad4
[AutoBump] Merge with fixes of 5d3ae516 (Jan 29)
jorickert Mar 26, 2026
97e1bc9
[AutoBump] Merge with 983562d8 (Jan 29)
jorickert Mar 26, 2026
89207f4
[AutoBump] Merge with c836b895 (Jan 29) (4) (#872)
jorickert Mar 27, 2026
f8117b9
[AutoBump] Merge with fixes of 5d3ae516 (Jan 29) (5) (#873)
jorickert Mar 27, 2026
255b0e1
[AutoBump] Merge with 983562d8 (Jan 29) (6) (#874)
jorickert Mar 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,9 @@ The integer elementwise intrinsics, including ``__builtin_elementwise_popcount``
``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``,
``__builtin_elementwise_sub_sat`` can be called in a ``constexpr`` context.

No implicit promotion of integer types takes place. The mixing of integer types
of different sizes and signs is forbidden in binary and ternary builtins.

============================================== ====================================================================== =========================================
Name Operation Supported element types
============================================== ====================================================================== =========================================
Expand Down
17 changes: 14 additions & 3 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2331,7 +2331,8 @@ class Sema final : public SemaBase {
const FunctionProtoType *Proto);

/// \param FPOnly restricts the arguments to floating-point types.
bool BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly = false);
std::optional<QualType> BuiltinVectorMath(CallExpr *TheCall,
bool FPOnly = false);
bool BuiltinVectorToScalarMath(CallExpr *TheCall);

void checkLifetimeCaptureBy(FunctionDecl *FDecl, bool IsMemberFunction,
Expand Down Expand Up @@ -7499,10 +7500,15 @@ class Sema final : public SemaBase {
return K == ConditionKind::Switch ? Context.IntTy : Context.BoolTy;
}

// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
// functions and arrays to their respective pointers (C99 6.3.2.1).
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2), converts
// functions and arrays to their respective pointers (C99 6.3.2.1), and
// promotes floating-piont types according to the language semantics.
ExprResult UsualUnaryConversions(Expr *E);

// UsualUnaryFPConversions - promotes floating-point types according to the
// current language semantics.
ExprResult UsualUnaryFPConversions(Expr *E);

/// CallExprUnaryConversions - a special case of an unary conversion
/// performed on a function designator of a call expression.
ExprResult CallExprUnaryConversions(Expr *E);
Expand Down Expand Up @@ -7565,6 +7571,11 @@ class Sema final : public SemaBase {
ExprResult DefaultVariadicArgumentPromotion(Expr *E, VariadicCallType CT,
FunctionDecl *FDecl);

// Check that the usual arithmetic conversions can be performed on this pair
// of expressions that might be of enumeration type.
void checkEnumArithmeticConversions(Expr *LHS, Expr *RHS, SourceLocation Loc,
Sema::ArithConvKind ACK);

// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
// operands and then handles various conversions that are common to binary
// operators (C99 6.3.1.8). If both operands aren't arithmetic, this
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ByteCode/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6175,7 +6175,7 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
}

if (D->getType()->isReferenceType())
return false; // FIXME: Do we need to emit InvalidDeclRef?
return this->emitDummyPtr(D, E);
}

// In case we need to re-visit a declaration.
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/AST/ByteCode/Descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@ QualType Descriptor::getElemQualType() const {
assert(isArray());
QualType T = getType();
if (T->isPointerOrReferenceType())
return T->getPointeeType();
T = T->getPointeeType();

if (const auto *AT = T->getAsArrayTypeUnsafe()) {
// For primitive arrays, we don't save a QualType at all,
// just a PrimType. Try to figure out the QualType here.
Expand All @@ -424,7 +425,8 @@ QualType Descriptor::getElemQualType() const {
return CT->getElementType();
if (const auto *CT = T->getAs<VectorType>())
return CT->getElementType();
llvm_unreachable("Array that's not an array/complex/vector type?");

return T;
}

SourceLocation Descriptor::getLocation() const {
Expand Down
20 changes: 9 additions & 11 deletions clang/lib/AST/ByteCode/Interp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ static bool diagnoseUnknownDecl(InterpState &S, CodePtr OpPC,
const SourceInfo &E = S.Current->getSource(OpPC);

if (isa<ParmVarDecl>(D)) {
if (D->getType()->isReferenceType())
return false;

if (S.getLangOpts().CPlusPlus11) {
S.FFDiag(E, diag::note_constexpr_function_param_value_unknown) << D;
S.Note(D->getLocation(), diag::note_declared_at) << D->getSourceRange();
Expand Down Expand Up @@ -1287,6 +1290,12 @@ bool Call(InterpState &S, CodePtr OpPC, const Function *Func,

const Pointer &ThisPtr = S.Stk.peek<Pointer>(ThisOffset);

// C++23 [expr.const]p5.6
// an invocation of a virtual function ([class.virtual]) for an object whose
// dynamic type is constexpr-unknown;
if (ThisPtr.isDummy() && Func->isVirtual())
return false;

// If the current function is a lambda static invoker and
// the function we're about to call is a lambda call operator,
// skip the CheckInvoke, since the ThisPtr is a null pointer
Expand Down Expand Up @@ -1661,17 +1670,6 @@ bool GetTypeidPtr(InterpState &S, CodePtr OpPC, const Type *TypeInfoType) {
if (!P.isBlockPointer())
return false;

if (P.isDummy()) {
QualType StarThisType =
S.getASTContext().getLValueReferenceType(P.getType());
S.FFDiag(S.Current->getSource(OpPC),
diag::note_constexpr_polymorphic_unknown_dynamic_type)
<< AK_TypeId
<< P.toAPValue(S.getASTContext())
.getAsString(S.getASTContext(), StarThisType);
return false;
}

S.Stk.push<Pointer>(P.getType().getTypePtr(), TypeInfoType);
return true;
}
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/AST/ByteCode/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1538,9 +1538,12 @@ static bool interp__builtin_constant_p(InterpState &S, CodePtr OpPC,
if (ArgType->isIntegralOrEnumerationType() || ArgType->isFloatingType() ||
ArgType->isAnyComplexType() || ArgType->isPointerType() ||
ArgType->isNullPtrType()) {
auto PrevDiags = S.getEvalStatus().Diag;
S.getEvalStatus().Diag = nullptr;
InterpStack Stk;
Compiler<EvalEmitter> C(S.Ctx, S.P, S, Stk);
auto Res = C.interpretExpr(Arg, /*ConvertResultToRValue=*/Arg->isGLValue());
S.getEvalStatus().Diag = PrevDiags;
if (Res.isInvalid()) {
C.cleanup();
Stk.clear();
Expand Down
33 changes: 22 additions & 11 deletions clang/lib/AST/ByteCode/Pointer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
return ASTCtx.toCharUnitsFromBits(Layout.getFieldOffset(FieldIndex));
};

bool UsePath = true;
if (getType()->isLValueReferenceType())
UsePath = false;

// Build the path into the object.
Pointer Ptr = *this;
while (Ptr.isField() || Ptr.isArrayElement()) {
Expand All @@ -217,38 +221,42 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
// An array root may still be an array element itself.
if (Ptr.isArrayElement()) {
Ptr = Ptr.expand();
const Descriptor *Desc = Ptr.getFieldDesc();
unsigned Index = Ptr.getIndex();
Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
QualType ElemType = Ptr.getFieldDesc()->getElemQualType();
QualType ElemType = Desc->getElemQualType();
Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType));
if (Ptr.getArray().getType()->isArrayType())
Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
Ptr = Ptr.getArray();
} else {
Path.push_back(APValue::LValuePathEntry(
{Ptr.getFieldDesc()->asDecl(), /*IsVirtual=*/false}));
const Descriptor *Desc = Ptr.getFieldDesc();
const auto *Dcl = Desc->asDecl();
Path.push_back(APValue::LValuePathEntry({Dcl, /*IsVirtual=*/false}));

if (const auto *FD =
dyn_cast_if_present<FieldDecl>(Ptr.getFieldDesc()->asDecl()))
if (const auto *FD = dyn_cast_if_present<FieldDecl>(Dcl))
Offset += getFieldOffset(FD);

Ptr = Ptr.getBase();
}
} else if (Ptr.isArrayElement()) {
Ptr = Ptr.expand();
const Descriptor *Desc = Ptr.getFieldDesc();
unsigned Index;
if (Ptr.isOnePastEnd())
Index = Ptr.getArray().getNumElems();
else
Index = Ptr.getIndex();

QualType ElemType = Ptr.getFieldDesc()->getElemQualType();
QualType ElemType = Desc->getElemQualType();
Offset += (Index * ASTCtx.getTypeSizeInChars(ElemType));
Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
if (Ptr.getArray().getType()->isArrayType())
Path.push_back(APValue::LValuePathEntry::ArrayIndex(Index));
Ptr = Ptr.getArray();
} else {
const Descriptor *Desc = Ptr.getFieldDesc();
bool IsVirtual = false;

// Create a path entry for the field.
const Descriptor *Desc = Ptr.getFieldDesc();
if (const auto *BaseOrMember = Desc->asDecl()) {
if (const auto *FD = dyn_cast<FieldDecl>(BaseOrMember)) {
Ptr = Ptr.getBase();
Expand Down Expand Up @@ -281,8 +289,11 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
// Just invert the order of the elements.
std::reverse(Path.begin(), Path.end());

return APValue(Base, Offset, Path, /*IsOnePastEnd=*/isOnePastEnd(),
/*IsNullPtr=*/false);
if (UsePath)
return APValue(Base, Offset, Path,
/*IsOnePastEnd=*/!isElementPastEnd() && isOnePastEnd());

return APValue(Base, Offset, APValue::NoLValuePath());
}

void Pointer::print(llvm::raw_ostream &OS) const {
Expand Down
3 changes: 1 addition & 2 deletions clang/lib/AST/ByteCode/Pointer.h
Original file line number Diff line number Diff line change
Expand Up @@ -630,8 +630,7 @@ class Pointer {
if (isUnknownSizeArray())
return false;

return isElementPastEnd() || isPastEnd() ||
(getSize() == getOffset() && !isZeroSizeArray());
return isPastEnd() || (getSize() == getOffset() && !isZeroSizeArray());
}

/// Checks if the pointer points past the end of the object.
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Basic/Targets/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,8 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasBTI = 1;
} else if (Feature == "+fullbf16") {
HasFullBFloat16 = true;
} else if (Feature == "+execute-only") {
TLSSupported = false;
}
}

Expand Down
106 changes: 73 additions & 33 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14649,11 +14649,23 @@ void Sema::CheckAddressOfPackedMember(Expr *rhs) {
_2, _3, _4));
}

// Performs a similar job to Sema::UsualUnaryConversions, but without any
// implicit promotion of integral/enumeration types.
static ExprResult BuiltinVectorMathConversions(Sema &S, Expr *E) {
// First, convert to an r-value.
ExprResult Res = S.DefaultFunctionArrayLvalueConversion(E);
if (Res.isInvalid())
return ExprError();

// Promote floating-point types.
return S.UsualUnaryFPConversions(Res.get());
}

bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
if (checkArgCount(TheCall, 1))
return true;

ExprResult A = UsualUnaryConversions(TheCall->getArg(0));
ExprResult A = BuiltinVectorMathConversions(*this, TheCall->getArg(0));
if (A.isInvalid())
return true;

Expand All @@ -14668,67 +14680,95 @@ bool Sema::PrepareBuiltinElementwiseMathOneArgCall(CallExpr *TheCall) {
}

bool Sema::BuiltinElementwiseMath(CallExpr *TheCall, bool FPOnly) {
QualType Res;
if (BuiltinVectorMath(TheCall, Res, FPOnly))
return true;
TheCall->setType(Res);
return false;
if (auto Res = BuiltinVectorMath(TheCall, FPOnly); Res.has_value()) {
TheCall->setType(*Res);
return false;
}
return true;
}

bool Sema::BuiltinVectorToScalarMath(CallExpr *TheCall) {
QualType Res;
if (BuiltinVectorMath(TheCall, Res))
std::optional<QualType> Res = BuiltinVectorMath(TheCall);
if (!Res)
return true;

if (auto *VecTy0 = Res->getAs<VectorType>())
if (auto *VecTy0 = (*Res)->getAs<VectorType>())
TheCall->setType(VecTy0->getElementType());
else
TheCall->setType(Res);
TheCall->setType(*Res);

return false;
}

bool Sema::BuiltinVectorMath(CallExpr *TheCall, QualType &Res, bool FPOnly) {
static bool checkBuiltinVectorMathMixedEnums(Sema &S, Expr *LHS, Expr *RHS,
SourceLocation Loc) {
QualType L = LHS->getEnumCoercedType(S.Context),
R = RHS->getEnumCoercedType(S.Context);
if (L->isUnscopedEnumerationType() && R->isUnscopedEnumerationType() &&
!S.Context.hasSameUnqualifiedType(L, R)) {
return S.Diag(Loc, diag::err_conv_mixed_enum_types_cxx26)
<< LHS->getSourceRange() << RHS->getSourceRange()
<< /*Arithmetic Between*/ 0 << L << R;
}
return false;
}

std::optional<QualType> Sema::BuiltinVectorMath(CallExpr *TheCall,
bool FPOnly) {
if (checkArgCount(TheCall, 2))
return true;
return std::nullopt;

ExprResult A = TheCall->getArg(0);
ExprResult B = TheCall->getArg(1);
// Do standard promotions between the two arguments, returning their common
// type.
Res = UsualArithmeticConversions(A, B, TheCall->getExprLoc(), ACK_Comparison);
if (A.isInvalid() || B.isInvalid())
return true;
if (checkBuiltinVectorMathMixedEnums(
*this, TheCall->getArg(0), TheCall->getArg(1), TheCall->getExprLoc()))
return std::nullopt;

QualType TyA = A.get()->getType();
QualType TyB = B.get()->getType();
Expr *Args[2];
for (int I = 0; I < 2; ++I) {
ExprResult Converted =
BuiltinVectorMathConversions(*this, TheCall->getArg(I));
if (Converted.isInvalid())
return std::nullopt;
Args[I] = Converted.get();
}

if (Res.isNull() || TyA.getCanonicalType() != TyB.getCanonicalType())
return Diag(A.get()->getBeginLoc(),
diag::err_typecheck_call_different_arg_types)
<< TyA << TyB;
SourceLocation LocA = Args[0]->getBeginLoc();
QualType TyA = Args[0]->getType();
QualType TyB = Args[1]->getType();

if (TyA.getCanonicalType() != TyB.getCanonicalType()) {
Diag(LocA, diag::err_typecheck_call_different_arg_types) << TyA << TyB;
return std::nullopt;
}

if (FPOnly) {
if (checkFPMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1))
return true;
if (checkFPMathBuiltinElementType(*this, LocA, TyA, 1))
return std::nullopt;
} else {
if (checkMathBuiltinElementType(*this, A.get()->getBeginLoc(), TyA, 1))
return true;
if (checkMathBuiltinElementType(*this, LocA, TyA, 1))
return std::nullopt;
}

TheCall->setArg(0, A.get());
TheCall->setArg(1, B.get());
return false;
TheCall->setArg(0, Args[0]);
TheCall->setArg(1, Args[1]);
return TyA;
}

bool Sema::BuiltinElementwiseTernaryMath(CallExpr *TheCall,
bool CheckForFloatArgs) {
if (checkArgCount(TheCall, 3))
return true;

SourceLocation Loc = TheCall->getExprLoc();
if (checkBuiltinVectorMathMixedEnums(*this, TheCall->getArg(0),
TheCall->getArg(1), Loc) ||
checkBuiltinVectorMathMixedEnums(*this, TheCall->getArg(1),
TheCall->getArg(2), Loc))
return true;

Expr *Args[3];
for (int I = 0; I < 3; ++I) {
ExprResult Converted = UsualUnaryConversions(TheCall->getArg(I));
ExprResult Converted =
BuiltinVectorMathConversions(*this, TheCall->getArg(I));
if (Converted.isInvalid())
return true;
Args[I] = Converted.get();
Expand Down
Loading
Loading