[llvm] [llubi] Implement experimental vector intrinsics (PR #206899)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 4 11:03:48 PDT 2026
================
@@ -1629,6 +1727,159 @@ class InstExecutor : public InstVisitor<InstExecutor, void>,
case Intrinsic::experimental_noalias_scope_decl:
// FIXME: Not implemented yet. Currently it acts as a noop.
return AnyValue();
+ case Intrinsic::experimental_cttz_elts: {
+ auto *IsZeroPoisonC = cast<ConstantInt>(CB.getArgOperand(1));
+ const bool IsZeroPoison = IsZeroPoisonC->isOne();
+
+ const auto &Vec = Args[0].asAggregate();
+ const unsigned RetBW = RetTy->getIntegerBitWidth();
+
+ if (!isUIntN(RetBW, Vec.size()))
+ return AnyValue::poison();
+
+ uint64_t Count = 0;
+ for (const AnyValue &V : Vec) {
+ if (V.isPoison())
+ return AnyValue::poison();
+ if (!V.asInteger().isZero())
+ break;
+ ++Count;
+ }
+
+ if (Count == Vec.size() && IsZeroPoison)
+ return AnyValue::poison();
+ return APInt(RetBW, Count);
+ }
+ case Intrinsic::experimental_get_vector_length: {
+ auto *VFC = cast<ConstantInt>(CB.getArgOperand(1));
+ auto *ScalableC = cast<ConstantInt>(CB.getArgOperand(2));
+
+ if (Args[0].isPoison())
+ return AnyValue::poison();
+
+ const APInt &Cnt = Args[0].asInteger();
+ const uint64_t VF = VFC->getZExtValue();
+ const bool Scalable = ScalableC->isOne();
+
+ const uint64_t MaxLanes = Ctx.getEVL(ElementCount::get(VF, Scalable));
+
+ uint64_t Res = 0;
+ if (!Cnt.isZero()) {
+ if (Cnt.getActiveBits() <= 64 && Cnt.getZExtValue() <= MaxLanes) {
+ Res = Cnt.getZExtValue();
+ } else {
+ auto ceilUDiv = [](const APInt &N, const APInt &D) {
+ APInt Q = N.udiv(D);
+ if (!N.urem(D).isZero())
+ ++Q;
+ return Q;
+ };
+
+ APInt Max(Cnt.getBitWidth(), MaxLanes);
+ APInt NumIters = ceilUDiv(Cnt, Max);
----------------
dtcxzyw wrote:
Use `APIntOps::RoundingUDiv`.
https://github.com/llvm/llvm-project/pull/206899
More information about the llvm-commits
mailing list