diff options
| author | NagaChaitanya Vellanki <pnagato@protonmail.com> | 2025-11-22 09:19:27 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-11-22 17:19:27 +0000 |
| commit | 456ca91815c3fdb60b5ca695c8bb05b75016a343 (patch) | |
| tree | 0b0d2b9ce76145f9f0ac52f926af89e1f5db1f27 /clang/lib/AST/ExprConstant.cpp | |
| parent | 126462035a1eb7adeb97f6beac48b6bddac65d09 (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.cpp | 42 |
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); + } } } |
