diff options
author | Aditya Chaudhari <98672108+AdityaC4@users.noreply.github.com> | 2025-10-03 08:08:39 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-10-03 13:08:39 +0000 |
commit | 9e3bbbb049ea9ca2abcbf8e4b3ea39a8deb7c1e2 (patch) | |
tree | 5bb916393e43c82f34b548c8eff606abcccaa36e /clang/lib/AST/ExprConstant.cpp | |
parent | 6bdf2cb2024e3a1f9596189f567b13665a19d1b1 (diff) | |
download | llvm-9e3bbbb049ea9ca2abcbf8e4b3ea39a8deb7c1e2.zip llvm-9e3bbbb049ea9ca2abcbf8e4b3ea39a8deb7c1e2.tar.gz llvm-9e3bbbb049ea9ca2abcbf8e4b3ea39a8deb7c1e2.tar.bz2 |
[X86][Clang] VectorExprEvaluator::VisitCallExpr / InterpretBuiltin - allow element extraction/insertion intrinsics to be used in constexpr #159753 (#161302)
FIXES: #159753
Enable constexpr evaluation for X86 vector element extract/insert builtins. and adds corresponding tests
Index is masked with `(Idx & (NumElts - 1))`, matching existing CodeGen.
Diffstat (limited to 'clang/lib/AST/ExprConstant.cpp')
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index b706b14..81a5c2d 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -12235,6 +12235,41 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { return Success(APValue(ResultElements.data(), ResultElements.size()), E); } + + case clang::X86::BI__builtin_ia32_vec_set_v4hi: + case clang::X86::BI__builtin_ia32_vec_set_v16qi: + case clang::X86::BI__builtin_ia32_vec_set_v8hi: + case clang::X86::BI__builtin_ia32_vec_set_v4si: + case clang::X86::BI__builtin_ia32_vec_set_v2di: + case clang::X86::BI__builtin_ia32_vec_set_v32qi: + case clang::X86::BI__builtin_ia32_vec_set_v16hi: + case clang::X86::BI__builtin_ia32_vec_set_v8si: + case clang::X86::BI__builtin_ia32_vec_set_v4di: { + APValue VecVal; + APSInt Scalar, IndexAPS; + if (!EvaluateVector(E->getArg(0), VecVal, Info) || + !EvaluateInteger(E->getArg(1), Scalar, Info) || + !EvaluateInteger(E->getArg(2), IndexAPS, Info)) + return false; + + QualType ElemTy = E->getType()->castAs<VectorType>()->getElementType(); + unsigned ElemWidth = Info.Ctx.getIntWidth(ElemTy); + bool ElemUnsigned = ElemTy->isUnsignedIntegerOrEnumerationType(); + Scalar.setIsUnsigned(ElemUnsigned); + APSInt ElemAPS = Scalar.extOrTrunc(ElemWidth); + APValue ElemAV(ElemAPS); + + unsigned NumElems = VecVal.getVectorLength(); + unsigned Index = + static_cast<unsigned>(IndexAPS.getZExtValue() & (NumElems - 1)); + + SmallVector<APValue, 4> Elems; + Elems.reserve(NumElems); + for (unsigned ElemNum = 0; ElemNum != NumElems; ++ElemNum) + Elems.push_back(ElemNum == Index ? ElemAV : VecVal.getVectorElt(ElemNum)); + + return Success(APValue(Elems.data(), NumElems), E); + } } } @@ -14822,6 +14857,25 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, return HandleMaskBinOp( [](const APSInt &LHS, const APSInt &RHS) { return LHS + RHS; }); } + + case clang::X86::BI__builtin_ia32_vec_ext_v4hi: + case clang::X86::BI__builtin_ia32_vec_ext_v16qi: + case clang::X86::BI__builtin_ia32_vec_ext_v8hi: + case clang::X86::BI__builtin_ia32_vec_ext_v4si: + case clang::X86::BI__builtin_ia32_vec_ext_v2di: + case clang::X86::BI__builtin_ia32_vec_ext_v32qi: + case clang::X86::BI__builtin_ia32_vec_ext_v16hi: + case clang::X86::BI__builtin_ia32_vec_ext_v8si: + case clang::X86::BI__builtin_ia32_vec_ext_v4di: { + APValue Vec; + APSInt IdxAPS; + if (!EvaluateVector(E->getArg(0), Vec, Info) || + !EvaluateInteger(E->getArg(1), IdxAPS, Info)) + return false; + unsigned N = Vec.getVectorLength(); + unsigned Idx = static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1)); + return Success(Vec.getVectorElt(Idx).getInt(), E); + } } } @@ -16638,6 +16692,17 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { (void)Result.fusedMultiplyAdd(SourceY, SourceZ, RM); return true; } + + case clang::X86::BI__builtin_ia32_vec_ext_v4sf: { + APValue Vec; + APSInt IdxAPS; + if (!EvaluateVector(E->getArg(0), Vec, Info) || + !EvaluateInteger(E->getArg(1), IdxAPS, Info)) + return false; + unsigned N = Vec.getVectorLength(); + unsigned Idx = static_cast<unsigned>(IdxAPS.getZExtValue() & (N - 1)); + return Success(Vec.getVectorElt(Idx), E); + } } } |