[llvm] [VPlan] Materialize VF and VFxUF using VPInstructions. (PR #152879)

David Sherwood via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 11 08:46:12 PDT 2025


================
@@ -3335,6 +3335,33 @@ void VPlanTransforms::materializeVectorTripCount(VPlan &Plan,
   VectorTC.replaceAllUsesWith(Res);
 }
 
+void VPlanTransforms::materializeVFAndVFxUF(VPlan &Plan, VPBasicBlock *VectorPH,
+                                            ElementCount VFEC) {
+  VPBuilder Builder(VectorPH, VectorPH->begin());
+  Type *TCTy = VPTypeAnalysis(Plan).inferScalarType(Plan.getTripCount());
+  VPValue &VF = Plan.getVF();
+  VPValue &VFxUF = Plan.getVFxUF();
+  if (VF.getNumUsers()) {
+    VPValue *RuntimeVF = Builder.createElementCount(TCTy, VFEC);
+    if (any_of(VF.users(), [&VF](VPUser *U) { return !U->usesScalars(&VF); })) {
+      auto *BC = Builder.createNaryOp(VPInstruction::Broadcast, RuntimeVF);
+      VF.replaceUsesWithIf(
+          BC, [&VF](VPUser &U, unsigned) { return !U.usesScalars(&VF); });
+    }
+    VF.replaceAllUsesWith(RuntimeVF);
+
+    VPValue *UF = Plan.getOrAddLiveIn(ConstantInt::get(TCTy, Plan.getUF()));
+    auto *MulByUF = Plan.getUF() == 1 ? RuntimeVF
----------------
david-arm wrote:

Perhaps I'm missing something, but it looked like these two pieces of code were calculating the same thing:

```
    VPValue *UF = Plan.getOrAddLiveIn(ConstantInt::get(TCTy, Plan.getUF()));
    VPValue *MulByUF =
        Plan.getUF() == 1
            ? RuntimeVF
            : Builder.createNaryOp(Instruction::Mul, {RuntimeVF, UF});
  }
```

and

```
  VPValue *RuntimeVFxUF = Builder.createElementCount(TCTy, VFEC * Plan.getUF());
```

The only difference seems to be that you're not using `createOverflowingOp` when multiplying the UF, whereas `Builder.createElementCount(TCTy, VFEC * Plan.getUF())` does.

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


More information about the llvm-commits mailing list