================
@@ -2735,6 +2735,160 @@ static bool interp__builtin_ia32_pmul(InterpState &S,
CodePtr OpPC,
return true;
}
+static bool interp_builtin_horizontal_int_binop(
+ InterpState &S, CodePtr OpPC, const CallExpr *Call,
+ llvm::function_ref<APInt(const APSInt &, const APSInt &)> Fn) {
+ assert(Call->getNumArgs() == 2);
+
+ assert(Call->getArg(0)->getType()->isVectorType() &&
+ Call->getArg(1)->getType()->isVectorType());
+ const auto *VT = Call->getArg(0)->getType()->castAs<VectorType>();
+ assert(VT->getElementType()->isIntegralOrEnumerationType());
+ PrimType ElemT = *S.getContext().classify(VT->getElementType());
+ bool DestUnsigned = Call->getType()->isUnsignedIntegerOrEnumerationType();
+
+ const Pointer &RHS = S.Stk.pop<Pointer>();
+ const Pointer &LHS = S.Stk.pop<Pointer>();
+ const Pointer &Dst = S.Stk.peek<Pointer>();
+
+ unsigned SourceLen = VT->getNumElements();
+ assert(SourceLen % 2 == 0 &&
+ Call->getArg(1)->getType()->castAs<VectorType>()->getNumElements() ==
+ SourceLen);
+ unsigned DstElem = 0;
+
+ for (unsigned I = 0; I != SourceLen; I += 2) {
----------------
RKSimon wrote:
```
for (unsigned Lane = 0; Lane != NumElts; Lane += EltsPerLane) {
for (unsigned I = 0; I != EltsPerLane; I += 2) {
INT_TYPE_SWITCH_NO_BOOL(ElemT, {
APSInt Elem1 = LHS.elem<T>(Lane + I).toAPSInt();
APSInt Elem2 = LHS.elem<T>(Lane + I + 1).toAPSInt();
Dst.elem<T>(Lane + I) = static_cast<T>(APSInt(Fn(Elem1, Elem2),
DestUnsigned));
});
}
for (unsigned I = 0; I != SrcPerLane; I += 2) {
INT_TYPE_SWITCH_NO_BOOL(ElemT, {
APSInt Elem1 = RLHS.elem<T>(Lane + I).toAPSInt();
APSInt Elem2 = RHS.elem<T>(Lane + I + 1).toAPSInt();
Dst.elem<T>(Lane + EltsPerLane + I) = static_cast<T>(APSInt(Fn(Elem1,
Elem2), DestUnsigned));
});
}
}
```
https://github.com/llvm/llvm-project/pull/156822
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits