[PATCH] D105199: [LoopVectorize] Fix scalable vector crash in VPReplicateRecipe::execute

David Sherwood via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 5 01:07:47 PDT 2021


david-arm added inline comments.


================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:3069
 
   // End if-block.
   if (IfPredicateInstr)
----------------
CarolineConcatto wrote:
> Do we need this test also for scalable recipe  in scalarizeInstructions 
> 
> ```
>   if (IfPredicateInstr)
> ```
> ?
Good question! So in VPRecipeBuilder::handleReplication I have explicitly asserted that we should never create this recipe with predication, because I think the only cases we'd hit are divides (which we don't support) or loads/stores. For the latter we'll widen the instruction using masked load/store intrinsics and shouldn't use this recipe I think.


================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:8964-8965
+  bool IsScalable = Range.Start.isScalable();
+  assert(IsScalable == Range.End.isScalable() &&
+         "VFRange contains mixture of scalable and fixed-width VFs!");
+  VPRecipeBase *Recipe;
----------------
CarolineConcatto wrote:
> I believe you don't need the assert
> See lib/Transforms/Vectorize/VPlan.h
> struct VFRange;
Ah I see now - good spot thank you! I hadn't realised we already asserted this in the VFRange constructor.


================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:8966
+         "VFRange contains mixture of scalable and fixed-width VFs!");
+  VPRecipeBase *Recipe;
+  if (IsScalable && !IsUniform) {
----------------
CarolineConcatto wrote:
> Why do we need R and Recipe here?
The problem here is caused by complicated multiple inheritance, i.e.

  class VPReplicateRecipe : public VPRecipeBase, public VPValue

and the fact the functions below take pointers to only one of the inherited base classes, i.e.

  void setRecipe(Instruction *I, VPRecipeBase *R) {

  void addVPValue(Value *V, VPValue *VPV)

In order to have a single common block here I would have to restructure the recipes to have the same common base, i.e.

  class VPReplicateBaseRecipe : public VPRecipeBase, public VPValue

  class VPScalableReplicateRecipe : public VPReplicateBaseRecipe {

  class VPReplicateRecipe : public VPReplicateBaseRecipe {

This would mean I could then write:

  VPReplicateBaseRecipe *Recipe;
  if (IsScalable && !IsUniform)
    Recipe = new VPScalableReplicateRecipe(I, Plan->mapToVPValues(I->operands()));
  else
    Recipe = new VPReplicateRecipe(I, Plan->mapToVPValues(I->operands()),
                                    IsUniform, IsPredicated);
  setRecipe(I, R);
  Plan->addVPValue(I, R);

However, I wasn't sure which was more acceptable here - rewrite the class structures to be more complex or simply have two blocks of code here?

Alternatively, if anyone knows some magic C++ that allows me to write a common block with rewriting the class structure that would be great too! I could well be missing some trick here.


================
Comment at: llvm/lib/Transforms/Vectorize/LoopVectorize.cpp:8967
+  VPRecipeBase *Recipe;
+  if (IsScalable && !IsUniform) {
+    auto *R =
----------------
CarolineConcatto wrote:
> Should we test if this is not predicated instruction here?
> I don't see any test for that in the recipe.
Ah you're right! I added an assert in the for loop below, but it's not quite the same thing. I'll add one here too.


================
Comment at: llvm/test/Transforms/LoopVectorize/AArch64/sve-vpreplicate.ll:2
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -loop-vectorize -scalable-vectorization=on -S | FileCheck %s
+
----------------
CarolineConcatto wrote:
> Is it possible to use that with for all architectures? 
> Or only  for now for AArch64?
Possibly so? I thought I might have tried that when I first started the patch and hit issues, but I can try again.


================
Comment at: llvm/test/Transforms/LoopVectorize/AArch64/sve-vpreplicate.ll:136
+!3 = !{!"llvm.loop.vectorize.scalable.enable", i1 true}
+!4 = !{ !5 }
+!5 = distinct !{ !5, !6 }
----------------
CarolineConcatto wrote:
> Why do you need 4,5,6 and 7?
This is needed for one of the loops above that contains metadata:

  tail call void @llvm.experimental.noalias.scope.decl(metadata !4)

This line is explicitly testing one of the code paths in the new scalarizeInstruction() function.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D105199/new/

https://reviews.llvm.org/D105199



More information about the llvm-commits mailing list