Bug type: crash
Component: ScalarEvolution
Bug location: llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp: SCEVExpander::expandIVInc
Issue title: llvm crash: Assertion `Idx >= 0 && "Invalid basic block argument!"' failed.
Labels: llvm:crash
llvm:SCEV
Reported by: shao-hua-li

llvm crashes in `loop-idiom` pass.

Bisected to 1c6e6432ca0b6832e06b93a4bcf22ead1899c14d, which was committed by @nikic 

Compiler explorer: https://godbolt.org/z/nxhnoE1Mb

**% cat reduced.ll**
```llvm
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define void @m(i8 %0, i64 %1, i32 %a.promoted) {
entry:
  %conv13 = sext i8 %0 to i64
  %add14 = add i64 %1, -1
  br label %for.cond5thread-pre-split.lr.ph.split.us.us

for.cond5thread-pre-split.lr.ph.split.us.us:      ; preds = %for.cond2.loopexit.us.us, %entry
  %inc.i1417.us = phi i32 [ %a.promoted, %entry ], [ %inc.i.us20, %for.cond2.loopexit.us.us ]
  %add161516.us = phi i64 [ 0, %entry ], [ %add16.us24, %for.cond2.loopexit.us.us ]
  br label %for.body7.us.us

for.body7.us.us:                                  ; preds = %for.body7.us.us, %for.cond5thread-pre-split.lr.ph.split.us.us
  %2 = phi i64 [ %add9.us.us, %for.body7.us.us ], [ 0, %for.cond5thread-pre-split.lr.ph.split.us.us ]
  %arrayidx8.us.us = getelementptr [1 x [5 x i8]], ptr null, i64 0, i64 %add161516.us, i64 %2
  store i8 0, ptr %arrayidx8.us.us, align 1
  %add9.us.us = add i64 %2, 1
  %tobool6.not.us.us = icmp eq i64 %add9.us.us, 0
  br i1 %tobool6.not.us.us, label %for.cond2.loopexit.us.us, label %for.body7.us.us

for.cond2.loopexit.us.us:                         ; preds = %for.body7.us.us
  %inc.i.us20 = add nsw i32 %inc.i1417.us, 1
  %conv.i.us21 = sext i32 %inc.i1417.us to i64
  %add15.us22 = add i64 %add14, %conv.i.us21
  %sub.us23 = add i64 %add15.us22, %conv13
  %add16.us24 = add i64 %sub.us23, %add161516.us
  br label %for.cond5thread-pre-split.lr.ph.split.us.us
}
```

**% opt -disable-output -passes=loop-idiom reduced.ll**
```console
opt: /tmp/tmpxmdtc3mt/tmpn8inmjh2/llvm/include/llvm/IR/Instructions.h:2910: llvm::Value* llvm::PHINode::getIncomingValueForBlock(const llvm::BasicBlock*) const: Assertion `Idx >= 0 && "Invalid basic block argument!"' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0.	Program arguments: /zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/opt -disable-output -passes=loop-idiom reduced.ll
 #0 0x00007fc24b876eaf llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x914eaf)
 #1 0x00007fc24b874414 SignalHandler(int) Signals.cpp:0:0
 #2 0x00007fc24ab77090 (/lib/x86_64-linux-gnu/libc.so.6+0x43090)
 #3 0x00007fc24ab7700b raise /build/glibc-wuryBv/glibc-2.31/signal/../sysdeps/unix/sysv/linux/raise.c:51:1
 #4 0x00007fc24ab56859 abort /build/glibc-wuryBv/glibc-2.31/stdlib/abort.c:81:7
 #5 0x00007fc24ab56729 get_sysdep_segment_value /build/glibc-wuryBv/glibc-2.31/intl/loadmsgcat.c:509:8
 #6 0x00007fc24ab56729 _nl_load_domain /build/glibc-wuryBv/glibc-2.31/intl/loadmsgcat.c:970:34
 #7 0x00007fc24ab67fd6 (/lib/x86_64-linux-gnu/libc.so.6+0x33fd6)
 #8 0x00007fc24d68155f llvm::Loop::getCanonicalInductionVariable() const (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x271f55f)
 #9 0x00007fc24ca39df5 llvm::SCEVExpander::visitAddRecExpr(llvm::SCEVAddRecExpr const*) (.part.0) ScalarEvolutionExpander.cpp:0:0
#10 0x00007fc24ca36745 llvm::SCEVVisitor<llvm::SCEVExpander, llvm::Value*>::visit(llvm::SCEV const*) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ad4745)
#11 0x00007fc24ca3711b llvm::SCEVExpander::expand(llvm::SCEV const*) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ad511b)
#12 0x00007fc24ca37380 llvm::SCEVExpander::expandCodeForImpl(llvm::SCEV const*, llvm::Type*) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ad5380)
#13 0x00007fc24ca399ec llvm::SCEVExpander::expandAddToGEP(llvm::SCEV const*, llvm::Type*, llvm::Value*) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ad79ec)
#14 0x00007fc24ca3ab97 llvm::SCEVExpander::expandIVInc(llvm::PHINode*, llvm::Value*, llvm::Loop const*, llvm::Type*, llvm::Type*, bool) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ad8b97)
#15 0x00007fc24ca3bb6e llvm::SCEVExpander::getAddRecExprPHILiterally(llvm::SCEVAddRecExpr const*, llvm::Loop const*, llvm::Type*, llvm::Type*, llvm::Type*&, bool&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ad9b6e)
#16 0x00007fc24ca3c5d4 llvm::SCEVExpander::expandAddRecExprLiterally(llvm::SCEVAddRecExpr const*) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ada5d4)
#17 0x00007fc24ca36745 llvm::SCEVVisitor<llvm::SCEVExpander, llvm::Value*>::visit(llvm::SCEV const*) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ad4745)
#18 0x00007fc24ca3711b llvm::SCEVExpander::expand(llvm::SCEV const*) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ad511b)
#19 0x00007fc24ca37380 llvm::SCEVExpander::expandCodeForImpl(llvm::SCEV const*, llvm::Type*) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ad5380)
#20 0x00007fc24ce4bc8c (anonymous namespace)::LoopIdiomRecognize::processLoopStridedStore(llvm::Value*, llvm::SCEV const*, llvm::MaybeAlign, llvm::Value*, llvm::Instruction*, llvm::SmallPtrSetImpl<llvm::Instruction*>&, llvm::SCEVAddRecExpr const*, llvm::SCEV const*, bool, bool) LoopIdiomRecognize.cpp:0:0
#21 0x00007fc24ce539b7 (anonymous namespace)::LoopIdiomRecognize::processLoopStores(llvm::SmallVectorImpl<llvm::StoreInst*>&, llvm::SCEV const*, (anonymous namespace)::LoopIdiomRecognize::ForMemset) LoopIdiomRecognize.cpp:0:0
#22 0x00007fc24ce5494c (anonymous namespace)::LoopIdiomRecognize::runOnCountableLoop() LoopIdiomRecognize.cpp:0:0
#23 0x00007fc24ce561fd llvm::LoopIdiomRecognizePass::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1ef41fd)
#24 0x00007fc24e6ee6c6 llvm::detail::PassModel<llvm::Loop, llvm::LoopIdiomRecognizePass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x378c6c6)
#25 0x00007fc24ce7544f std::optional<llvm::PreservedAnalyses> llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::runSinglePass<llvm::Loop, std::unique_ptr<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, std::default_delete<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>>>>(llvm::Loop&, std::unique_ptr<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>, std::default_delete<llvm::detail::PassConcept<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>>>&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&, llvm::PassInstrumentation&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1f1344f)
#26 0x00007fc24ce756f6 llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::runWithoutLoopNestPasses(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1f136f6)
#27 0x00007fc24ce76b0d llvm::PassManager<llvm::Loop, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&>::run(llvm::Loop&, llvm::AnalysisManager<llvm::Loop, llvm::LoopStandardAnalysisResults&>&, llvm::LoopStandardAnalysisResults&, llvm::LPMUpdater&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1f14b0d)
#28 0x00007fc24ce77d62 llvm::FunctionToLoopPassAdaptor::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x1f15d62)
#29 0x00007fc24e6eb0c6 llvm::detail::PassModel<llvm::Function, llvm::FunctionToLoopPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x37890c6)
#30 0x00007fc24ba8a40d llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0xb2840d)
#31 0x00007fc24e6e41a6 llvm::detail::PassModel<llvm::Function, llvm::PassManager<llvm::Function, llvm::AnalysisManager<llvm::Function>>, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Function>>::run(llvm::Function&, llvm::AnalysisManager<llvm::Function>&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x37821a6)
#32 0x00007fc24ba88c9d llvm::ModuleToFunctionPassAdaptor::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0xb26c9d)
#33 0x00007fc24e6eb026 llvm::detail::PassModel<llvm::Module, llvm::ModuleToFunctionPassAdaptor, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0x3789026)
#34 0x00007fc24ba86c1d llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module>>::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/../lib/libLLVM-18git.so+0xb24c1d)
#35 0x000055608ac0cc95 llvm::runPassPipeline(llvm::StringRef, llvm::Module&, llvm::TargetMachine*, llvm::TargetLibraryInfoImpl*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::ToolOutputFile*, llvm::StringRef, llvm::ArrayRef<llvm::PassPlugin>, llvm::opt_tool::OutputKind, llvm::opt_tool::VerifierKind, bool, bool, bool, bool, bool, bool, bool) (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/opt+0x25c95)
#36 0x000055608ac00876 main (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/opt+0x19876)
#37 0x00007fc24ab58083 __libc_start_main /build/glibc-wuryBv/glibc-2.31/csu/../csu/libc-start.c:342:3
#38 0x000055608ac0151e _start (/zdata/shaoli/compilers/ccbuilder-compilers/clang-1c6e6432ca0b6832e06b93a4bcf22ead1899c14d/bin/opt+0x1a51e)
[1]    1629345 abort       -disable-output -passes=loop-idiom reduced.ll
```

The IR is reduced from the following C code:
```C
int a, b;
long d, h, j;
short e;
char f;
static char *g = &f;
static long *i = &d;
char k[1][5];
long l() {
  long c = a++;
  return c;
}
void m() {
  for (; b;)
    for (;; j = l() + *g + *i - 1 + j) {
      e = 0;
      for (; *i + e; e = 1)
        for (; h; h = h + 1)
          k[j][h] = 4;
    }
}
int main() {}
```


Fix patch:
commit bec7181d5b9d1828129d78d440fd9e02d5cb63e8
Author: Nikita Popov <npopov@redhat.com>
Date:   Wed Feb 7 11:06:51 2024 +0100

    [SCEVExpander] Don't use recursive expansion for ptr IV inc
    
    Similar to the non-ptr case, directly create the getelementptr
    instruction. Going through expandAddToGEP() no longer makes sense
    with opaque pointers, where generating the necessary instruction
    is trivial.
    
    This avoids recursive expansion of (the SCEV of) StepV while the
    IR is in an inconsistent state, in particular with an incomplete
    IV phi node, which utilities may not be prepared to deal with.
    
    Fixes https://github.com/llvm/llvm-project/issues/80954.

diff --git a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
index 58dbac0e85fb..3a28909473d9 100644
--- a/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
+++ b/llvm/lib/Transforms/Utils/ScalarEvolutionExpander.cpp
@@ -795,7 +795,8 @@ Value *SCEVExpander::expandIVInc(PHINode *PN, Value *StepV, const Loop *L,
   Value *IncV;
   // If the PHI is a pointer, use a GEP, otherwise use an add or sub.
   if (PN->getType()->isPointerTy()) {
-    IncV = expandAddToGEP(SE.getSCEV(StepV), PN);
+    // TODO: Change name to IVName.iv.next.
+    IncV = Builder.CreatePtrAdd(PN, StepV, "scevgep");
   } else {
     IncV = useSubtract ?
       Builder.CreateSub(PN, StepV, Twine(IVName) + ".iv.next") :


Regression tests:
file: llvm/test/Transforms/LoopIdiom/pr80954.ll
commands: opt -S -passes=loop-idiom < %s
tests: test_name: test
test_body: define void @test(ptr %p, i8 %arg, i64 %arg1, i32 %arg2) {
entry:
  %sext = sext i8 %arg to i64
  %add = add i64 %arg1, -1
  br label %loop

loop:                                             ; preds = %latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %latch ]
  %phi = phi i32 [ %arg2, %entry ], [ %add9, %latch ]
  br label %loop2

loop2:                                            ; preds = %loop2, %loop
  %iv2 = phi i64 [ %iv2.next, %loop2 ], [ 0, %loop ]
  %gep = getelementptr [4 x i8], ptr %p, i64 %iv, i64 %iv2
  store i8 0, ptr %gep, align 1
  %iv2.next = add i64 %iv2, 1
  %icmp = icmp eq i64 %iv2.next, 0
  br i1 %icmp, label %latch, label %loop2

latch:                                            ; preds = %loop2
  %add9 = add nsw i32 %phi, 1
  %sext10 = sext i32 %phi to i64
  %add11 = add i64 %add, %sext10
  %add12 = add i64 %add11, %sext
  %iv.next = add i64 %add12, %iv
  br label %loop
}