[clang] [Headers][X86] VectorExprEvaluator::VisitCallExpr - allow SSE/AVX2/AVX512 pack intrinsics to be used in constexpr (PR #156003)
Shafik Yaghmour via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 29 10:40:19 PDT 2025
================
@@ -11599,6 +11599,89 @@ static bool handleVectorElementCast(EvalInfo &Info, const FPOptions FPO,
return false;
}
+enum class PackKind {
+ SSWB,
+ USWB,
+ SSDW,
+ USDW
+}; // 16→8 signed/unsigned; 32→16 signed/unsigned
+
+static bool evalPackBuiltin(const CallExpr *E, EvalInfo &Info, APValue &Result,
+ PackKind K) {
+ APValue L, R;
+ if (!EvaluateAsRValue(Info, E->getArg(0), L) ||
+ !EvaluateAsRValue(Info, E->getArg(1), R))
+ return false;
+
+ unsigned SrcBits = (K == PackKind::SSWB || K == PackKind::USWB) ? 16 : 32;
+ unsigned DstBits = SrcBits / 2;
+
+ unsigned NL = L.getVectorLength();
+ unsigned NR = R.getVectorLength();
+ if (NL == 0 || NR == 0 || NL != NR)
+ return false;
+
+ // Bounds for saturation (extended to SrcBits for compares).
+ APInt Lo = (K == PackKind::USWB || K == PackKind::USDW)
+ ? APInt(SrcBits, 0)
+ : APInt::getSignedMinValue(DstBits).sext(SrcBits);
+ APInt Hi = (K == PackKind::USWB || K == PackKind::USDW)
+ ? APInt::getMaxValue(DstBits).zext(SrcBits)
+ : APInt::getSignedMaxValue(DstBits).sext(SrcBits);
+
+ // Result element signedness follows the builtin's return vector element type.
+ QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
+ bool DestIsUnsigned = DestEltTy->isUnsignedIntegerType();
+
+ // Clamp one source element to the target range and narrow to DstBits.
+ auto clampOne = [&](const APSInt &X) -> APSInt {
+ APInt V = X;
+ if (V.getBitWidth() != SrcBits)
+ V = V.sextOrTrunc(SrcBits);
+
+ if (K == PackKind::USWB || K == PackKind::USDW) {
----------------
shafik wrote:
Please make sure to verify that you cover each branch, I see a lot of combination but I am sure we cover them all in the tests.
https://github.com/llvm/llvm-project/pull/156003
More information about the cfe-commits
mailing list