@@ -11827,6 +11827,53 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
11827
11827
11828
11828
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
11829
11829
}
11830
+ case Builtin::BI__builtin_elementwise_ctlz:
11831
+ case Builtin::BI__builtin_elementwise_cttz: {
11832
+ APValue SourceLHS;
11833
+ std::optional<APValue> Fallback;
11834
+ if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS))
11835
+ return false;
11836
+ if (E->getNumArgs() > 1) {
11837
+ APValue FallbackTmp;
11838
+ if (!EvaluateAsRValue(Info, E->getArg(1), FallbackTmp))
11839
+ return false;
11840
+ Fallback = FallbackTmp;
11841
+ }
11842
+
11843
+ QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
11844
+ unsigned SourceLen = SourceLHS.getVectorLength();
11845
+ SmallVector<APValue, 4> ResultElements;
11846
+ ResultElements.reserve(SourceLen);
11847
+
11848
+ for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) {
11849
+ APSInt LHS = SourceLHS.getVectorElt(EltNum).getInt();
11850
+ if (!LHS) {
11851
+ // Without a fallback, a zero element is undefined
11852
+ if (!Fallback) {
11853
+ Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
11854
+ << /*IsTrailing=*/(E->getBuiltinCallee() ==
11855
+ Builtin::BI__builtin_elementwise_cttz);
11856
+ return false;
11857
+ }
11858
+ ResultElements.push_back(Fallback->getVectorElt(EltNum));
11859
+ continue;
11860
+ }
11861
+ switch (E->getBuiltinCallee()) {
11862
+ case Builtin::BI__builtin_elementwise_ctlz:
11863
+ ResultElements.push_back(APValue(
11864
+ APSInt(APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countl_zero()),
11865
+ DestEltTy->isUnsignedIntegerOrEnumerationType())));
11866
+ break;
11867
+ case Builtin::BI__builtin_elementwise_cttz:
11868
+ ResultElements.push_back(APValue(
11869
+ APSInt(APInt(Info.Ctx.getIntWidth(DestEltTy), LHS.countr_zero()),
11870
+ DestEltTy->isUnsignedIntegerOrEnumerationType())));
11871
+ break;
11872
+ }
11873
+ }
11874
+
11875
+ return Success(APValue(ResultElements.data(), ResultElements.size()), E);
11876
+ }
11830
11877
}
11831
11878
}
11832
11879
@@ -13382,6 +13429,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
13382
13429
case Builtin::BI__builtin_clzll:
13383
13430
case Builtin::BI__builtin_clzs:
13384
13431
case Builtin::BI__builtin_clzg:
13432
+ case Builtin::BI__builtin_elementwise_ctlz:
13385
13433
case Builtin::BI__lzcnt16: // Microsoft variants of count leading-zeroes
13386
13434
case Builtin::BI__lzcnt:
13387
13435
case Builtin::BI__lzcnt64: {
@@ -13390,7 +13438,9 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
13390
13438
return false;
13391
13439
13392
13440
std::optional<APSInt> Fallback;
13393
- if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) {
13441
+ if ((BuiltinOp == Builtin::BI__builtin_clzg ||
13442
+ BuiltinOp == Builtin::BI__builtin_elementwise_ctlz) &&
13443
+ E->getNumArgs() > 1) {
13394
13444
APSInt FallbackTemp;
13395
13445
if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info))
13396
13446
return false;
@@ -13408,6 +13458,11 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
13408
13458
BuiltinOp != Builtin::BI__lzcnt &&
13409
13459
BuiltinOp != Builtin::BI__lzcnt64;
13410
13460
13461
+ if (BuiltinOp == Builtin::BI__builtin_elementwise_ctlz) {
13462
+ Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13463
+ << /*IsTrailing=*/false;
13464
+ }
13465
+
13411
13466
if (ZeroIsUndefined)
13412
13467
return Error(E);
13413
13468
}
@@ -13462,13 +13517,16 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
13462
13517
case Builtin::BI__builtin_ctzl:
13463
13518
case Builtin::BI__builtin_ctzll:
13464
13519
case Builtin::BI__builtin_ctzs:
13465
- case Builtin::BI__builtin_ctzg: {
13520
+ case Builtin::BI__builtin_ctzg:
13521
+ case Builtin::BI__builtin_elementwise_cttz: {
13466
13522
APSInt Val;
13467
13523
if (!EvaluateInteger(E->getArg(0), Val, Info))
13468
13524
return false;
13469
13525
13470
13526
std::optional<APSInt> Fallback;
13471
- if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) {
13527
+ if ((BuiltinOp == Builtin::BI__builtin_ctzg ||
13528
+ BuiltinOp == Builtin::BI__builtin_elementwise_cttz) &&
13529
+ E->getNumArgs() > 1) {
13472
13530
APSInt FallbackTemp;
13473
13531
if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info))
13474
13532
return false;
@@ -13479,6 +13537,10 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
13479
13537
if (Fallback)
13480
13538
return Success(*Fallback, E);
13481
13539
13540
+ if (BuiltinOp == Builtin::BI__builtin_elementwise_cttz) {
13541
+ Info.FFDiag(E, diag::note_constexpr_countzeroes_zero)
13542
+ << /*IsTrailing=*/true;
13543
+ }
13482
13544
return Error(E);
13483
13545
}
13484
13546
0 commit comments