Bug type: crash
Component: LoopVectorize
Bug location: llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp: VPPredInstPHIRecipe::execute
Issue title: [clang] Assertion failed in VPlan.cpp:258
Labels: vectorizers
crash
regression:19
Reported by: cardigan1008

When I compiled the code with -O2 flag, it crashed:

```c
#include <stdint.h>
static uint8_t c[] = {1};
void a();
long b(int h) {
  long d = 0;
  if (h < 0)
    return -1;
  int e = 0;
  for (int f = 0; f <= h; f++) {
    e++;
    d += f;
  }
  long a = d / e;
  return a;
}
void g();
uint8_t i() {
  uint16_t k[4];
  int f;
  for (; g + f < 4; f++)
    k[b(c[0] - 1)] = 5;
  for (; f; a(k))
    ;
  uint8_t *l[3][3], j;
  l[0][j] = c;
}
```

The crash is:
```
clang: /root/llvm-project/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.
```

Details can be found here: https://godbolt.org/z/fTrKKha5E

Comments: author: shafik
body: Looks like a clang-19 regression: https://godbolt.org/z/6d3edKn86

Fix patch:
commit 68210c7c269b7b7325dedaea7cea9fe9d979fab5
Author: Florian Hahn <flo@fhahn.com>
Date:   Sat Oct 5 19:15:05 2024 +0100

    [VPlan] Only generate first lane for VPPredInstPHI if no others used.
    
    IF only the first lane of the result is used, only generate the first
    lane.
    
    Fixes https://github.com/llvm/llvm-project/issues/111042.

diff --git a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
index 0d092b9c10ac..376b3d33be76 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanRecipes.cpp
@@ -2185,6 +2185,9 @@ void VPPredInstPHIRecipe::execute(VPTransformState &State) {
     // predicated iteration inserts its generated value in the correct vector.
     State.reset(getOperand(0), VPhi);
   } else {
+    if (vputils::onlyFirstLaneUsed(this) && !State.Lane->isFirstLane())
+      return;
+
     Type *PredInstType = getOperand(0)->getUnderlyingValue()->getType();
     PHINode *Phi = State.Builder.CreatePHI(PredInstType, 2);
     Phi->addIncoming(PoisonValue::get(ScalarPredInst->getType()),


Regression tests:
file: llvm/test/Transforms/LoopVectorize/X86/divs-with-tail-folding.ll
commands: opt -p loop-vectorize -mtriple x86_64 -prefer-predicate-over-epilogue=predicate-dont-vectorize -mcpu=skylake-avx512 -S %s
tests: test_name: sdiv_feeding_gep_predicated
test_body: define void @sdiv_feeding_gep_predicated(ptr %dst, i32 %x, i64 %M, i64 %conv6, i64 %N) {
entry:
  %conv61 = zext i32 %x to i64
  br label %loop

loop:                                             ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
  %c = icmp ule i64 %iv, %M
  br i1 %c, label %then, label %loop.latch

then:                                             ; preds = %loop
  %div18 = sdiv i64 %M, %conv6
  %conv20 = trunc i64 %div18 to i32
  %mul30 = mul i64 %div18, %conv61
  %sub31 = sub i64 %iv, %mul30
  %conv34 = trunc i64 %sub31 to i32
  %mul35 = mul i32 %x, %conv20
  %add36 = add i32 %mul35, %conv34
  %idxprom = sext i32 %add36 to i64
  %gep = getelementptr double, ptr %dst, i64 %idxprom
  store double 0.000000e+00, ptr %gep, align 8
  br label %loop.latch

loop.latch:                                       ; preds = %then, %loop
  %iv.next = add i64 %iv, 1
  %ec = icmp eq i64 %iv.next, %N
  br i1 %ec, label %exit, label %loop

exit:                                             ; preds = %loop.latch
  ret void
}

file: llvm/test/Transforms/LoopVectorize/X86/drop-poison-generating-flags.ll
commands: opt %s -passes=loop-vectorize -force-vector-width=4 -force-vector-interleave=1 -S
tests: test_name: pr70590_recipe_without_underlying_instr
test_body: 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-pc-linux-gnu"

@c = external global [5 x i8]

define void @pr70590_recipe_without_underlying_instr(i64 %n, ptr noalias %dst) {
entry:
  br label %loop.header

loop.header:                                      ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %inc, %loop.latch ]
  %cmp = icmp eq i64 %iv, %n
  br i1 %cmp, label %loop.latch, label %then

then:                                             ; preds = %loop.header
  %rem = srem i64 3, 0
  %add3 = add i64 %rem, -3
  %add5 = add i64 %iv, %add3
  %gep = getelementptr [5 x i8], ptr @c, i64 0, i64 %add5
  %l = load i8, ptr %gep, align 1
  br label %loop.latch

loop.latch:                                       ; preds = %then, %loop.header
  %sr = phi i8 [ 0, %loop.header ], [ %l, %then ]
  %gep.dst = getelementptr i8, ptr %dst, i64 %iv
  store i8 %sr, ptr %gep.dst, align 4
  %inc = add i64 %iv, 1
  %exitcond.not = icmp eq i64 %inc, 4
  br i1 %exitcond.not, label %exit, label %loop.header

exit:                                             ; preds = %loop.latch
  ret void
}

file: llvm/test/Transforms/LoopVectorize/X86/replicate-recipe-with-only-first-lane-used.ll
commands: opt -p loop-vectorize -force-vector-width=4 -force-vector-interleave=2 -S %s
tests: test_name: replicate_udiv_with_only_first_lane_used
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 void @replicate_udiv_with_only_first_lane_used(i32 %x, ptr %dst, i64 %d) {
entry:
  %c = icmp eq i32 %x, 10
  br label %loop.header

loop.header:                                      ; preds = %loop.latch, %entry
  %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
  br i1 true, label %loop.latch, label %else

else:                                             ; preds = %loop.header
  %div.i = udiv i64 99, %d
  br label %loop.latch

loop.latch:                                       ; preds = %else, %loop.header
  %retval.0.i = phi i64 [ %div.i, %else ], [ 0, %loop.header ]
  %gep = getelementptr i16, ptr %dst, i64 %retval.0.i
  store i16 0, ptr %gep, align 2
  %iv.next = add i64 %iv, 1
  %cmp = icmp ult i64 %iv.next, 101
  br i1 %cmp, label %loop.header, label %exit

exit:                                             ; preds = %loop.latch
  ret void
}