[llvm] [LV] Convert gather loads with constant stride into strided loads (PR #147297)
Luke Lau via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 26 01:20:54 PDT 2026
https://github.com/lukel97 commented:
I'm seeing a crash on SPEC CPU 2017, here's a reduced test case which might be good to include in this PR:
```llvm
; ModuleID = 'reduced.bc'
target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
target triple = "riscv64-unknown-linux-gnu"
define void @_ZN6dealii8internal13Triangulation14Implementation18execute_refinementILi3EEEvRNS_13TriangulationILi3EXT_EEE(ptr %0, i64 %sub.ptr.sub.i3060) #0 {
entry:
br label %for.cond785.preheader
for.cond785.preheader: ; preds = %for.cond785.preheader, %entry
%conv77719316 = phi i64 [ %conv777, %for.cond785.preheader ], [ 0, %entry ]
%q.019315 = phi i32 [ %inc817, %for.cond785.preheader ], [ 0, %entry ]
%add.ptr.i3062 = getelementptr nusw [16 x i8], ptr %0, i64 %conv77719316
%1 = load i32, ptr %add.ptr.i3062, align 4
%arrayidx.i.1 = getelementptr i8, ptr %add.ptr.i3062, i64 4
%2 = load i32, ptr %arrayidx.i.1, align 4
%arrayidx.i.3 = getelementptr nusw i8, ptr %add.ptr.i3062, i64 12
%3 = load i32, ptr %arrayidx.i.3, align 4
store i32 0, ptr %add.ptr.i3062, align 4
%inc817 = add i32 %q.019315, 1
%conv777 = zext i32 %inc817 to i64
%cmp782 = icmp ugt i64 %sub.ptr.sub.i3060, %conv777
br i1 %cmp782, label %for.cond785.preheader, label %for.body823
for.body823: ; preds = %for.cond785.preheader
ret void
}
attributes #0 = { "target-features"="+v" }
```
The crash is coming from this cast to VPWidenMemoryRecipe bit in createInterleaveGroups:
```
void VPlanTransforms::createInterleaveGroups(
VPlan &Plan,
const SmallPtrSetImpl<const InterleaveGroup<Instruction> *>
&InterleaveGroups,
VPRecipeBuilder &RecipeBuilder, const bool &ScalarEpilogueAllowed) {
if (InterleaveGroups.empty())
return;
// Interleave memory: for each Interleave Group we marked earlier as relevant
// for this VPlan, replace the Recipes widening its memory instructions with a
// single VPInterleaveRecipe at its insertion point.
VPDominatorTree VPDT(Plan);
for (const auto *IG : InterleaveGroups) {
auto *Start =
cast<VPWidenMemoryRecipe>(RecipeBuilder.getRecipe(IG->getMember(0)));
```
I'm guessing a NF=4 interleaved access is probably the more profitable option here. Off the top of my head I guess there's two ways we can handle this:
1) Bail in `convertToStridedAccesses` if the load is in an interleave group
2) Instead of `VPWidenMemIntrinsicRecipe`, make a `VPStridedLoadRecipe` which is a subclass of `VPWidenMemoryRecipe` so `createInterleaveGroups` can handle it
Maybe there's other ways around this. I don't have a strong opinion on this but 2) seems slightly nicer since we wouldn't need to plumb interleave groups through to `convertToStridedAccesses`
https://github.com/llvm/llvm-project/pull/147297
More information about the llvm-commits
mailing list