summaryrefslogtreecommitdiff
path: root/clang/lib/AST/ExprConstant.cpp
diff options
context:
space:
mode:
authorNagaChaitanya Vellanki <pnagato@protonmail.com>2025-11-22 09:19:27 -0800
committerGitHub <noreply@github.com>2025-11-22 17:19:27 +0000
commit456ca91815c3fdb60b5ca695c8bb05b75016a343 (patch)
tree0b0d2b9ce76145f9f0ac52f926af89e1f5db1f27 /clang/lib/AST/ExprConstant.cpp
parent126462035a1eb7adeb97f6beac48b6bddac65d09 (diff)
[Clang] VectorExprEvaluator::VisitCallExpr / InterpretBuiltin - Allow AVX512 VPSHUFBITQMB intrinsics to be used in constexpr (#168100)
Resolves #161337
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r--clang/lib/AST/ExprConstant.cpp42
1 files changed, 42 insertions, 0 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index ad1f49ce9b04..3b91678f7d40 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -16762,6 +16762,48 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
return Success(APValue(RetMask), E);
}
+ case X86::BI__builtin_ia32_vpshufbitqmb128_mask:
+ case X86::BI__builtin_ia32_vpshufbitqmb256_mask:
+ case X86::BI__builtin_ia32_vpshufbitqmb512_mask: {
+ assert(E->getNumArgs() == 3);
+
+ APValue Source, ShuffleMask;
+ APSInt ZeroMask;
+ if (!EvaluateVector(E->getArg(0), Source, Info) ||
+ !EvaluateVector(E->getArg(1), ShuffleMask, Info) ||
+ !EvaluateInteger(E->getArg(2), ZeroMask, Info))
+ return false;
+
+ assert(Source.getVectorLength() == ShuffleMask.getVectorLength());
+ assert(ZeroMask.getBitWidth() == Source.getVectorLength());
+
+ unsigned NumBytesInQWord = 8;
+ unsigned NumBitsInByte = 8;
+ unsigned NumBytes = Source.getVectorLength();
+ unsigned NumQWords = NumBytes / NumBytesInQWord;
+ unsigned RetWidth = ZeroMask.getBitWidth();
+ APSInt RetMask(llvm::APInt(RetWidth, 0), /*isUnsigned=*/true);
+
+ for (unsigned QWordId = 0; QWordId != NumQWords; ++QWordId) {
+ APInt SourceQWord(64, 0);
+ for (unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
+ uint64_t Byte = Source.getVectorElt(QWordId * NumBytesInQWord + ByteIdx)
+ .getInt()
+ .getZExtValue();
+ SourceQWord.insertBits(APInt(8, Byte & 0xFF), ByteIdx * NumBitsInByte);
+ }
+
+ for (unsigned ByteIdx = 0; ByteIdx != NumBytesInQWord; ++ByteIdx) {
+ unsigned SelIdx = QWordId * NumBytesInQWord + ByteIdx;
+ unsigned M =
+ ShuffleMask.getVectorElt(SelIdx).getInt().getZExtValue() & 0x3F;
+ if (ZeroMask[SelIdx]) {
+ RetMask.setBitVal(SelIdx, SourceQWord[M]);
+ }
+ }
+ }
+ return Success(APValue(RetMask), E);
+ }
}
}