Skip to content

Commit 44e5533

Browse files
author
z1_cciauto
authored
merge main into amd-staging (llvm#3747)
2 parents 52736a4 + 3fe8d3a commit 44e5533

File tree

159 files changed

+2665
-1849
lines changed

Some content is hidden

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

159 files changed

+2665
-1849
lines changed

clang/docs/LanguageExtensions.rst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4179,7 +4179,7 @@ builtin, the mangler emits their usual pattern without any special treatment.
41794179
-----------------------
41804180
41814181
``__builtin_popcountg`` returns the number of 1 bits in the argument. The
4182-
argument can be of any unsigned integer type.
4182+
argument can be of any unsigned integer type or fixed boolean vector.
41834183
41844184
**Syntax**:
41854185
@@ -4211,7 +4211,13 @@ such as ``unsigned __int128`` and C23 ``unsigned _BitInt(N)``.
42114211
42124212
``__builtin_clzg`` (respectively ``__builtin_ctzg``) returns the number of
42134213
leading (respectively trailing) 0 bits in the first argument. The first argument
4214-
can be of any unsigned integer type.
4214+
can be of any unsigned integer type or fixed boolean vector.
4215+
4216+
For boolean vectors, these builtins interpret the vector like a bit-field where
4217+
the ith element of the vector is bit i of the bit-field, counting from the
4218+
least significant end. ``__builtin_clzg`` returns the number of zero elements at
4219+
the end of the vector, while ``__builtin_ctzg`` returns the number of zero
4220+
elements at the start of the vector.
42154221
42164222
If the first argument is 0 and an optional second argument of ``int`` type is
42174223
provided, then the second argument is returned. If the first argument is 0, but

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ Non-comprehensive list of changes in this release
157157
- Added ``__builtin_masked_load`` and ``__builtin_masked_store`` for conditional
158158
memory loads from vectors. Binds to the LLVM intrinsic of the same name.
159159

160+
- The ``__builtin_popcountg``, ``__builtin_ctzg``, and ``__builtin_clzg``
161+
functions now accept fixed-size boolean vectors.
162+
160163
- Use of ``__has_feature`` to detect the ``ptrauth_qualifier`` and ``ptrauth_intrinsics``
161164
features has been deprecated, and is restricted to the arm64e target only. The
162165
correct method to check for these features is to test for the ``__PTRAUTH__``

clang/lib/AST/ByteCode/Descriptor.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,25 @@ static void dtorRecord(Block *B, std::byte *Ptr, const Descriptor *D) {
246246
destroyBase(B, Ptr, F.Desc, F.Offset);
247247
}
248248

249+
/// Whether a record needs its descriptor dtor function called.
250+
static bool needsRecordDtor(const Record *R) {
251+
for (const auto &B : R->bases()) {
252+
if (B.Desc->DtorFn)
253+
return true;
254+
}
255+
256+
for (const auto &F : R->fields()) {
257+
if (F.Desc->DtorFn)
258+
return true;
259+
}
260+
261+
for (const auto &V : R->virtual_bases()) {
262+
if (V.Desc->DtorFn)
263+
return true;
264+
}
265+
return false;
266+
}
267+
249268
static BlockCtorFn getCtorPrim(PrimType Type) {
250269
// Floating types are special. They are primitives, but need their
251270
// constructor called.
@@ -336,7 +355,7 @@ Descriptor::Descriptor(const DeclTy &D, const Type *SourceTy,
336355
AllocSize(std::max<size_t>(alignof(void *), Size) + MDSize),
337356
ElemDesc(Elem), IsConst(IsConst), IsMutable(IsMutable),
338357
IsTemporary(IsTemporary), IsArray(true), CtorFn(ctorArrayDesc),
339-
DtorFn(dtorArrayDesc) {
358+
DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) {
340359
assert(Source && "Missing source");
341360
}
342361

@@ -347,7 +366,7 @@ Descriptor::Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize MD,
347366
Size(UnknownSizeMark), MDSize(MD.value_or(0)),
348367
AllocSize(MDSize + alignof(void *)), ElemDesc(Elem), IsConst(true),
349368
IsMutable(false), IsTemporary(IsTemporary), IsArray(true),
350-
CtorFn(ctorArrayDesc), DtorFn(dtorArrayDesc) {
369+
CtorFn(ctorArrayDesc), DtorFn(Elem->DtorFn ? dtorArrayDesc : nullptr) {
351370
assert(Source && "Missing source");
352371
}
353372

@@ -359,7 +378,7 @@ Descriptor::Descriptor(const DeclTy &D, const Record *R, MetadataSize MD,
359378
Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
360379
ElemRecord(R), IsConst(IsConst), IsMutable(IsMutable),
361380
IsTemporary(IsTemporary), IsVolatile(IsVolatile), CtorFn(ctorRecord),
362-
DtorFn(dtorRecord) {
381+
DtorFn(needsRecordDtor(R) ? dtorRecord : nullptr) {
363382
assert(Source && "Missing source");
364383
}
365384

clang/lib/AST/ByteCode/Integral.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,11 @@ template <unsigned Bits, bool Signed> class Integral final {
318318
template <typename T> static bool CheckMulUB(T A, T B, T &R) {
319319
if constexpr (std::is_signed_v<T>) {
320320
return llvm::MulOverflow<T>(A, B, R);
321+
} else if constexpr (sizeof(T) < sizeof(int)) {
322+
// Silly integer promotion rules will convert both A and B to int,
323+
// even it T is unsigned. Prevent that by manually casting to uint first.
324+
R = static_cast<T>(static_cast<unsigned>(A) * static_cast<unsigned>(B));
325+
return false;
321326
} else {
322327
R = A * B;
323328
return false;

clang/lib/AST/ByteCode/Interp.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,17 +1207,15 @@ static bool runRecordDestructor(InterpState &S, CodePtr OpPC,
12071207
}
12081208

12091209
// Destructor of this record.
1210-
if (const CXXDestructorDecl *Dtor = R->getDestructor();
1211-
Dtor && !Dtor->isTrivial()) {
1212-
const Function *DtorFunc = S.getContext().getOrCreateFunction(Dtor);
1213-
if (!DtorFunc)
1214-
return false;
1210+
const CXXDestructorDecl *Dtor = R->getDestructor();
1211+
assert(Dtor);
1212+
assert(!Dtor->isTrivial());
1213+
const Function *DtorFunc = S.getContext().getOrCreateFunction(Dtor);
1214+
if (!DtorFunc)
1215+
return false;
12151216

1216-
S.Stk.push<Pointer>(BasePtr);
1217-
if (!Call(S, OpPC, DtorFunc, 0))
1218-
return false;
1219-
}
1220-
return true;
1217+
S.Stk.push<Pointer>(BasePtr);
1218+
return Call(S, OpPC, DtorFunc, 0);
12211219
}
12221220

12231221
static bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B) {
@@ -1229,6 +1227,9 @@ static bool RunDestructors(InterpState &S, CodePtr OpPC, const Block *B) {
12291227

12301228
assert(Desc->isRecord() || Desc->isCompositeArray());
12311229

1230+
if (Desc->hasTrivialDtor())
1231+
return true;
1232+
12321233
if (Desc->isCompositeArray()) {
12331234
unsigned N = Desc->getNumElems();
12341235
if (N == 0)

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 84 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,22 @@ static void diagnoseNonConstexprBuiltin(InterpState &S, CodePtr OpPC,
141141
S.CCEDiag(Loc, diag::note_invalid_subexpr_in_const_expr);
142142
}
143143

144+
static llvm::APSInt convertBoolVectorToInt(const Pointer &Val) {
145+
assert(Val.getFieldDesc()->isPrimitiveArray() &&
146+
Val.getFieldDesc()->getElemQualType()->isBooleanType() &&
147+
"Not a boolean vector");
148+
unsigned NumElems = Val.getNumElems();
149+
150+
// Each element is one bit, so create an integer with NumElts bits.
151+
llvm::APSInt Result(NumElems, 0);
152+
for (unsigned I = 0; I != NumElems; ++I) {
153+
if (Val.elem<bool>(I))
154+
Result.setBit(I);
155+
}
156+
157+
return Result;
158+
}
159+
144160
static bool interp__builtin_is_constant_evaluated(InterpState &S, CodePtr OpPC,
145161
const InterpFrame *Frame,
146162
const CallExpr *Call) {
@@ -643,8 +659,14 @@ static bool interp__builtin_abs(InterpState &S, CodePtr OpPC,
643659
static bool interp__builtin_popcount(InterpState &S, CodePtr OpPC,
644660
const InterpFrame *Frame,
645661
const CallExpr *Call) {
646-
PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
647-
APSInt Val = popToAPSInt(S.Stk, ArgT);
662+
APSInt Val;
663+
if (Call->getArg(0)->getType()->isExtVectorBoolType()) {
664+
const Pointer &Arg = S.Stk.pop<Pointer>();
665+
Val = convertBoolVectorToInt(Arg);
666+
} else {
667+
PrimType ArgT = *S.getContext().classify(Call->getArg(0)->getType());
668+
Val = popToAPSInt(S.Stk, ArgT);
669+
}
648670
pushInteger(S, Val.popcount(), Call->getType());
649671
return true;
650672
}
@@ -940,8 +962,14 @@ static bool interp__builtin_clz(InterpState &S, CodePtr OpPC,
940962
PrimType FallbackT = *S.getContext().classify(Call->getArg(1));
941963
Fallback = popToAPSInt(S.Stk, FallbackT);
942964
}
943-
PrimType ValT = *S.getContext().classify(Call->getArg(0));
944-
const APSInt &Val = popToAPSInt(S.Stk, ValT);
965+
APSInt Val;
966+
if (Call->getArg(0)->getType()->isExtVectorBoolType()) {
967+
const Pointer &Arg = S.Stk.pop<Pointer>();
968+
Val = convertBoolVectorToInt(Arg);
969+
} else {
970+
PrimType ValT = *S.getContext().classify(Call->getArg(0));
971+
Val = popToAPSInt(S.Stk, ValT);
972+
}
945973

946974
// When the argument is 0, the result of GCC builtins is undefined, whereas
947975
// for Microsoft intrinsics, the result is the bit-width of the argument.
@@ -971,8 +999,14 @@ static bool interp__builtin_ctz(InterpState &S, CodePtr OpPC,
971999
PrimType FallbackT = *S.getContext().classify(Call->getArg(1));
9721000
Fallback = popToAPSInt(S.Stk, FallbackT);
9731001
}
974-
PrimType ValT = *S.getContext().classify(Call->getArg(0));
975-
const APSInt &Val = popToAPSInt(S.Stk, ValT);
1002+
APSInt Val;
1003+
if (Call->getArg(0)->getType()->isExtVectorBoolType()) {
1004+
const Pointer &Arg = S.Stk.pop<Pointer>();
1005+
Val = convertBoolVectorToInt(Arg);
1006+
} else {
1007+
PrimType ValT = *S.getContext().classify(Call->getArg(0));
1008+
Val = popToAPSInt(S.Stk, ValT);
1009+
}
9761010

9771011
if (Val == 0) {
9781012
if (Fallback) {
@@ -2514,9 +2548,9 @@ static bool interp__builtin_is_within_lifetime(InterpState &S, CodePtr OpPC,
25142548
return true;
25152549
}
25162550

2517-
static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
2518-
const CallExpr *Call,
2519-
unsigned BuiltinID) {
2551+
static bool interp__builtin_elementwise_int_binop(InterpState &S, CodePtr OpPC,
2552+
const CallExpr *Call,
2553+
unsigned BuiltinID) {
25202554
assert(Call->getNumArgs() == 2);
25212555

25222556
// Single integer case.
@@ -2553,6 +2587,8 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
25532587
const Pointer &LHS = S.Stk.pop<Pointer>();
25542588
const Pointer &Dst = S.Stk.peek<Pointer>();
25552589
PrimType ElemT = *S.getContext().classify(VT->getElementType());
2590+
bool DestUnsigned =
2591+
VT->getElementType()->isUnsignedIntegerOrEnumerationType();
25562592
unsigned NumElems = VT->getNumElements();
25572593
for (unsigned I = 0; I != NumElems; ++I) {
25582594
APSInt Elem1;
@@ -2586,6 +2622,34 @@ static bool interp__builtin_elementwise_sat(InterpState &S, CodePtr OpPC,
25862622
Result = APSInt(llvm::APIntOps::mulhs(Elem1, Elem2),
25872623
/*isUnsigned=*/false);
25882624
break;
2625+
case clang::X86::BI__builtin_ia32_psllv2di:
2626+
case clang::X86::BI__builtin_ia32_psllv4di:
2627+
case clang::X86::BI__builtin_ia32_psllv4si:
2628+
case clang::X86::BI__builtin_ia32_psllv8si:
2629+
if (Elem2.uge(Elem2.getBitWidth())) {
2630+
Result = APSInt(APInt::getZero(Elem2.getBitWidth()), DestUnsigned);
2631+
break;
2632+
}
2633+
Result = APSInt(Elem1.shl(Elem2.getZExtValue()), DestUnsigned);
2634+
break;
2635+
case clang::X86::BI__builtin_ia32_psrav4si:
2636+
case clang::X86::BI__builtin_ia32_psrav8si:
2637+
if (Elem2.uge(Elem2.getBitWidth())) {
2638+
Result = APSInt(Elem1.ashr(Elem2.getBitWidth() - 1), DestUnsigned);
2639+
break;
2640+
}
2641+
Result = APSInt(Elem1.ashr(Elem2.getZExtValue()), DestUnsigned);
2642+
break;
2643+
case clang::X86::BI__builtin_ia32_psrlv2di:
2644+
case clang::X86::BI__builtin_ia32_psrlv4di:
2645+
case clang::X86::BI__builtin_ia32_psrlv4si:
2646+
case clang::X86::BI__builtin_ia32_psrlv8si:
2647+
if (Elem2.uge(Elem2.getBitWidth())) {
2648+
Result = APSInt(APInt::getZero(Elem2.getBitWidth()), DestUnsigned);
2649+
break;
2650+
}
2651+
Result = APSInt(Elem1.lshr(Elem2.getZExtValue()), DestUnsigned);
2652+
break;
25892653
default:
25902654
llvm_unreachable("Wrong builtin ID");
25912655
}
@@ -3232,7 +3296,17 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
32323296
case clang::X86::BI__builtin_ia32_pmulhw128:
32333297
case clang::X86::BI__builtin_ia32_pmulhw256:
32343298
case clang::X86::BI__builtin_ia32_pmulhw512:
3235-
return interp__builtin_elementwise_sat(S, OpPC, Call, BuiltinID);
3299+
case clang::X86::BI__builtin_ia32_psllv2di:
3300+
case clang::X86::BI__builtin_ia32_psllv4di:
3301+
case clang::X86::BI__builtin_ia32_psllv4si:
3302+
case clang::X86::BI__builtin_ia32_psllv8si:
3303+
case clang::X86::BI__builtin_ia32_psrav4si:
3304+
case clang::X86::BI__builtin_ia32_psrav8si:
3305+
case clang::X86::BI__builtin_ia32_psrlv2di:
3306+
case clang::X86::BI__builtin_ia32_psrlv4di:
3307+
case clang::X86::BI__builtin_ia32_psrlv4si:
3308+
case clang::X86::BI__builtin_ia32_psrlv8si:
3309+
return interp__builtin_elementwise_int_binop(S, OpPC, Call, BuiltinID);
32363310

32373311
case Builtin::BI__builtin_elementwise_max:
32383312
case Builtin::BI__builtin_elementwise_min:

clang/lib/AST/ByteCode/Program.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ unsigned Program::createGlobalString(const StringLiteral *S, const Expr *Base) {
101101
}
102102
}
103103
}
104-
Ptr.initialize();
104+
Ptr.initializeAllElements();
105105

106106
return GlobalIndex;
107107
}

clang/lib/AST/ExprConstant.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11255,6 +11255,24 @@ static bool EvaluateVector(const Expr* E, APValue& Result, EvalInfo &Info) {
1125511255
return VectorExprEvaluator(Info, Result).Visit(E);
1125611256
}
1125711257

11258+
static llvm::APInt ConvertBoolVectorToInt(const APValue &Val) {
11259+
assert(Val.isVector() && "expected vector APValue");
11260+
unsigned NumElts = Val.getVectorLength();
11261+
11262+
// Each element is one bit, so create an integer with NumElts bits.
11263+
llvm::APInt Result(NumElts, 0);
11264+
11265+
for (unsigned I = 0; I < NumElts; ++I) {
11266+
const APValue &Elt = Val.getVectorElt(I);
11267+
assert(Elt.isInt() && "expected integer element in bool vector");
11268+
11269+
if (Elt.getInt().getBoolValue())
11270+
Result.setBit(I);
11271+
}
11272+
11273+
return Result;
11274+
}
11275+
1125811276
bool VectorExprEvaluator::VisitCastExpr(const CastExpr *E) {
1125911277
const VectorType *VTy = E->getType()->castAs<VectorType>();
1126011278
unsigned NElts = VTy->getNumElements();
@@ -13442,8 +13460,14 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1344213460
case Builtin::BI__lzcnt:
1344313461
case Builtin::BI__lzcnt64: {
1344413462
APSInt Val;
13445-
if (!EvaluateInteger(E->getArg(0), Val, Info))
13463+
if (E->getArg(0)->getType()->isExtVectorBoolType()) {
13464+
APValue Vec;
13465+
if (!EvaluateVector(E->getArg(0), Vec, Info))
13466+
return false;
13467+
Val = ConvertBoolVectorToInt(Vec);
13468+
} else if (!EvaluateInteger(E->getArg(0), Val, Info)) {
1344613469
return false;
13470+
}
1344713471

1344813472
std::optional<APSInt> Fallback;
1344913473
if ((BuiltinOp == Builtin::BI__builtin_clzg ||
@@ -13528,8 +13552,14 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1352813552
case Builtin::BI__builtin_ctzg:
1352913553
case Builtin::BI__builtin_elementwise_cttz: {
1353013554
APSInt Val;
13531-
if (!EvaluateInteger(E->getArg(0), Val, Info))
13555+
if (E->getArg(0)->getType()->isExtVectorBoolType()) {
13556+
APValue Vec;
13557+
if (!EvaluateVector(E->getArg(0), Vec, Info))
13558+
return false;
13559+
Val = ConvertBoolVectorToInt(Vec);
13560+
} else if (!EvaluateInteger(E->getArg(0), Val, Info)) {
1353213561
return false;
13562+
}
1353313563

1353413564
std::optional<APSInt> Fallback;
1353513565
if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
@@ -13744,8 +13774,14 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
1374413774
case Builtin::BI__popcnt:
1374513775
case Builtin::BI__popcnt64: {
1374613776
APSInt Val;
13747-
if (!EvaluateInteger(E->getArg(0), Val, Info))
13777+
if (E->getArg(0)->getType()->isExtVectorBoolType()) {
13778+
APValue Vec;
13779+
if (!EvaluateVector(E->getArg(0), Vec, Info))
13780+
return false;
13781+
Val = ConvertBoolVectorToInt(Vec);
13782+
} else if (!EvaluateInteger(E->getArg(0), Val, Info)) {
1374813783
return false;
13784+
}
1374913785

1375013786
return Success(Val.popcount(), E);
1375113787
}

0 commit comments

Comments
 (0)