Skip to content

[LV] Constant::getSplatValue: Assertion `this->getType()->isVectorTy() && "Only valid for vectors!"' failed. #169334

@david-arm

Description

@david-arm

While trying to rewrite the test 'both' in test/Transforms/LoopVectorize/iv_outside_user.ll to look like this:

define ptr @both(ptr %p, i32 %k)  {
entry:
  %base = getelementptr inbounds i32, ptr %p, i64 1
  br label %for.body

for.body:
  %inc.phi = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  %inc.lag1 = phi ptr [ %base, %entry ], [ %tmp, %for.body]
  %inc.lag2 = phi ptr [ %base, %entry ], [ %inc.lag1, %for.body]
  %tmp = getelementptr inbounds i32, ptr %inc.lag1, i64 1
  %inc = add nsw i32 %inc.phi, 1
  %cmp = icmp eq i32 %inc, %k
  br i1 %cmp, label %for.end, label %for.body

for.end:
  ret ptr %inc.lag1
}

I encountered this assert and backtrace:

llvm::Constant* llvm::Constant::getSplatValue(bool) const: Assertion `this->getType()->isVectorTy() && "Only valid for vectors!"' failed.
...
 #8 0x0000aaaab9e2fba4 llvm::Constant::getSplatValue(bool) const (./bin/opt+0x4c2fba4)
 #9 0x0000aaaab9dfb844 llvm::ConstantFoldBinaryInstruction(unsigned int, llvm::Constant*, llvm::Constant*) (./bin/opt+0x4bfb844)
#10 0x0000aaaab8235dd0 llvm::IRBuilderBase::CreateBinOpFMF(llvm::Instruction::BinaryOps, llvm::Value*, llvm::Value*, llvm::FMFSource, llvm::Twine const&, llvm::MDNode*) (.constprop.0) VPlanRecipes.cpp:0:0
#11 0x0000aaaab8248338 llvm::VPInstruction::generate(llvm::VPTransformState&) (./bin/opt+0x3048338)
#12 0x0000aaaab824a5c0 llvm::VPInstruction::execute(llvm::VPTransformState&) (./bin/opt+0x304a5c0)
#13 0x0000aaaab81f7988 llvm::VPBasicBlock::executeRecipes(llvm::VPTransformState*, llvm::BasicBlock*) (./bin/opt+0x2ff7988)
#14 0x0000aaaab820422c llvm::VPBasicBlock::execute(llvm::VPTransformState*) (./bin/opt+0x300422c)

when using the command:

opt -S -passes=loop-vectorize -force-vector-interleave=2 -force-vector-width=1 < iv_outside_user.ll

The vplan for VF=1 looks like this:

vector.body:
  EMIT-SCALAR vp<%index> = phi [ ir<0>, vector.ph ], [ vp<%index.next>, vector.body ]
  EMIT-SCALAR vp<%pointer.phi> = phi [ ir<%base>, vector.ph ], [ vp<%ptr.ind>, vector.body ]
  EMIT vp<%7> = step-vector i64
  EMIT vp<%8> = mul vp<%7>, ir<4>
  EMIT vp<%vector.gep> = wide-ptradd vp<%pointer.phi>, vp<%8>
  EMIT vp<%step.add> = wide-ptradd vp<%vector.gep>, vp<%6>
  EMIT vp<%index.next> = add nuw vp<%index>, ir<2>
  EMIT vp<%ptr.ind> = ptradd vp<%pointer.phi>, ir<8>
  EMIT branch-on-count vp<%index.next>, vp<%n.vec>
Successor(s): middle.block, vector.body

The problem happens when generating code for the mul VPInstruction, since we are attempting to multiply <1 x i64> zeroinitializer by i64 4. It looks like this is the problematic code:

  if (Instruction::isBinaryOp(getOpcode())) {
    bool OnlyFirstLaneUsed = vputils::onlyFirstLaneUsed(this);
    Value *A = State.get(getOperand(0), OnlyFirstLaneUsed);
    Value *B = State.get(getOperand(1), OnlyFirstLaneUsed);

Presumably OnlyFirstLaneUsed should be true here?

Metadata

Metadata

Assignees

No one assigned

    Labels

    crashPrefer [crash-on-valid] or [crash-on-invalid]vectorizers

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions