[llvm] 8830525 - [ConstantFolding] Add constant folding for scalable vector interleave intrinsics. (#168668)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 19 15:50:41 PST 2025


Author: Craig Topper
Date: 2025-11-19T15:50:36-08:00
New Revision: 88305251fe809ba384ea4ff4893bf671757504fb

URL: https://github.com/llvm/llvm-project/commit/88305251fe809ba384ea4ff4893bf671757504fb
DIFF: https://github.com/llvm/llvm-project/commit/88305251fe809ba384ea4ff4893bf671757504fb.diff

LOG: [ConstantFolding] Add constant folding for scalable vector interleave intrinsics. (#168668)

We can constant fold interleave of identical splat vectors to a larger
splat vector.

Added: 
    

Modified: 
    llvm/lib/Analysis/ConstantFolding.cpp
    llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp
index 4bece85d3cfbf..916154b465af4 100644
--- a/llvm/lib/Analysis/ConstantFolding.cpp
+++ b/llvm/lib/Analysis/ConstantFolding.cpp
@@ -4313,6 +4313,22 @@ static Constant *ConstantFoldScalableVectorCall(
       return ConstantVector::getNullValue(SVTy);
     break;
   }
+  case Intrinsic::vector_interleave2:
+  case Intrinsic::vector_interleave3:
+  case Intrinsic::vector_interleave4:
+  case Intrinsic::vector_interleave5:
+  case Intrinsic::vector_interleave6:
+  case Intrinsic::vector_interleave7:
+  case Intrinsic::vector_interleave8: {
+    Constant *SplatVal = Operands[0]->getSplatValue();
+    if (!SplatVal)
+      return nullptr;
+
+    if (!llvm::all_equal(Operands))
+      return nullptr;
+
+    return ConstantVector::getSplat(SVTy->getElementCount(), SplatVal);
+  }
   default:
     break;
   }

diff  --git a/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll b/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll
index 5d9ed867c5e68..3f3cf341357d1 100644
--- a/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll
+++ b/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll
@@ -51,6 +51,32 @@ define <8 x i32> @fold_vector_interleave2() {
   ret <8 x i32> %1
 }
 
+define <vscale x 8 x i32> @fold_scalable_vector_interleave2() {
+; CHECK-LABEL: define <vscale x 8 x i32> @fold_scalable_vector_interleave2() {
+; CHECK-NEXT:    ret <vscale x 8 x i32> zeroinitializer
+;
+  %1 = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
+  ret <vscale x 8 x i32> %1
+}
+
+define <vscale x 8 x i32> @fold_scalable_vector_interleave2_splat() {
+; CHECK-LABEL: define <vscale x 8 x i32> @fold_scalable_vector_interleave2_splat() {
+; CHECK-NEXT:    ret <vscale x 8 x i32> splat (i32 1)
+;
+  %1 = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
+  ret <vscale x 8 x i32> %1
+}
+
+; Negative test.
+define <vscale x 8 x i32> @fold_scalable_vector_interleave2_mismatch_splat() {
+; CHECK-LABEL: define <vscale x 8 x i32> @fold_scalable_vector_interleave2_mismatch_splat() {
+; CHECK-NEXT:    [[TMP1:%.*]] = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 2))
+; CHECK-NEXT:    ret <vscale x 8 x i32> [[TMP1]]
+;
+  %1 = call <vscale x 8 x i32> @llvm.vector.interleave2.nxv8i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 2))
+  ret <vscale x 8 x i32> %1
+}
+
 define <12 x i32> @fold_vector_interleave3() {
 ; CHECK-LABEL: define <12 x i32> @fold_vector_interleave3() {
 ; CHECK-NEXT:    ret <12 x i32> <i32 1, i32 5, i32 9, i32 2, i32 6, i32 10, i32 3, i32 7, i32 11, i32 4, i32 8, i32 12>
@@ -59,6 +85,22 @@ define <12 x i32> @fold_vector_interleave3() {
   ret <12 x i32> %1
 }
 
+define <vscale x 12 x i32> @fold_scalable_vector_interleave3() {
+; CHECK-LABEL: define <vscale x 12 x i32> @fold_scalable_vector_interleave3() {
+; CHECK-NEXT:    ret <vscale x 12 x i32> zeroinitializer
+;
+  %1 = call <vscale x 12 x i32> @llvm.vector.interleave3.nxv8i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
+  ret <vscale x 12 x i32> %1
+}
+
+define <vscale x 12 x i32> @fold_scalable_vector_interleave3_splat() {
+; CHECK-LABEL: define <vscale x 12 x i32> @fold_scalable_vector_interleave3_splat() {
+; CHECK-NEXT:    ret <vscale x 12 x i32> splat (i32 1)
+;
+  %1 = call <vscale x 12 x i32> @llvm.vector.interleave3.nxv8i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
+  ret <vscale x 12 x i32> %1
+}
+
 define <16 x i32> @fold_vector_interleave4() {
 ; CHECK-LABEL: define <16 x i32> @fold_vector_interleave4() {
 ; CHECK-NEXT:    ret <16 x i32> <i32 1, i32 5, i32 9, i32 13, i32 2, i32 6, i32 10, i32 14, i32 3, i32 7, i32 11, i32 15, i32 4, i32 8, i32 12, i32 16>
@@ -67,6 +109,22 @@ define <16 x i32> @fold_vector_interleave4() {
   ret <16 x i32> %1
 }
 
+define <vscale x 16 x i32> @fold_scalable_vector_interleave4() {
+; CHECK-LABEL: define <vscale x 16 x i32> @fold_scalable_vector_interleave4() {
+; CHECK-NEXT:    ret <vscale x 16 x i32> zeroinitializer
+;
+  %1 = call <vscale x 16 x i32> @llvm.vector.interleave4.nxv16i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
+  ret <vscale x 16 x i32> %1
+}
+
+define <vscale x 16 x i32> @fold_scalable_vector_interleave4_splat() {
+; CHECK-LABEL: define <vscale x 16 x i32> @fold_scalable_vector_interleave4_splat() {
+; CHECK-NEXT:    ret <vscale x 16 x i32> splat (i32 1)
+;
+  %1 = call <vscale x 16 x i32> @llvm.vector.interleave4.nxv16i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
+  ret <vscale x 16 x i32> %1
+}
+
 define <20 x i32> @fold_vector_interleave5() {
 ; CHECK-LABEL: define <20 x i32> @fold_vector_interleave5() {
 ; CHECK-NEXT:    ret <20 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 2, i32 6, i32 10, i32 14, i32 18, i32 3, i32 7, i32 11, i32 15, i32 19, i32 4, i32 8, i32 12, i32 16, i32 20>
@@ -75,6 +133,22 @@ define <20 x i32> @fold_vector_interleave5() {
   ret <20 x i32> %1
 }
 
+define <vscale x 20 x i32> @fold_scalable_vector_interleave5() {
+; CHECK-LABEL: define <vscale x 20 x i32> @fold_scalable_vector_interleave5() {
+; CHECK-NEXT:    ret <vscale x 20 x i32> zeroinitializer
+;
+  %1 = call <vscale x 20 x i32> @llvm.vector.interleave5.nxv20i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
+  ret <vscale x 20 x i32> %1
+}
+
+define <vscale x 20 x i32> @fold_scalable_vector_interleave5_splat() {
+; CHECK-LABEL: define <vscale x 20 x i32> @fold_scalable_vector_interleave5_splat() {
+; CHECK-NEXT:    ret <vscale x 20 x i32> splat (i32 1)
+;
+  %1 = call <vscale x 20 x i32> @llvm.vector.interleave5.nxv20i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
+  ret <vscale x 20 x i32> %1
+}
+
 define <24 x i32> @fold_vector_interleave6() {
 ; CHECK-LABEL: define <24 x i32> @fold_vector_interleave6() {
 ; CHECK-NEXT:    ret <24 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 21, i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 3, i32 7, i32 11, i32 15, i32 19, i32 23, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24>
@@ -83,6 +157,22 @@ define <24 x i32> @fold_vector_interleave6() {
   ret <24 x i32> %1
 }
 
+define <vscale x 24 x i32> @fold_scalable_vector_interleave6() {
+; CHECK-LABEL: define <vscale x 24 x i32> @fold_scalable_vector_interleave6() {
+; CHECK-NEXT:    ret <vscale x 24 x i32> zeroinitializer
+;
+  %1 = call <vscale x 24 x i32> @llvm.vector.interleave6.nxv24i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
+  ret <vscale x 24 x i32> %1
+}
+
+define <vscale x 24 x i32> @fold_scalable_vector_interleave6_splat() {
+; CHECK-LABEL: define <vscale x 24 x i32> @fold_scalable_vector_interleave6_splat() {
+; CHECK-NEXT:    ret <vscale x 24 x i32> splat (i32 1)
+;
+  %1 = call <vscale x 24 x i32> @llvm.vector.interleave6.nxv24i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
+  ret <vscale x 24 x i32> %1
+}
+
 define <28 x i32> @fold_vector_interleave7() {
 ; CHECK-LABEL: define <28 x i32> @fold_vector_interleave7() {
 ; CHECK-NEXT:    ret <28 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 21, i32 25, i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 3, i32 7, i32 11, i32 15, i32 19, i32 23, i32 27, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28>
@@ -91,6 +181,22 @@ define <28 x i32> @fold_vector_interleave7() {
   ret <28 x i32> %1
 }
 
+define <vscale x 28 x i32> @fold_scalable_vector_interleave7() {
+; CHECK-LABEL: define <vscale x 28 x i32> @fold_scalable_vector_interleave7() {
+; CHECK-NEXT:    ret <vscale x 28 x i32> zeroinitializer
+;
+  %1 = call <vscale x 28 x i32> @llvm.vector.interleave7.nxv28i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
+  ret <vscale x 28 x i32> %1
+}
+
+define <vscale x 28 x i32> @fold_scalable_vector_interleave7_splat() {
+; CHECK-LABEL: define <vscale x 28 x i32> @fold_scalable_vector_interleave7_splat() {
+; CHECK-NEXT:    ret <vscale x 28 x i32> splat (i32 1)
+;
+  %1 = call <vscale x 28 x i32> @llvm.vector.interleave7.nxv28i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
+  ret <vscale x 28 x i32> %1
+}
+
 define <32 x i32> @fold_vector_interleave8() {
 ; CHECK-LABEL: define <32 x i32> @fold_vector_interleave8() {
 ; CHECK-NEXT:    ret <32 x i32> <i32 1, i32 5, i32 9, i32 13, i32 17, i32 21, i32 25, i32 29, i32 2, i32 6, i32 10, i32 14, i32 18, i32 22, i32 26, i32 30, i32 3, i32 7, i32 11, i32 15, i32 19, i32 23, i32 27, i32 31, i32 4, i32 8, i32 12, i32 16, i32 20, i32 24, i32 28, i32 32>
@@ -99,6 +205,22 @@ define <32 x i32> @fold_vector_interleave8() {
   ret <32 x i32> %1
 }
 
+define <vscale x 32 x i32> @fold_scalable_vector_interleave8() {
+; CHECK-LABEL: define <vscale x 32 x i32> @fold_scalable_vector_interleave8() {
+; CHECK-NEXT:    ret <vscale x 32 x i32> zeroinitializer
+;
+  %1 = call <vscale x 32 x i32> @llvm.vector.interleave8.nxv32i32(<vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer, <vscale x 4 x i32> zeroinitializer)
+  ret <vscale x 32 x i32> %1
+}
+
+define <vscale x 32 x i32> @fold_scalable_vector_interleave8_splat() {
+; CHECK-LABEL: define <vscale x 32 x i32> @fold_scalable_vector_interleave8_splat() {
+; CHECK-NEXT:    ret <vscale x 32 x i32> splat (i32 1)
+;
+  %1 = call <vscale x 32 x i32> @llvm.vector.interleave8.nxv32i32(<vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1), <vscale x 4 x i32> splat (i32 1))
+  ret <vscale x 32 x i32> %1
+}
+
 define { <4 x i32>, <4 x i32> } @fold_vector_deinterleave2() {
 ; CHECK-LABEL: define { <4 x i32>, <4 x i32> } @fold_vector_deinterleave2() {
 ; CHECK-NEXT:    ret { <4 x i32>, <4 x i32> } { <4 x i32> <i32 1, i32 2, i32 3, i32 4>, <4 x i32> <i32 5, i32 6, i32 7, i32 8> }


        


More information about the llvm-commits mailing list