================
@@ -4189,6 +4189,56 @@ static bool interp__builtin_ia32_gfni_mul(InterpState 
&S, CodePtr OpPC,
   return true;
 }
 
+static bool interp__builtin_ia32_vpdp(InterpState &S, CodePtr OpPC,
+                                      const CallExpr *Call,
+                                      bool IsSaturating) {
+  const auto *SrcVecT = Call->getArg(0)->getType()->castAs<VectorType>();
+  const auto *OpAVecT = Call->getArg(1)->getType()->castAs<VectorType>();
+  const auto *OpBVecT = Call->getArg(2)->getType()->castAs<VectorType>();
+
+  assert(OpAVecT->getNumElements() == OpBVecT->getNumElements());
+
+  unsigned NumSrcElts = SrcVecT->getNumElements();
+  unsigned NumOperandElts = OpAVecT->getNumElements();
+  unsigned EltsPerLane = NumOperandElts / NumSrcElts;
+
+  PrimType SrcElemT = *S.getContext().classify(SrcVecT->getElementType());
+  PrimType OpAElemT = *S.getContext().classify(OpAVecT->getElementType());
+  PrimType OpBElemT = *S.getContext().classify(OpBVecT->getElementType());
+
+  const Pointer &OpBPtr = S.Stk.pop<Pointer>();
+  const Pointer &OpAPtr = S.Stk.pop<Pointer>();
+  const Pointer &SrcPtr = S.Stk.pop<Pointer>();
+  const Pointer &Dst = S.Stk.peek<Pointer>();
+
+  for (unsigned I = 0; I != NumSrcElts; ++I) {
+    APSInt Acc;
+    INT_TYPE_SWITCH_NO_BOOL(SrcElemT, { Acc = SrcPtr.elem<T>(I).toAPSInt(); });
+    Acc = Acc.sext(64);
+    for (unsigned J = 0; J != EltsPerLane; ++J) {
+      APSInt OpA, OpB;
+      INT_TYPE_SWITCH_NO_BOOL(OpAElemT, {
+        OpA = OpAPtr.elem<T>(EltsPerLane * I + J).toAPSInt();
+        });
+      INT_TYPE_SWITCH_NO_BOOL(OpBElemT, {
+               OpB = OpBPtr.elem<T>(EltsPerLane * I + J).toAPSInt();
+               });
+         OpA = APSInt(OpA.extend(64), false);
+      OpB = APSInt(OpB.extend(64), false);
+      Acc += OpA * OpB;
+    }
+    if (IsSaturating) {
+      Acc = APSInt(Acc.truncSSat(32), false);
+    } else {
+         Acc = APSInt(Acc.trunc(32), false);
+       }
----------------
AkashDeoNU wrote:

Yes! The clarification about the `Src` / `Dst` type difference helps. They are 
not allowed to be different types. So I now check that they are the same type, 
and I am properly casting `Dst`. 

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

Reply via email to