[llvm] [llubi] Implement vector reduction/manipulation intrinsics (PR #194345)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 27 05:23:05 PDT 2026
================
@@ -683,6 +691,225 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
}
});
}
+ case Intrinsic::vector_reduce_add:
+ case Intrinsic::vector_reduce_mul:
+ case Intrinsic::vector_reduce_and:
+ case Intrinsic::vector_reduce_or:
+ case Intrinsic::vector_reduce_xor:
+ case Intrinsic::vector_reduce_smax:
+ case Intrinsic::vector_reduce_smin:
+ case Intrinsic::vector_reduce_umax:
+ case Intrinsic::vector_reduce_umin: {
+ std::optional<APInt> Res;
+ for (const auto &V : Args[0].asAggregate()) {
+ if (V.isPoison()) {
+ Res.reset();
+ break;
+ }
+ const auto &IntV = V.asInteger();
+ if (!Res) {
+ Res = IntV;
+ continue;
+ }
+ switch (IID) {
+ case Intrinsic::vector_reduce_add:
+ *Res += IntV;
+ break;
+ case Intrinsic::vector_reduce_mul:
+ *Res *= IntV;
+ break;
+ case Intrinsic::vector_reduce_and:
+ *Res &= IntV;
+ break;
+ case Intrinsic::vector_reduce_or:
+ *Res |= IntV;
+ break;
+ case Intrinsic::vector_reduce_xor:
+ *Res ^= IntV;
+ break;
+ case Intrinsic::vector_reduce_smax:
+ *Res = APIntOps::smax(*Res, IntV);
+ break;
+ case Intrinsic::vector_reduce_smin:
+ *Res = APIntOps::smin(*Res, IntV);
+ break;
+ case Intrinsic::vector_reduce_umax:
+ *Res = APIntOps::umax(*Res, IntV);
+ break;
+ case Intrinsic::vector_reduce_umin:
+ *Res = APIntOps::umin(*Res, IntV);
+ break;
+ default:
+ llvm_unreachable("Unexpected intrinsic ID");
+ }
+ }
+ return Res ? *Res : AnyValue::poison();
+ }
+ case Intrinsic::vector_insert: {
+ if (Args[2].isPoison()) {
+ reportImmediateUB("vector_insert with poison index");
+ return AnyValue::poison();
+ }
+ const auto &Vec = Args[0].asAggregate();
+ const auto &SubVec = Args[1].asAggregate();
+ const auto &Idx = Args[2].asInteger();
+ const uint64_t Offset = Idx.getZExtValue();
+ if (Offset + SubVec.size() > Vec.size())
+ return AnyValue::poison();
+ std::vector<AnyValue> Res;
+ Res.reserve(Vec.size());
+ for (size_t I = 0; I != Vec.size(); ++I) {
+ if (I >= Offset && I < Offset + SubVec.size())
+ Res.push_back(SubVec[I - Offset]);
+ else
+ Res.push_back(Vec[I]);
+ }
+ return std::move(Res);
+ }
+ case Intrinsic::vector_extract: {
+ if (Args[1].isPoison()) {
+ reportImmediateUB("vector_extract with poison index");
+ return AnyValue::poison();
+ }
+ const auto &Vec = Args[0].asAggregate();
+ const auto &Idx = Args[1].asInteger();
+ const uint64_t Offset = Idx.getZExtValue();
+ const uint64_t DstSize = cast<FixedVectorType>(RetTy)->getNumElements();
+ if (Offset + DstSize > Vec.size())
+ return AnyValue::poison();
+ return std::vector(Vec.begin() + Offset, Vec.begin() + Offset + DstSize);
+ }
+ case Intrinsic::vector_reverse: {
+ auto Vec = Args[0].asAggregate();
+ std::reverse(Vec.begin(), Vec.end());
+ return std::move(Vec);
+ }
+ case Intrinsic::vector_deinterleave2:
+ case Intrinsic::vector_deinterleave3:
+ case Intrinsic::vector_deinterleave4:
+ case Intrinsic::vector_deinterleave5:
+ case Intrinsic::vector_deinterleave6:
+ case Intrinsic::vector_deinterleave7:
+ case Intrinsic::vector_deinterleave8: {
+ const unsigned Factor = [IID]() -> unsigned {
+ switch (IID) {
+ case Intrinsic::vector_deinterleave2:
+ return 2;
+ case Intrinsic::vector_deinterleave3:
+ return 3;
+ case Intrinsic::vector_deinterleave4:
+ return 4;
+ case Intrinsic::vector_deinterleave5:
+ return 5;
+ case Intrinsic::vector_deinterleave6:
+ return 6;
+ case Intrinsic::vector_deinterleave7:
+ return 7;
+ case Intrinsic::vector_deinterleave8:
+ return 8;
+ default:
+ llvm_unreachable("Unexpected intrinsic ID");
+ }
+ }();
+ const auto &Vec = Args[0].asAggregate();
+ std::vector<std::vector<AnyValue>> Res(Factor);
+ for (auto &SubVec : Res)
+ SubVec.reserve(Vec.size() / Factor);
+ for (const auto &[I, V] : enumerate(Vec))
+ Res[I % Factor].push_back(V);
+
+ std::vector<AnyValue> AggRes;
+ AggRes.reserve(Factor);
+ for (auto &SubVec : Res)
+ AggRes.emplace_back(std::move(SubVec));
+ return AnyValue(std::move(AggRes));
+ }
+ case Intrinsic::vector_interleave2:
+ case Intrinsic::vector_interleave3:
+ case Intrinsic::vector_interleave4:
+ case Intrinsic::vector_interleave5:
+ case Intrinsic::vector_interleave6:
+ case Intrinsic::vector_interleave7:
+ case Intrinsic::vector_interleave8: {
+ const unsigned Factor = [IID]() -> unsigned {
----------------
nikic wrote:
getInterleaveIntrinsicFactor
https://github.com/llvm/llvm-project/pull/194345
More information about the llvm-commits
mailing list