Skip to content

[SLP]Support freeze as copyable main op - #239999

Open
alexey-bataev wants to merge 2 commits into
mainfrom
users/alexey-bataev/spr/slpsupport-freeze-as-copyable-main-op
Open

alexey-bataev wants to merge 2 commits into
mainfrom
users/alexey-bataev/spr/slpsupport-freeze-as-copyable-main-op

Conversation

@alexey-bataev

Copy link
Copy Markdown
Member

Model non-freeze lanes as freeze(V), which refines V, so mixed
bundles become a single vector freeze instead of a gather.

Assisted-by: Cursor

Created using spr 1.3.7
@llvmorg-github-actions

llvmorg-github-actions Bot commented Nov 7, 2026 •

Copy link
Copy Markdown

@llvm/pr-subscribers-llvm-transforms

@llvm/pr-subscribers-llvm-vectorizers

Author: Alexey Bataev (alexey-bataev)

Changes

Model non-freeze lanes as freeze(V), which refines V, so mixed
bundles become a single vector freeze instead of a gather.

Assisted-by: Cursor


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

5 Files Affected:

  • (modified) llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp (+16-9)
  • (modified) llvm/test/Transforms/SLPVectorizer/X86/copyable-freeze.ll (+8-34)
  • (modified) llvm/test/Transforms/SLPVectorizer/X86/select-copyable-cmp-poison.ll (+11-13)
  • (modified) llvm/test/Transforms/SLPVectorizer/X86/shl-to-add-transformation5.ll (+3-3)
  • (modified) llvm/test/Transforms/SLPVectorizer/X86/shuffle-mask-emission.ll (+3-6)
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index e7fb2b024fa0a..f7e2cdcc8f18a 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -10342,9 +10342,12 @@ class InstructionsCompatibilityAnalysis {
   /// lanes are inserted into it. A single-index scalar GEP is supported: the
   /// copyable lanes are modeled as zero-index GEPs of the lane values
   /// themselves. A scalar zext is supported: the copyable lanes are constants
-  /// modeled as zexts of truncated constants.
+  /// modeled as zexts of truncated constants. A freeze is supported: the
+  /// copyable lanes are modeled as freezes of the lane values, which refine
+  /// them.
   static bool isSupportedMainOp(Instruction *I) {
-    return isSupportedOpcode(I->getOpcode()) || isa<MinMaxIntrinsic>(I) ||
+    return isSupportedOpcode(I->getOpcode()) ||
+           isa<MinMaxIntrinsic, FreezeInst>(I) ||
            RecurrenceDescriptor::isFMulAddIntrinsic(I) ||
            (isa<ExtractElementInst>(I) && isVectorLikeInstWithConstOps(I) &&
             isa<FixedVectorType>(I->getOperand(0)->getType())) ||
@@ -10587,6 +10590,9 @@ class InstructionsCompatibilityAnalysis {
     if (MainOpcode == Instruction::ZExt)
       return {ConstantExpr::getTrunc(cast<Constant>(V),
                                      cast<CastInst>(MainOp)->getSrcTy())};
+    // freeze(V) refines V.
+    if (MainOpcode == Instruction::Freeze)
+      return {V};
     assert(isSupportedMainOp(MainOp) && "Unsupported opcode");
     Type *Ty = V->getType();
     if (PoisonPlaceholder &&
@@ -11264,11 +11270,12 @@ class InstructionsCompatibilityAnalysis {
           Candidates.emplace_back(V1, (I1 || I2) ? V2 : V1);
         };
     if (VL.size() == 2) {
-      // The operand-pairing heuristic below does not apply to calls, GEPs
-      // and casts; defer to the full tree cost computation instead of
+      // The operand-pairing heuristic below does not apply to calls, GEPs,
+      // casts and freezes; defer to the full tree cost computation instead of
       // pre-rejecting here.
       if (MainOpcode == Instruction::Call ||
-          MainOpcode == Instruction::GetElementPtr || isa<CastInst>(MainOp))
+          MainOpcode == Instruction::GetElementPtr ||
+          isa<CastInst, FreezeInst>(MainOp))
         return S;
       // Check if the operands allow better vectorization.
       SmallVector<std::pair<Value *, Value *>, 4> Candidates1, Candidates2;
@@ -11322,10 +11329,10 @@ class InstructionsCompatibilityAnalysis {
         return OrigS;
       return S;
     }
-    // Casts are the only 1-operand and fma/fmuladd are the only 3-operand
-    // copyables.
+    // Casts and freezes are the only 1-operand and fma/fmuladd are the only
+    // 3-operand copyables.
     assert((Operands.size() == 2 ||
-            (Operands.size() == 1 && isa<CastInst>(MainOp)) ||
+            (Operands.size() == 1 && isa<CastInst, FreezeInst>(MainOp)) ||
             (Operands.size() == 3 && isFMAOrFMulAdd(MainOp))) &&
            "Unexpected number of operands!");
     if (CopyableNum < VL.size() / 2)
@@ -11390,7 +11397,7 @@ class InstructionsCompatibilityAnalysis {
       return OrigS;
     // Check the operand holding the copyable values.
     if (!CheckOperand(Operands[S.getCopyableOpIdx()])) {
-      if (Operands.size() == 2)
+      if (!isFMAOrFMulAdd(MainOp))
         return OrigS;
       // Retry with the copyable modeled as the first multiplicand.
       S.setCopyableOpIdx(0);
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/copyable-freeze.ll b/llvm/test/Transforms/SLPVectorizer/X86/copyable-freeze.ll
index cc0a358531095..a145052849d97 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/copyable-freeze.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/copyable-freeze.ll
@@ -4,17 +4,8 @@
 define void @one_copyable(ptr %p, ptr %q) {
 ; CHECK-LABEL: @one_copyable(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[G2:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 2
-; CHECK-NEXT:    [[G3:%.*]] = getelementptr i32, ptr [[P]], i64 3
-; CHECK-NEXT:    [[A2:%.*]] = load i32, ptr [[G2]], align 4
-; CHECK-NEXT:    [[A3:%.*]] = load i32, ptr [[G3]], align 4
-; CHECK-NEXT:    [[F2:%.*]] = freeze i32 [[A2]]
-; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x i32>, ptr [[P]], align 4
-; CHECK-NEXT:    [[TMP1:%.*]] = freeze <2 x i32> [[TMP0]]
-; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <4 x i32> poison, i32 [[F2]], i64 2
-; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <4 x i32> [[TMP2]], i32 [[A3]], i64 3
-; CHECK-NEXT:    [[TMP4:%.*]] = shufflevector <2 x i32> [[TMP1]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
-; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <4 x i32> [[TMP3]], <4 x i32> [[TMP4]], <4 x i32> <i32 4, i32 5, i32 2, i32 3>
+; CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i32>, ptr [[P:%.*]], align 4
+; CHECK-NEXT:    [[TMP5:%.*]] = freeze <4 x i32> [[TMP0]]
 ; CHECK-NEXT:    [[TMP6:%.*]] = mul <4 x i32> [[TMP5]], <i32 3, i32 5, i32 7, i32 9>
 ; CHECK-NEXT:    store <4 x i32> [[TMP6]], ptr [[Q:%.*]], align 4
 ; CHECK-NEXT:    ret void
@@ -47,22 +38,9 @@ entry:
 define void @half_copyable_loads(ptr %p, ptr %q) {
 ; CHECK-LABEL: @half_copyable_loads(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[G1:%.*]] = getelementptr i32, ptr [[P:%.*]], i64 1
-; CHECK-NEXT:    [[G2:%.*]] = getelementptr i32, ptr [[P]], i64 2
-; CHECK-NEXT:    [[G3:%.*]] = getelementptr i32, ptr [[P]], i64 3
-; CHECK-NEXT:    [[A0:%.*]] = load i32, ptr [[P]], align 4
-; CHECK-NEXT:    [[A1:%.*]] = load i32, ptr [[G1]], align 4
-; CHECK-NEXT:    [[A2:%.*]] = load i32, ptr [[G2]], align 4
-; CHECK-NEXT:    [[A3:%.*]] = load i32, ptr [[G3]], align 4
-; CHECK-NEXT:    [[F0:%.*]] = freeze i32 [[A0]]
-; CHECK-NEXT:    [[F2:%.*]] = freeze i32 [[A2]]
-; CHECK-NEXT:    [[H1:%.*]] = getelementptr i32, ptr [[Q:%.*]], i64 1
-; CHECK-NEXT:    [[H2:%.*]] = getelementptr i32, ptr [[Q]], i64 2
-; CHECK-NEXT:    [[H3:%.*]] = getelementptr i32, ptr [[Q]], i64 3
-; CHECK-NEXT:    store i32 [[F0]], ptr [[Q]], align 4
-; CHECK-NEXT:    store i32 [[A1]], ptr [[H1]], align 4
-; CHECK-NEXT:    store i32 [[F2]], ptr [[H2]], align 4
-; CHECK-NEXT:    store i32 [[A3]], ptr [[H3]], align 4
+; CHECK-NEXT:    [[TMP0:%.*]] = load <4 x i32>, ptr [[P:%.*]], align 4
+; CHECK-NEXT:    [[TMP1:%.*]] = freeze <4 x i32> [[TMP0]]
+; CHECK-NEXT:    store <4 x i32> [[TMP1]], ptr [[Q:%.*]], align 4
 ; CHECK-NEXT:    ret void
 ;
 entry:
@@ -119,13 +97,9 @@ entry:
 define void @two_lanes(ptr %p, ptr %q) {
 ; CHECK-LABEL: @two_lanes(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[G1:%.*]] = getelementptr i64, ptr [[P:%.*]], i64 1
-; CHECK-NEXT:    [[A0:%.*]] = load i64, ptr [[P]], align 8
-; CHECK-NEXT:    [[A1:%.*]] = load i64, ptr [[G1]], align 8
-; CHECK-NEXT:    [[F0:%.*]] = freeze i64 [[A0]]
-; CHECK-NEXT:    [[H1:%.*]] = getelementptr i64, ptr [[Q:%.*]], i64 1
-; CHECK-NEXT:    store i64 [[F0]], ptr [[Q]], align 8
-; CHECK-NEXT:    store i64 [[A1]], ptr [[H1]], align 8
+; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x i64>, ptr [[P:%.*]], align 8
+; CHECK-NEXT:    [[TMP1:%.*]] = freeze <2 x i64> [[TMP0]]
+; CHECK-NEXT:    store <2 x i64> [[TMP1]], ptr [[Q:%.*]], align 8
 ; CHECK-NEXT:    ret void
 ;
 entry:
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/select-copyable-cmp-poison.ll b/llvm/test/Transforms/SLPVectorizer/X86/select-copyable-cmp-poison.ll
index bf64a3c6cc0eb..429fc26bccfc0 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/select-copyable-cmp-poison.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/select-copyable-cmp-poison.ll
@@ -10,30 +10,28 @@ define i32 @foo(i32 %v2, ptr byval(%struct.S2) align 8 %v5, i1 %cmp3644) {
 ; CHECK-NEXT:  [[ENTRY:.*:]]
 ; CHECK-NEXT:    br label %[[BB4:.*]]
 ; CHECK:       [[BB4]]:
-; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <8 x i32> poison, i32 [[V2]], i64 1
+; CHECK-NEXT:    [[TMP0:%.*]] = insertelement <4 x i32> poison, i32 [[V2]], i64 0
 ; CHECK-NEXT:    br label %[[BB5:.*]]
 ; CHECK:       [[BB5]]:
 ; CHECK-NEXT:    [[F1783:%.*]] = getelementptr i8, ptr [[V5]], i64 108
 ; CHECK-NEXT:    [[F2354:%.*]] = getelementptr i8, ptr [[V5]], i64 88
 ; CHECK-NEXT:    [[F2882:%.*]] = getelementptr i8, ptr [[V5]], i64 100
 ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[F2354]], align 8
-; CHECK-NEXT:    [[DOTFR5727:%.*]] = freeze i32 [[TMP2]]
 ; CHECK-NEXT:    [[TMP3:%.*]] = load <4 x i32>, ptr [[F2882]], align 4
-; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <4 x i32> [[TMP3]], <4 x i32> poison, <2 x i32> <i32 0, i32 3>
-; CHECK-NEXT:    [[TMP4:%.*]] = freeze <2 x i32> [[TMP5]]
+; CHECK-NEXT:    [[TMP8:%.*]] = shufflevector <4 x i32> [[TMP3]], <4 x i32> poison, <2 x i32> <i32 3, i32 0>
+; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <4 x i32> [[TMP0]], i32 [[TMP2]], i64 1
+; CHECK-NEXT:    [[TMP5:%.*]] = shufflevector <2 x i32> [[TMP8]], <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
+; CHECK-NEXT:    [[TMP6:%.*]] = shufflevector <4 x i32> [[TMP4]], <4 x i32> [[TMP5]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+; CHECK-NEXT:    [[TMP7:%.*]] = freeze <4 x i32> [[TMP6]]
 ; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[F1783]], align 4
 ; CHECK-NEXT:    [[DOTFR5726:%.*]] = freeze i32 [[TMP1]]
-; CHECK-NEXT:    [[TMP6:%.*]] = insertelement <8 x i32> [[TMP0]], i32 [[DOTFR5727]], i64 0
-; CHECK-NEXT:    [[TMP7:%.*]] = shufflevector <2 x i32> [[TMP4]], <2 x i32> poison, <8 x i32> <i32 1, i32 poison, i32 0, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison>
-; CHECK-NEXT:    [[TMP31:%.*]] = shufflevector <8 x i32> [[TMP6]], <8 x i32> [[TMP7]], <8 x i32> <i32 0, i32 1, i32 poison, i32 8, i32 poison, i32 10, i32 poison, i32 poison>
+; CHECK-NEXT:    [[TMP31:%.*]] = shufflevector <4 x i32> [[TMP7]], <4 x i32> poison, <8 x i32> <i32 0, i32 poison, i32 1, i32 2, i32 poison, i32 3, i32 poison, i32 poison>
 ; CHECK-NEXT:    [[TMP32:%.*]] = insertelement <8 x i32> [[TMP31]], i32 [[DOTFR5726]], i64 6
-; CHECK-NEXT:    [[TMP33:%.*]] = shufflevector <8 x i32> [[TMP32]], <8 x i32> poison, <8 x i32> <i32 0, i32 1, i32 1, i32 3, i32 0, i32 5, i32 6, i32 1>
+; CHECK-NEXT:    [[TMP33:%.*]] = shufflevector <8 x i32> [[TMP32]], <8 x i32> poison, <8 x i32> <i32 0, i32 0, i32 2, i32 3, i32 2, i32 5, i32 6, i32 0>
 ; CHECK-NEXT:    [[TMP34:%.*]] = srem <8 x i32> [[TMP33]], splat (i32 46337)
-; CHECK-NEXT:    [[TMP14:%.*]] = shufflevector <8 x i32> [[TMP34]], <8 x i32> poison, <8 x i32> <i32 2, i32 1, i32 0, i32 3, i32 4, i32 5, i32 6, i32 7>
-; CHECK-NEXT:    [[TMP13:%.*]] = shufflevector <8 x i32> [[TMP34]], <8 x i32> poison, <8 x i32> <i32 2, i32 1, i32 0, i32 3, i32 0, i32 5, i32 6, i32 2>
-; CHECK-NEXT:    [[TMP9:%.*]] = or <8 x i32> [[TMP13]], zeroinitializer
-; CHECK-NEXT:    [[TMP10:%.*]] = icmp slt <8 x i32> [[TMP14]], zeroinitializer
-; CHECK-NEXT:    [[TMP11:%.*]] = shufflevector <8 x i32> [[TMP34]], <8 x i32> <i32 0, i32 0, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 0>, <8 x i32> <i32 8, i32 9, i32 0, i32 3, i32 0, i32 5, i32 6, i32 15>
+; CHECK-NEXT:    [[TMP9:%.*]] = or <8 x i32> [[TMP34]], zeroinitializer
+; CHECK-NEXT:    [[TMP10:%.*]] = icmp slt <8 x i32> [[TMP34]], zeroinitializer
+; CHECK-NEXT:    [[TMP11:%.*]] = shufflevector <8 x i32> [[TMP34]], <8 x i32> <i32 0, i32 0, i32 poison, i32 poison, i32 poison, i32 poison, i32 poison, i32 0>, <8 x i32> <i32 8, i32 9, i32 2, i32 3, i32 2, i32 5, i32 6, i32 15>
 ; CHECK-NEXT:    [[TMP12:%.*]] = select <8 x i1> [[TMP10]], <8 x i32> [[TMP9]], <8 x i32> [[TMP11]]
 ; CHECK-NEXT:    [[TMP18:%.*]] = load <21 x i32>, ptr [[V5]], align 4
 ; CHECK-NEXT:    [[TMP19:%.*]] = shufflevector <21 x i32> [[TMP18]], <21 x i32> poison, <4 x i32> <i32 0, i32 1, i32 14, i32 20>
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/shl-to-add-transformation5.ll b/llvm/test/Transforms/SLPVectorizer/X86/shl-to-add-transformation5.ll
index ecd944e47bd81..1948fa219364f 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/shl-to-add-transformation5.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/shl-to-add-transformation5.ll
@@ -164,9 +164,9 @@ entry:
 define void @shl_add(ptr %p, i32 %a, i32 %b, i32 %c) {
 ; CHECK-LABEL: define void @shl_add(
 ; CHECK-SAME: ptr [[P:%.*]], i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) #[[ATTR0]] {
-; CHECK-NEXT:    [[TMP1:%.*]] = freeze i32 [[A]]
-; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <2 x i32> poison, i32 [[TMP1]], i64 0
-; CHECK-NEXT:    [[TMP2:%.*]] = insertelement <2 x i32> [[TMP4]], i32 [[B]], i64 1
+; CHECK-NEXT:    [[TMP1:%.*]] = insertelement <2 x i32> poison, i32 [[A]], i64 0
+; CHECK-NEXT:    [[TMP4:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[B]], i64 1
+; CHECK-NEXT:    [[TMP2:%.*]] = freeze <2 x i32> [[TMP4]]
 ; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <2 x i32> [[TMP2]], i32 [[C]], i64 1
 ; CHECK-NEXT:    [[TMP6:%.*]] = add <2 x i32> [[TMP2]], [[TMP3]]
 ; CHECK-NEXT:    store <2 x i32> [[TMP6]], ptr [[P]], align 4
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/shuffle-mask-emission.ll b/llvm/test/Transforms/SLPVectorizer/X86/shuffle-mask-emission.ll
index f99703d8e3562..8bce3616902bf 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/shuffle-mask-emission.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/shuffle-mask-emission.ll
@@ -4,13 +4,10 @@
 define i1 @test() {
 ; CHECK-LABEL: define i1 @test() {
 ; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[H_PROMOTED118_I_FR:%.*]] = freeze i32 1
-; CHECK-NEXT:    [[TMP3:%.*]] = insertelement <4 x i32> <i32 0, i32 0, i32 poison, i32 0>, i32 [[H_PROMOTED118_I_FR]], i64 2
-; CHECK-NEXT:    [[TMP2:%.*]] = add <4 x i32> zeroinitializer, [[TMP3]]
-; CHECK-NEXT:    [[TMP9:%.*]] = insertelement <4 x i32> <i32 poison, i32 0, i32 poison, i32 poison>, i32 [[H_PROMOTED118_I_FR]], i64 0
-; CHECK-NEXT:    [[TMP10:%.*]] = shufflevector <4 x i32> [[TMP9]], <4 x i32> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 0>
+; CHECK-NEXT:    [[TMP10:%.*]] = freeze <4 x i32> <i32 0, i32 0, i32 1, i32 0>
 ; CHECK-NEXT:    [[TMP4:%.*]] = add <4 x i32> zeroinitializer, [[TMP10]]
-; CHECK-NEXT:    [[TMP5:%.*]] = add <4 x i32> [[TMP2]], [[TMP4]]
+; CHECK-NEXT:    [[TMP2:%.*]] = shufflevector <4 x i32> [[TMP10]], <4 x i32> [[TMP4]], <4 x i32> <i32 2, i32 2, i32 7, i32 2>
+; CHECK-NEXT:    [[TMP5:%.*]] = add <4 x i32> [[TMP4]], [[TMP2]]
 ; CHECK-NEXT:    [[TMP6:%.*]] = and <4 x i32> [[TMP5]], <i32 0, i32 1, i32 1, i32 1>
 ; CHECK-NEXT:    [[TMP7:%.*]] = icmp eq <4 x i32> [[TMP6]], <i32 1, i32 0, i32 0, i32 0>
 ; CHECK-NEXT:    [[TMP8:%.*]] = call i1 @llvm.vector.reduce.or.v4i1(<4 x i1> [[TMP7]])

; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> [[TMP4]], i32 [[B]], i64 1
; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> poison, i32 [[A]], i64 0
; CHECK-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[B]], i64 1
; CHECK-NEXT: [[TMP2:%.*]] = freeze <2 x i32> [[TMP4]]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This freezes extra lane, should be just scalar a

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be ok, technically, but having it after gather/buildvector is not ok, will add extra check/trim

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeap, it seems like SLP catches buildvector [freeze a, b] here.

; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i32> [[TMP4]], i32 [[B]], i64 1
; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i32> poison, i32 [[A]], i64 0
; CHECK-NEXT: [[TMP4:%.*]] = insertelement <2 x i32> [[TMP1]], i32 [[B]], i64 1
; CHECK-NEXT: [[TMP2:%.*]] = freeze <2 x i32> [[TMP4]]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeap, it seems like SLP catches buildvector [freeze a, b] here.

Comment on lines +10349 to +10350
return isSupportedOpcode(I->getOpcode()) ||
isa<MinMaxIntrinsic, FreezeInst>(I) ||

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how it works on a tie. Would it be dependent on an order of the lanes? Note, that freeze is not BinaryOp to be handled by findAndSetMainInstruction.

Created using spr 1.3.7

This branch has not been deployed

No deployments
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.

2 participants