Bug type: crash
Component: SLPVectorizer
Bug location: llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp: BoUpSLP::canBuildSplitNode
Issue title: [slp] ICE: Instruction does not dominate all uses!
Labels: llvm:SLPVectorizer
crash-on-valid
Reported by: ashermancinelli

First showed up in 04c38981a9ce3e6225669c0e41cab947e3e7989f, last known good commit was 0283bb3afcc5dc521f6b2e7d541a830a9546ed80.

Commits in this range with SLP in the subject line:
```
$ g log 0283bb3afcc5dc521f6b2e7d541a830a9546ed80^1..04c38981a9ce3e6225669c0e41cab947e3e7989f|grep -i slp
'61d04f1aac96 Thu Apr 10 16:05:01 2025 -0400  [SLP][NFC]Extract preliminary checks from buildTree_rec, NFC'
'aaaa2a325bd1 Thu Apr 10 12:06:38 2025 -0400  [SLP]Support vectorization of previously vectorized scalars in split nodes'
'4ea57b3481c0 Thu Apr 10 08:30:43 2025 -0700  [SLP]Fix detection of matching splat vector'
'396e2ef3b7f4 Thu Apr 10 08:20:28 2025 -0700  [SLP][NFC]Add a test with incorrect identity match for less-defined splat'
'a693f23ef2fc Thu Apr 10 23:07:45 2025 +0800  [SLP][REVEC] Fix CompressVectorize does not expand mask when REVEC is enabled. (#135174)'
'd02a704ec952 Thu Apr 10 18:54:45 2025 +0800  [SLP][REVEC] Make getExtractWithExtendCost support FixedVectorType as Dst. (#134822)'
```

```
$ opt -passes=slp-vectorizer reduced.ll -disable-output
Instruction does not dominate all uses!
  %15 = call <6 x double> @llvm.vector.insert.v6f64.v2f64(<6 x double> %14, <2 x double> %13, i64 4)
  %9 = shufflevector <6 x double> %15, <6 x double> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
Instruction does not dominate all uses!
  %13 = insertelement <2 x double> %12, double %1, i32 1
  %11 = call <6 x double> @llvm.vector.insert.v6f64.v2f64(<6 x double> %10, <2 x double> %13, i64 4)
LLVM ERROR: Broken module found, compilation aborted!
```

```
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 @foo(double %0) {
.thread:
  %1 = call double null(ptr null, ptr null, ptr null)
  %2 = call double null(ptr null, ptr null, ptr null)
  br i1 false, label %3, label %5

3:                                                ; preds = %.thread
  %4 = call double null(ptr null, ptr null, ptr null)
  br label %5

5:                                                ; preds = %3, %.thread
  %.1226 = phi double [ %4, %3 ], [ 0.000000e+00, %.thread ]
  %.1222 = phi double [ 0.000000e+00, %3 ], [ 0.000000e+00, %.thread ]
  %.1218 = phi double [ %0, %3 ], [ 0.000000e+00, %.thread ]
  %.1216 = phi double [ 0.000000e+00, %3 ], [ 0.000000e+00, %.thread ]
  br i1 false, label %.lr.ph272.preheader, label %._crit_edge

.lr.ph272.preheader:                              ; preds = %5
  br i1 false, label %._crit_edge, label %6

6:                                                ; preds = %.lr.ph272.preheader
  %7 = fdiv double 0.000000e+00, 0.000000e+00
  %8 = fsub double 0.000000e+00, %7
  %9 = fdiv double 0.000000e+00, 0.000000e+00
  %10 = fsub double 0.000000e+00, %9
  br i1 false, label %11, label %._crit_edge

11:                                               ; preds = %6
  br label %._crit_edge

._crit_edge:                                      ; preds = %11, %6, %.lr.ph272.preheader, %5
  %.2227.lcssa = phi double [ %.1226, %5 ], [ 0.000000e+00, %11 ], [ %.1226, %6 ], [ %.1226, %.lr.ph272.preheader ]
  %.2223.lcssa = phi double [ %.1222, %5 ], [ 0.000000e+00, %11 ], [ %.1222, %6 ], [ %.1222, %.lr.ph272.preheader ]
  %.2219.lcssa = phi double [ %.1218, %5 ], [ 0.000000e+00, %11 ], [ %.1218, %6 ], [ %.1218, %.lr.ph272.preheader ]
  %.2.lcssa = phi double [ %.1216, %5 ], [ %0, %11 ], [ %.1216, %6 ], [ %.1216, %.lr.ph272.preheader ]
  %.0213.lcssa = phi double [ %2, %5 ], [ 0.000000e+00, %11 ], [ %10, %6 ], [ %2, %.lr.ph272.preheader ]
  %.0211.lcssa = phi double [ %1, %5 ], [ 0.000000e+00, %11 ], [ %8, %6 ], [ %1, %.lr.ph272.preheader ]
  ret void
}
```


Fix patch:
commit 2271f0bebd48c9ed8b16b500886a819c4f269a6a
Author: Alexey Bataev <a.bataev@outlook.com>
Date:   Tue Apr 15 13:02:32 2025 -0700

    [SLP]Check for perfect/shuffled match for the split node
    
    If the potential split node is a perfect/shuffled match of another split
    node, need to skip creation of the another split node with the same
    scalars, it should be a buildvector.
    
    Fixes #135800

diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 253933a2438c..234cd340ebc1 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -9575,6 +9575,24 @@ bool BoUpSLP::canBuildSplitNode(ArrayRef<Value *> VL,
       !SplitAlternateInstructions)
     return false;
 
+  // Check if this is a duplicate of another split entry.
+  LLVM_DEBUG(dbgs() << "SLP: \tChecking bundle: " << *LocalState.getMainOp()
+                    << ".\n");
+  for (TreeEntry *E : getSplitTreeEntries(LocalState.getMainOp())) {
+    if (E->isSame(VL)) {
+      LLVM_DEBUG(dbgs() << "SLP: Perfect diamond merge at "
+                        << *LocalState.getMainOp() << ".\n");
+      return false;
+    }
+    SmallPtrSet<Value *, 8> Values(llvm::from_range, E->Scalars);
+    if (all_of(VL, [&](Value *V) {
+          return isa<PoisonValue>(V) || Values.contains(V);
+        })) {
+      LLVM_DEBUG(dbgs() << "SLP: Gathering due to full overlap.\n");
+      return false;
+    }
+  }
+
   ReorderIndices.assign(VL.size(), VL.size());
   SmallBitVector Op1Indices(VL.size());
   for (auto [Idx, V] : enumerate(VL)) {


Regression tests:
file: llvm/test/Transforms/SLPVectorizer/X86/split-node-full-match.ll
commands: opt -S --passes=slp-vectorizer -mtriple=x86_64-unknown-linux-gnu < %s
tests: test_name: <module>
test_body: 
define void @test(double %0) {
;
.thread:
  %1 = call double null(ptr null, ptr null, ptr null)
  %2 = call double null(ptr null, ptr null, ptr null)
  br i1 false, label %3, label %5

3:
  %4 = call double null(ptr null, ptr null, ptr null)
  br label %5

5:
  %.1226 = phi double [ %4, %3 ], [ 0.000000e+00, %.thread ]
  %.1222 = phi double [ 0.000000e+00, %3 ], [ 0.000000e+00, %.thread ]
  %.1218 = phi double [ %0, %3 ], [ 0.000000e+00, %.thread ]
  %.1216 = phi double [ 0.000000e+00, %3 ], [ 0.000000e+00, %.thread ]
  br i1 false, label %.lr.ph272.preheader, label %._crit_edge

.lr.ph272.preheader:
  br i1 false, label %._crit_edge, label %6

6:
  %7 = fdiv double 0.000000e+00, 0.000000e+00
  %8 = fsub double 0.000000e+00, %7
  %9 = fdiv double 0.000000e+00, 0.000000e+00
  %10 = fsub double 0.000000e+00, %9
  br i1 false, label %11, label %._crit_edge

11:
  br label %._crit_edge

._crit_edge:
  %.2227.lcssa = phi double [ %.1226, %5 ], [ 0.000000e+00, %11 ], [ %.1226, %6 ], [ %.1226, %.lr.ph272.preheader ]
  %.2223.lcssa = phi double [ %.1222, %5 ], [ 0.000000e+00, %11 ], [ %.1222, %6 ], [ %.1222, %.lr.ph272.preheader ]
  %.2219.lcssa = phi double [ %.1218, %5 ], [ 0.000000e+00, %11 ], [ %.1218, %6 ], [ %.1218, %.lr.ph272.preheader ]
  %.2.lcssa = phi double [ %.1216, %5 ], [ %0, %11 ], [ %.1216, %6 ], [ %.1216, %.lr.ph272.preheader ]
  %.0213.lcssa = phi double [ %2, %5 ], [ 0.000000e+00, %11 ], [ %10, %6 ], [ %2, %.lr.ph272.preheader ]
  %.0211.lcssa = phi double [ %1, %5 ], [ 0.000000e+00, %11 ], [ %8, %6 ], [ %1, %.lr.ph272.preheader ]
  ret void
}
file: llvm/test/Transforms/SLPVectorizer/X86/split-node-no-reorder-copy.ll
commands: opt -S --passes=slp-vectorizer -mtriple=x86_64-sie-ps5 -mcpu=znver2 < %s
tests: test_name: test
test_body: define i1 @test(ptr %0, ptr %1, <2 x float> %2, <2 x float> %3, <2 x float> %4) {
  %6 = load float, ptr %1, align 4
  %7 = load float, ptr %0, align 4
  %8 = fmul float %6, %6
  %9 = fmul float %7, %7
  %10 = fmul float %7, %7
  %11 = fmul float %7, %7
  %12 = fmul float %7, %7
  %13 = fmul float %7, %7
  %14 = load float, ptr %0, align 4
  %15 = fmul float %14, %14
  %16 = fmul float %14, %14
  %17 = extractelement <2 x float> %2, i64 0
  %18 = extractelement <2 x float> %2, i64 0
  %19 = fmul float %17, %17
  %20 = fmul float %18, %18
  %21 = extractelement <2 x float> %3, i64 0
  %22 = extractelement <2 x float> %2, i64 0
  %23 = fmul float %21, %21
  %24 = fmul float %22, %22
  %25 = extractelement <2 x float> %2, i64 0
  %26 = extractelement <2 x float> %2, i64 0
  %27 = fmul float %25, %25
  %28 = fmul float %26, %26
  %29 = extractelement <2 x float> %2, i64 0
  %30 = extractelement <2 x float> %4, i64 0
  %31 = fmul float %29, %29
  %32 = fmul float %30, %30
  %33 = fadd reassoc nsz float %8, %9
  %34 = fadd reassoc nsz float %33, %10
  %35 = fadd reassoc nsz float %34, %11
  %36 = fadd reassoc nsz float %35, %12
  %37 = fadd reassoc nsz float %36, %13
  %38 = fadd reassoc nsz float %37, %15
  %39 = fadd reassoc nsz float %38, %16
  %40 = fadd reassoc nsz float %39, %19
  %41 = fadd reassoc nsz float %40, %20
  %42 = fadd reassoc nsz float %41, %23
  %43 = fadd reassoc nsz float %42, %24
  %44 = fadd reassoc nsz float %43, %27
  %45 = fadd reassoc nsz float %44, %28
  %46 = fadd reassoc nsz float %45, %31
  %47 = fadd reassoc nsz float %46, %32
  %48 = call float @foo(float %47)
  ret i1 false
}

declare float @foo(float)