Bug type: crash
Component: LoopVectorize
Bug location: llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp: VPInstruction::generate
Issue title: A/F: "Trying to access a single scalar per part but has multiple scalars " "per part."' failed after 7f74651
Labels: vectorizers
crash
Reported by: dyung

Recently one of our internal tests started hitting an assertion failure when compiling which I bisected back to commit 7f74651. 

Here is a reduced repro from the crashing code:
```c
typedef float a;
typedef struct {
  a b, c;
} d;
typedef struct {
  d e;
  a f;
} g;
#define h()                                                                    \
  i = j->e.b;                                                                  \
  k = l->e.c;                                                                  \
  l->f = k;
a i, k;
int m;
g *l;
void n() {
  g *j = l + 1;
  for (; m; ++m, ++l, ++j) {
    h()
  }
}
```

When compiled with `-O2 -g -ffast-math -march=znver2` using a compiler built from 7f74651 you can see the crash:
```
$ ~/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang -c -O2 -g -ffast-math -march=znver2 repro.c
clang: /home/dyung/src/upstream/llvm_clean_git/llvm/lib/Transforms/Vectorize/VPlan.cpp:258: llvm::Value* llvm::VPTransformState::get(llvm::VPValue*, bool): Assertion `(VF.isScalar() || Def->isLiveIn() || hasVectorValue(Def) || !vputils::onlyFirstLaneUsed(Def) || (hasScalarValue(Def, VPLane(0)) && Data.VPV2Scalars[Def].size() == 1)) && "Trying to access a single scalar per part but has multiple scalars " "per part."' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0.      Program arguments: /home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang -c -O2 -g -ffast-math -march=znver2 repro2.c
1.      <eof> parser at end of file
2.      Optimizer
3.      Running pass "function<eager-inv>(float2int,lower-constant-intrinsics,loop(loop-rotate<header-duplication;no-prepare-for-lto>,loop-deletion),loop-distribute,inject-tli-mappings,loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>,infer-alignment,loop-load-elim,instcombine<max-iterations=1;no-verify-fixpoint>,simplifycfg<bonus-inst-threshold=1;forward-switch-cond;switch-range-to-icmp;switch-to-lookup;no-keep-loops;hoist-common-insts;no-hoist-loads-stores-with-cond-faulting;sink-common-insts;speculate-blocks;simplify-cond-branch;no-speculate-unpredictables>,slp-vectorizer,vector-combine,instcombine<max-iterations=1;no-verify-fixpoint>,loop-unroll<O2>,transform-warning,sroa<preserve-cfg>,infer-alignment,instcombine<max-iterations=1;no-verify-fixpoint>,loop-mssa(licm<allowspeculation>),alignment-from-assumptions,loop-sink,instsimplify,div-rem-pairs,tailcallelim,simplifycfg<bonus-inst-threshold=1;no-forward-switch-cond;switch-range-to-icmp;no-switch-to-lookup;keep-loops;no-hoist-common-insts;hoist-loads-stores-with-cond-faulting;no-sink-common-insts;speculate-blocks;simplify-cond-branch;speculate-unpredictables>)" on module "repro2.c"
4.      Running pass "loop-vectorize<no-interleave-forced-only;no-vectorize-forced-only;>" on function "n"
 #0 0x000055d0e9ad0e1f llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x235be1f)
 #1 0x000055d0e9ace96c llvm::sys::CleanupOnSignal(unsigned long) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x235996c)
 #2 0x000055d0e9a20cc8 CrashRecoverySignalHandler(int) CrashRecoveryContext.cpp:0:0
 #3 0x00007f44c03e9420 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x14420)
 #4 0x00007f44bfeb600b raise /build/glibc-LcI20x/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #5 0x00007f44bfe95859 abort /build/glibc-LcI20x/glibc-2.31/stdlib/abort.c:81:7
 #6 0x00007f44bfe95729 get_sysdep_segment_value /build/glibc-LcI20x/glibc-2.31/intl/loadmsgcat.c:509:8
 #7 0x00007f44bfe95729 _nl_load_domain /build/glibc-LcI20x/glibc-2.31/intl/loadmsgcat.c:970:34
 #8 0x00007f44bfea6fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #9 0x000055d0eb66055a llvm::VPTransformState::get(llvm::VPValue*, bool) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3eeb55a)
#10 0x000055d0eb6926a9 llvm::VPInstruction::generate(llvm::VPTransformState&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3f1d6a9)
#11 0x000055d0eb695d01 llvm::VPInstruction::execute(llvm::VPTransformState&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3f20d01)
#12 0x000055d0eb65fb77 llvm::VPBasicBlock::executeRecipes(llvm::VPTransformState*, llvm::BasicBlock*) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3eeab77)
#13 0x000055d0eb66283e llvm::VPBasicBlock::execute(llvm::VPTransformState*) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3eed83e)
#14 0x000055d0eb6645c8 llvm::VPRegionBlock::execute(llvm::VPTransformState*) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3eef5c8)
#15 0x000055d0eb660b8e llvm::VPlan::execute(llvm::VPTransformState*) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3eebb8e)
#16 0x000055d0eb5362cb llvm::LoopVectorizationPlanner::executePlan(llvm::ElementCount, unsigned int, llvm::VPlan&, llvm::InnerLoopVectorizer&, llvm::DominatorTree*, bool, llvm::DenseMap<llvm::SCEV const*, llvm::Value*, llvm::DenseMapInfo<llvm::SCEV const*, void>, llvm::detail::DenseMapPair<llvm::SCEV const*, llvm::Value*>> const*) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3dc12cb)
#17 0x000055d0eb54baf4 llvm::LoopVectorizePass::processLoop(llvm::Loop*) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3dd6af4)
#18 0x000055d0eb54dac1 llvm::LoopVectorizePass::runImpl(llvm::Function&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3dd8ac1)
#19 0x000055d0eb54e133 llvm::LoopVectorizePass::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3dd9133)
#20 0x000055d0eaf6f396 llvm::detail::PassModel<llvm::Function, llvm::LoopVectorizePass, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x37fa396)
#21 0x000055d0e9589031 llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x1e14031)
#22 0x000055d0e86a7026 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0xf32026)
#23 0x000055d0e958799d llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x1e1299d)
#24 0x000055d0e86a79e6 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0xf329e6)
#25 0x000055d0e95873d1 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x1e123d1)
#26 0x000055d0e9d65d23 (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>&, std::unique_ptr<llvm::ToolOutputFile, std::default_delete<llvm::ToolOutputFile>>&, clang::BackendConsumer*) BackendUtil.cpp:0:0
#27 0x000055d0e9d692f8 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::unique_ptr<llvm::raw_pwrite_stream, std::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x25f42f8)
#28 0x000055d0ea4492ac clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x2cd42ac)
#29 0x000055d0ec3dbb9c clang::ParseAST(clang::Sema&, bool, bool) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x4c66b9c)
#30 0x000055d0ea4496c8 clang::CodeGenAction::ExecuteAction() (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x2cd46c8)
#31 0x000055d0ea7119a9 clang::FrontendAction::Execute() (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x2f9c9a9)
#32 0x000055d0ea68d99e clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x2f1899e)
#33 0x000055d0ea7fe466 clang::ExecuteCompilerInvocation(clang::CompilerInstance*) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x3089466)
#34 0x000055d0e862a295 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0xeb5295)
#35 0x000055d0e862201a ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) driver.cpp:0:0
#36 0x000055d0ea48f17d void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const::'lambda'()>(long) Job.cpp:0:0
#37 0x000055d0e9a211d0 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x22ac1d0)
#38 0x000055d0ea48f79f clang::driver::CC1Command::Execute(llvm::ArrayRef<std::optional<llvm::StringRef>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, bool*) const (.part.0) Job.cpp:0:0
#39 0x000055d0ea4538f4 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&, bool) const (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x2cde8f4)
#40 0x000055d0ea454a0d clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&, bool) const (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x2cdfa0d)
#41 0x000055d0ea45cb55 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::pair<int, clang::driver::Command const*>>&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0x2ce7b55)
#42 0x000055d0e862722b clang_main(int, char**, llvm::ToolContext const&) (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0xeb222b)
#43 0x000055d0e855712b main (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0xde212b)
#44 0x00007f44bfe97083 __libc_start_main /build/glibc-LcI20x/glibc-2.31/csu/../csu/libc-start.c:342:3
#45 0x000055d0e8621aae _start (/home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin/clang+0xeacaae)
clang: error: clang frontend command failed with exit code 134 (use -v to see invocation)
clang version 20.0.0 (https://github.com/llvm/llvm-project.git 7f74651837b8f95996ea4c774b2e604020446951)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /home/dyung/src/upstream/7f74651837b8f95996ea4c774b2e604020446951-linux/bin
Build config: +assertions
```

Here is a link to godbolt also showing the failure: https://godbolt.org/z/bnPM9qqYo


Fix patch:
commit 01cbbc52dc95fe5d9e30ecbfb2ec8c7c1e0199c4
Author: Florian Hahn <flo@fhahn.com>
Date:   Wed Oct 9 13:18:53 2024 +0100

    [VPlan] Request lane 0 for pointer arg in PtrAdd.
    
    After 7f74651, the pointer operand may be replicated of a PtrAdd. Instead
    of requesting a single scalar, request lane 0, which correctly handles the
    case when there is a scalar-per-lane.
    
    Fixes https://github.com/llvm/llvm-project/issues/111606.

diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 123eb0d8d71a..2468616be0bd 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -645,8 +645,8 @@ Value *VPInstruction::generate(VPTransformState &State) {
   case VPInstruction::PtrAdd: {
     assert(vputils::onlyFirstLaneUsed(this) &&
            "can only generate first lane for PtrAdd");
-    Value *Ptr = State.get(getOperand(0), /* IsScalar */ true);
-    Value *Addend = State.get(getOperand(1), /* IsScalar */ true);
+    Value *Ptr = State.get(getOperand(0), VPLane(0));
+    Value *Addend = State.get(getOperand(1), VPLane(0));
     return isInBounds() ? Builder.CreateInBoundsPtrAdd(Ptr, Addend, Name)
                         : Builder.CreatePtrAdd(Ptr, Addend, Name);
   }


Regression tests:
file: llvm/test/Transforms/LoopVectorize/X86/interleave-ptradd-with-replicated-operand.ll
commands: opt -p loop-vectorize -force-vector-width=4 -S %s
tests: test_name: test_interleave_ptradd_with_replicated_op
test_body: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define ptr @test_interleave_ptradd_with_replicated_op(ptr %m) #0 {
entry:
  br label %loop

loop:                                             ; preds = %loop, %entry
  %ptr.iv = phi ptr [ %m, %entry ], [ %ptr.iv.next, %loop ]
  %iv = phi i32 [ 1, %entry ], [ %iv.next, %loop ]
  %ptr.iv.next = getelementptr i8, ptr %ptr.iv, i64 8
  %p.4 = getelementptr i8, ptr %ptr.iv, i64 4
  %l.1 = load i32, ptr %p.4, align 4
  %p.0 = getelementptr i8, ptr %ptr.iv, i64 0
  %l.2 = load i32, ptr %p.0, align 4
  %add = add i32 %l.1, %l.2
  store i32 %add, ptr %ptr.iv, align 4
  %iv.next = add i32 %iv, 1
  %tobool.not = icmp eq i32 %iv, 100
  br i1 %tobool.not, label %exit, label %loop

exit:                                             ; preds = %loop
  ret ptr %p.4
}

attributes #0 = { "target-cpu"="znver2" }