================
@@ -11618,6 +11618,99 @@ static bool evalPackBuiltin(const CallExpr *E, 
EvalInfo &Info, APValue &Result,
   return true;
 }
 
+static bool evalShuffleGeneric(EvalInfo &Info, const CallExpr *Call,
+                               APValue &Out,
+                               llvm::function_ref<std::pair<unsigned, 
unsigned>(
+                                   unsigned, unsigned, unsigned)>
+                                   GetSourceIndex,
+                               bool IsSingleSrc) {
+
+  const auto *VT = Call->getType()->getAs<VectorType>();
+  if (!VT)
+    return false;
+
+  QualType MaskType = Call->getArg(IsSingleSrc ? 1 : 2)->getType();
+  bool IsMaskVector = MaskType->isVectorType();
+
+  unsigned ShuffleMask = 0;
+  APValue MaskVec;
+  if (IsMaskVector) {
+    if (!EvaluateAsRValue(Info, Call->getArg(IsSingleSrc ? 1 : 2), MaskVec))
+      return false;
+  } else {
+    APSInt MaskImm;
+    if (!EvaluateInteger(Call->getArg(IsSingleSrc ? 1 : 2), MaskImm, Info))
+      return false;
+    ShuffleMask = static_cast<unsigned>(MaskImm.getZExtValue());
+  }
+
+  APValue A, B;
+  if (IsSingleSrc) {
+    if (!EvaluateAsRValue(Info, Call->getArg(0), A))
+      return false;
+    B = A;
+  } else {
+    if (!EvaluateAsRValue(Info, Call->getArg(0), A) ||
+        !EvaluateAsRValue(Info, Call->getArg(1), B))
+      return false;
+  }
+
+  QualType ElemT = VT->getElementType();
+  unsigned ElemBits = Info.Ctx.getTypeSize(ElemT);
+  unsigned NumElts = VT->getNumElements();
+
+  SmallVector<APValue, 16> ResultElements;
+  ResultElements.reserve(NumElts);
+
+  for (unsigned DstIdx = 0; DstIdx != NumElts; ++DstIdx) {
+    if (IsMaskVector) {
+      APValue CtlVal = MaskVec.getVectorElt(DstIdx);
+      APSInt CtlByte = CtlVal.getInt();
+      uint8_t Control = static_cast<uint8_t>(CtlByte.getZExtValue());
+
+      if (Control & 0x80) {
+        APValue Zero(Info.Ctx.MakeIntValue(0, ElemT));
+        ResultElements.push_back(Zero);
+        continue;
+      }
+      ShuffleMask = Control;
+    }
+
+    auto [SrcVecIdx, SrcIdx] = GetSourceIndex(DstIdx, ShuffleMask, ElemBits);
+    const APValue &Src = (SrcVecIdx == 0) ? A : B;
+    ResultElements.push_back(Src.getVectorElt(SrcIdx));
+  }
+
+  Out = APValue(ResultElements.data(), ResultElements.size());
+  return true;
+}
+
+static bool evalShufpspdBuiltin(EvalInfo &Info, const CallExpr *Call,
----------------
RKSimon wrote:

Similar to interpbuiltin - split the shufps/pd callbacks and this should allow 
us to avoid the evalShufpspdBuiltin wrapper entirely.

https://github.com/llvm/llvm-project/pull/164078
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to