Skip to content

[SLP]Do not vectorize the same freeze in several nodes - #240125

Merged
alexey-bataev merged 1 commit into
mainfrom
users/alexey-bataev/spr/slpdo-not-vectorize-the-same-freeze-in-several-nodes
Nov 8, 2026
Merged

alexey-bataev merged 1 commit into
mainfrom
users/alexey-bataev/spr/slpdo-not-vectorize-the-same-freeze-in-several-nodes

Conversation

@alexey-bataev

Copy link
Copy Markdown
Member

Each vector freeze may produce its own value for an undef or poison
lane, so a freeze vectorized in more than one node is duplicated.
Gather such bundles instead.

Fixes #240001

Assisted-by: Cursor

Created using spr 1.3.7
@alexey-bataev
alexey-bataev merged commit 38f7f72 into main Nov 8, 2026
11 of 14 checks passed
@alexey-bataev
alexey-bataev deleted the users/alexey-bataev/spr/slpdo-not-vectorize-the-same-freeze-in-several-nodes branch November 8, 2026 12:26
@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-llvm-transforms

Author: Alexey Bataev (alexey-bataev)

Changes

Each vector freeze may produce its own value for an undef or poison
lane, so a freeze vectorized in more than one node is duplicated.
Gather such bundles instead.

Fixes #240001

Assisted-by: Cursor


Full diff: https://github.com/llvm/llvm-project/pull/240125.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp (+9)
  • (modified) llvm/test/Transforms/SLPVectorizer/X86/freeze-multi-node.ll (+6-5)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 71210f53a461b..920205b1f9ce1 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -11820,6 +11820,15 @@ BoUpSLP::getScalarsVectorizationLegality(ArrayRef<Value *> VL, unsigned Depth,
     }
   }
 
+  // The same freeze, vectorized in several nodes, may produce different values
+  // if its operand is undef or poison.
+  if (S.getOpcode() == Instruction::Freeze &&
+      any_of(make_isa_range<FreezeInst>(VL),
+             [&](FreezeInst *FI) { return isVectorized(FI); })) {
+    LLVM_DEBUG(dbgs() << "SLP: Gathering due to already vectorized freeze.\n");
+    return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
+  }
+
   bool AreAllSameBlock = !AreScatterAllGEPSameBlock;
   bool AreAllSameInsts = AreAllSameBlock || AreScatterAllGEPSameBlock;
   if (!AreAllSameInsts || isSplat(VL) ||
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/freeze-multi-node.ll b/llvm/test/Transforms/SLPVectorizer/X86/freeze-multi-node.ll
index 9c8981aef8d8e..5580ddcedbd3b 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/freeze-multi-node.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/freeze-multi-node.ll
@@ -5,14 +5,15 @@ define void @test(ptr %g, ptr %o) {
 ; CHECK-LABEL: define void @test(
 ; CHECK-SAME: ptr [[G:%.*]], ptr [[O:%.*]]) {
 ; CHECK-NEXT:    [[PG4:%.*]] = getelementptr i32, ptr [[G]], i64 4
-; CHECK-NEXT:    [[TMP4:%.*]] = load <4 x i32>, ptr [[G]], align 4
 ; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i32>, ptr [[PG4]], align 4
+; CHECK-NEXT:    [[TMP11:%.*]] = add nsw <2 x i32> [[TMP2]], splat (i32 10)
+; CHECK-NEXT:    [[TMP3:%.*]] = freeze <2 x i32> [[TMP11]]
+; CHECK-NEXT:    [[TMP4:%.*]] = load <4 x i32>, ptr [[G]], align 4
 ; CHECK-NEXT:    [[TMP5:%.*]] = add nsw <4 x i32> [[TMP4]], <i32 2147483647, i32 10, i32 10, i32 10>
-; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <2 x i32> [[TMP2]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
-; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <4 x i32> [[TMP7]], <4 x i32> [[TMP4]], <4 x i32> <i32 0, i32 4, i32 1, i32 5>
-; CHECK-NEXT:    [[TMP11:%.*]] = add nsw <4 x i32> [[TMP8]], <i32 10, i32 2147483647, i32 10, i32 10>
 ; CHECK-NEXT:    [[TMP6:%.*]] = freeze <4 x i32> [[TMP5]]
-; CHECK-NEXT:    [[TMP9:%.*]] = freeze <4 x i32> [[TMP11]]
+; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <4 x i32> [[TMP6]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 poison, i32 1>
+; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <2 x i32> [[TMP3]], <2 x i32> poison, <4 x i32> <i32 0, i32 poison, i32 1, i32 poison>
+; CHECK-NEXT:    [[TMP9:%.*]] = shufflevector <4 x i32> [[TMP7]], <4 x i32> [[TMP8]], <4 x i32> <i32 4, i32 1, i32 6, i32 3>
 ; CHECK-NEXT:    [[TMP10:%.*]] = sub <4 x i32> [[TMP6]], [[TMP9]]
 ; CHECK-NEXT:    store <4 x i32> [[TMP10]], ptr [[O]], align 4
 ; CHECK-NEXT:    ret void

@llvmorg-github-actions

Copy link
Copy Markdown

@llvm/pr-subscribers-llvm-vectorizers

Author: Alexey Bataev (alexey-bataev)

Changes

Each vector freeze may produce its own value for an undef or poison
lane, so a freeze vectorized in more than one node is duplicated.
Gather such bundles instead.

Fixes #240001

Assisted-by: Cursor


Full diff: https://github.com/llvm/llvm-project/pull/240125.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp (+9)
  • (modified) llvm/test/Transforms/SLPVectorizer/X86/freeze-multi-node.ll (+6-5)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 71210f53a461b..920205b1f9ce1 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -11820,6 +11820,15 @@ BoUpSLP::getScalarsVectorizationLegality(ArrayRef<Value *> VL, unsigned Depth,
     }
   }
 
+  // The same freeze, vectorized in several nodes, may produce different values
+  // if its operand is undef or poison.
+  if (S.getOpcode() == Instruction::Freeze &&
+      any_of(make_isa_range<FreezeInst>(VL),
+             [&](FreezeInst *FI) { return isVectorized(FI); })) {
+    LLVM_DEBUG(dbgs() << "SLP: Gathering due to already vectorized freeze.\n");
+    return ScalarsVectorizationLegality(S, /*IsLegal=*/false);
+  }
+
   bool AreAllSameBlock = !AreScatterAllGEPSameBlock;
   bool AreAllSameInsts = AreAllSameBlock || AreScatterAllGEPSameBlock;
   if (!AreAllSameInsts || isSplat(VL) ||
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/freeze-multi-node.ll b/llvm/test/Transforms/SLPVectorizer/X86/freeze-multi-node.ll
index 9c8981aef8d8e..5580ddcedbd3b 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/freeze-multi-node.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/freeze-multi-node.ll
@@ -5,14 +5,15 @@ define void @test(ptr %g, ptr %o) {
 ; CHECK-LABEL: define void @test(
 ; CHECK-SAME: ptr [[G:%.*]], ptr [[O:%.*]]) {
 ; CHECK-NEXT:    [[PG4:%.*]] = getelementptr i32, ptr [[G]], i64 4
-; CHECK-NEXT:    [[TMP4:%.*]] = load <4 x i32>, ptr [[G]], align 4
 ; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x i32>, ptr [[PG4]], align 4
+; CHECK-NEXT:    [[TMP11:%.*]] = add nsw <2 x i32> [[TMP2]], splat (i32 10)
+; CHECK-NEXT:    [[TMP3:%.*]] = freeze <2 x i32> [[TMP11]]
+; CHECK-NEXT:    [[TMP4:%.*]] = load <4 x i32>, ptr [[G]], align 4
 ; CHECK-NEXT:    [[TMP5:%.*]] = add nsw <4 x i32> [[TMP4]], <i32 2147483647, i32 10, i32 10, i32 10>
-; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <2 x i32> [[TMP2]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
-; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <4 x i32> [[TMP7]], <4 x i32> [[TMP4]], <4 x i32> <i32 0, i32 4, i32 1, i32 5>
-; CHECK-NEXT:    [[TMP11:%.*]] = add nsw <4 x i32> [[TMP8]], <i32 10, i32 2147483647, i32 10, i32 10>
 ; CHECK-NEXT:    [[TMP6:%.*]] = freeze <4 x i32> [[TMP5]]
-; CHECK-NEXT:    [[TMP9:%.*]] = freeze <4 x i32> [[TMP11]]
+; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <4 x i32> [[TMP6]], <4 x i32> poison, <4 x i32> <i32 poison, i32 0, i32 poison, i32 1>
+; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <2 x i32> [[TMP3]], <2 x i32> poison, <4 x i32> <i32 0, i32 poison, i32 1, i32 poison>
+; CHECK-NEXT:    [[TMP9:%.*]] = shufflevector <4 x i32> [[TMP7]], <4 x i32> [[TMP8]], <4 x i32> <i32 4, i32 1, i32 6, i32 3>
 ; CHECK-NEXT:    [[TMP10:%.*]] = sub <4 x i32> [[TMP6]], [[TMP9]]
 ; CHECK-NEXT:    store <4 x i32> [[TMP10]], ptr [[O]], align 4
 ; CHECK-NEXT:    ret void

llvm-sync Bot pushed a commit to arm/arm-toolchain that referenced this pull request Nov 8, 2026
Each vector freeze may produce its own value for an undef or poison
lane, so a freeze vectorized in more than one node is duplicated.
Gather such bundles instead.

Fixes #240001

Assisted-by: Cursor

Reviewers:

Pull Request: llvm/llvm-project#240125
llvm-upstreamsync Bot pushed a commit to qualcomm/cpullvm-toolchain that referenced this pull request Nov 8, 2026
Each vector freeze may produce its own value for an undef or poison
lane, so a freeze vectorized in more than one node is duplicated.
Gather such bundles instead.

Fixes #240001

Assisted-by: Cursor

Reviewers:

Pull Request: llvm/llvm-project#240125
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[SLPVectorizer] Duplicated freeze

1 participant