[llvm] [LV] Use index type for base pointer computation in convertToStridedAccesses (PR #201070)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 3 02:04:53 PDT 2026
================
@@ -7023,17 +7023,19 @@ void VPlanTransforms::convertToStridedAccesses(VPlan &Plan,
VPBuilder Builder(LoadR);
// Create the base pointer of strided access.
+ // TODO: reuse VPDerivedIVRecipe for base pointer computation when it
+ // supports a general VPValue as the start value.
VPValue *StartVPV = vputils::getOrCreateVPValueForSCEVExpr(Plan, Start);
VPValue *StrideInBytes = Plan.getOrAddLiveIn(Step->getValue());
Type *IndexTy = Plan.getDataLayout().getIndexType(Ptr->getScalarType());
assert(IndexTy == StrideInBytes->getScalarType() &&
"Stride type from SCEV must match the index type");
- VPValue *CanIVTyStride = Builder.createScalarSExtOrTrunc(
- StrideInBytes, VectorLoop->getCanonicalIVType(), IndexTy,
- DebugLoc::getUnknown());
+ VPValue *CanIV = Builder.createScalarSExtOrTrunc(
+ VectorLoop->getCanonicalIV(), IndexTy,
+ VectorLoop->getCanonicalIVType(), DebugLoc::getUnknown());
----------------
lukel97 wrote:
I think this is an example that showcases the issue:
```llvm
define void @canonical_iv_i64(ptr noalias %arr, ptr noalias %out, i64 %n) {
entry:
br label %loop
loop:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
%ptr = getelementptr [1024 x i8], ptr %arr, i64 %iv
%val = load i8, ptr %ptr
store i8 %val, ptr %out
%iv.next = add nuw i64 %iv, 1
%ec = icmp ult i64 %iv.next, %n
br i1 %ec, label %loop, label %exit
exit:
ret void
}
```
Without strided accesses the IR is:
```llvm
vector.body: ; preds = %vector.body, %vector.ph
%vec.ind = phi <vscale x 8 x i64> [ %0, %vector.ph ], [ %vec.ind.next, %vector.body ]
%avl = phi i64 [ %umax, %vector.ph ], [ %avl.next, %vector.body ]
%1 = call i32 @llvm.experimental.get.vector.length.i64(i64 %avl, i32 8, i1 true)
%2 = zext i32 %1 to i64
%broadcast.splatinsert1 = insertelement <vscale x 8 x i64> poison, i64 %2, i64 0
%broadcast.splat2 = shufflevector <vscale x 8 x i64> %broadcast.splatinsert1, <vscale x 8 x i64> poison, <vscale x 8 x i32> zeroinitializer
%3 = getelementptr [1024 x i8], ptr %arr, <vscale x 8 x i64> %vec.ind
%wide.masked.gather = call <vscale x 8 x i8> @llvm.vp.gather.nxv8i8.nxv8p0(<vscale x 8 x ptr> align 1 %3, <vscale x 8 x i1> splat (i1 true), i32 %1)
call void @llvm.vp.scatter.nxv8i8.nxv8p0(<vscale x 8 x i8> %wide.masked.gather, <vscale x 8 x ptr> align 1 %broadcast.splat, <vscale x 8 x i1> splat (i1 true), i32 %1)
%avl.next = sub nuw i64 %avl, %2
%vec.ind.next = add nuw <vscale x 8 x i64> %vec.ind, %broadcast.splat2
%4 = icmp eq i64 %avl.next, 0
br i1 %4, label %middle.block, label %vector.body, !llvm.loop !0
```
Before this patch the offset is in i64:
```llvm
vector.body: ; preds = %vector.body, %vector.ph
%index = phi i64 [ 0, %vector.ph ], [ %current.iteration.next, %vector.body ]
%avl = phi i64 [ %umax, %vector.ph ], [ %avl.next, %vector.body ]
%0 = call i32 @llvm.experimental.get.vector.length.i64(i64 %avl, i32 16, i1 true)
%1 = shl i64 %index, 10
%2 = getelementptr i8, ptr %arr, i64 %1
%3 = call <vscale x 16 x i8> @llvm.experimental.vp.strided.load.nxv16i8.p0.i32(ptr align 1 %2, i32 1024, <vscale x 16 x i1> splat (i1 true), i32 %0)
call void @llvm.vp.scatter.nxv16i8.nxv16p0(<vscale x 16 x i8> %3, <vscale x 16 x ptr> align 1 %broadcast.splat, <vscale x 16 x i1> splat (i1 true), i32 %0)
%4 = zext i32 %0 to i64
%current.iteration.next = add i64 %4, %index
%avl.next = sub nuw i64 %avl, %4
%5 = icmp eq i64 %avl.next, 0
br i1 %5, label %middle.block, label %vector.body, !llvm.loop !0
```
After it's truncated to i32:
```llvm
vector.body: ; preds = %vector.body, %vector.ph
%index = phi i64 [ 0, %vector.ph ], [ %current.iteration.next, %vector.body ]
%avl = phi i64 [ %umax, %vector.ph ], [ %avl.next, %vector.body ]
%0 = call i32 @llvm.experimental.get.vector.length.i64(i64 %avl, i32 16, i1 true)
%1 = trunc i64 %index to i32
%2 = shl i32 %1, 10
%3 = getelementptr i8, ptr %arr, i32 %2
%4 = call <vscale x 16 x i8> @llvm.experimental.vp.strided.load.nxv16i8.p0.i32(ptr align 1 %3, i32 1024, <vscale x 16 x i1> splat (i1 true), i32 %0)
call void @llvm.vp.scatter.nxv16i8.nxv16p0(<vscale x 16 x i8> %4, <vscale x 16 x ptr> align 1 %broadcast.splat, <vscale x 16 x i1> splat (i1 true), i32 %0)
%5 = zext i32 %0 to i64
%current.iteration.next = add i64 %5, %index
%avl.next = sub nuw i64 %avl, %5
%6 = icmp eq i64 %avl.next, 0
br i1 %6, label %middle.block, label %vector.body, !llvm.loop !0
```
https://github.com/llvm/llvm-project/pull/201070
More information about the llvm-commits
mailing list