[llvm] [VPlan] Optimize LastActiveLane to EVL - 1 (PR #169766)

Luke Lau via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 26 23:30:01 PST 2025


================
@@ -2787,13 +2788,22 @@ static VPRecipeBase *optimizeMaskToEVL(VPValue *HeaderMask,
             m_Select(m_Specific(HeaderMask), m_VPValue(LHS), m_VPValue(RHS))))
     return new VPWidenIntrinsicRecipe(
         Intrinsic::vp_merge, {Plan->getTrue(), LHS, RHS, &EVL},
-        TypeInfo.inferScalarType(LHS), {}, {}, CurRecipe.getDebugLoc());
+        TypeInfo.inferScalarType(LHS), {}, {}, DL);
 
   if (match(&CurRecipe, m_Select(m_RemoveMask(HeaderMask, Mask), m_VPValue(LHS),
                                  m_VPValue(RHS))))
     return new VPWidenIntrinsicRecipe(
         Intrinsic::vp_merge, {Mask, LHS, RHS, &EVL},
-        TypeInfo.inferScalarType(LHS), {}, {}, CurRecipe.getDebugLoc());
+        TypeInfo.inferScalarType(LHS), {}, {}, DL);
+
+  if (match(&CurRecipe, m_LastActiveLane(m_Specific(HeaderMask)))) {
+    Type *I64Ty = IntegerType::getInt64Ty(Plan->getContext());
+    VPValue *Zext = VPBuilder(&CurRecipe)
+                        .createScalarCast(Instruction::ZExt, &EVL, I64Ty, DL);
----------------
lukel97 wrote:

Yeah, FirstActiveLane and LastActiveLane only generate i64s:

```c++
  case VPInstruction::FirstActiveLane: {
    if (getNumOperands() == 1) {
      Value *Mask = State.get(getOperand(0));
      return Builder.CreateCountTrailingZeroElems(Builder.getInt64Ty(), Mask,
                                                  /*ZeroIsPoison=*/false, Name);
    }
```

But I guess it would be good to not hardcode it here, changed to use TypeInfo.inferScalarType in 1cdacb6ef17503b21f396f445f6fd0dfce2ab579

https://github.com/llvm/llvm-project/pull/169766


More information about the llvm-commits mailing list