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 @fold_scalable_vector_interleave2() { +; CHECK-LABEL: define @fold_scalable_vector_interleave2() { +; CHECK-NEXT: ret zeroinitializer +; + %1 = call @llvm.vector.interleave2.nxv8i32( zeroinitializer, zeroinitializer) + ret %1 +} + +define @fold_scalable_vector_interleave2_splat() { +; CHECK-LABEL: define @fold_scalable_vector_interleave2_splat() { +; CHECK-NEXT: ret splat (i32 1) +; + %1 = call @llvm.vector.interleave2.nxv8i32( splat (i32 1), splat (i32 1)) + ret %1 +} + +; Negative test. +define @fold_scalable_vector_interleave2_mismatch_splat() { +; CHECK-LABEL: define @fold_scalable_vector_interleave2_mismatch_splat() { +; CHECK-NEXT: [[TMP1:%.*]] = call @llvm.vector.interleave2.nxv8i32( splat (i32 1), splat (i32 2)) +; CHECK-NEXT: ret [[TMP1]] +; + %1 = call @llvm.vector.interleave2.nxv8i32( splat (i32 1), splat (i32 2)) + ret %1 +} + define <12 x i32> @fold_vector_interleave3() { ; CHECK-LABEL: define <12 x i32> @fold_vector_interleave3() { ; CHECK-NEXT: ret <12 x i32> @@ -59,6 +85,22 @@ define <12 x i32> @fold_vector_interleave3() { ret <12 x i32> %1 } +define @fold_scalable_vector_interleave3() { +; CHECK-LABEL: define @fold_scalable_vector_interleave3() { +; CHECK-NEXT: ret zeroinitializer +; + %1 = call @llvm.vector.interleave3.nxv8i32( zeroinitializer, zeroinitializer, zeroinitializer) + ret %1 +} + +define @fold_scalable_vector_interleave3_splat() { +; CHECK-LABEL: define @fold_scalable_vector_interleave3_splat() { +; CHECK-NEXT: ret splat (i32 1) +; + %1 = call @llvm.vector.interleave3.nxv8i32( splat (i32 1), splat (i32 1), splat (i32 1)) + ret %1 +} + define <16 x i32> @fold_vector_interleave4() { ; CHECK-LABEL: define <16 x i32> @fold_vector_interleave4() { ; CHECK-NEXT: ret <16 x i32> @@ -67,6 +109,22 @@ define <16 x i32> @fold_vector_interleave4() { ret <16 x i32> %1 } +define @fold_scalable_vector_interleave4() { +; CHECK-LABEL: define @fold_scalable_vector_interleave4() { +; CHECK-NEXT: ret zeroinitializer +; + %1 = call @llvm.vector.interleave4.nxv16i32( zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer) + ret %1 +} + +define @fold_scalable_vector_interleave4_splat() { +; CHECK-LABEL: define @fold_scalable_vector_interleave4_splat() { +; CHECK-NEXT: ret splat (i32 1) +; + %1 = call @llvm.vector.interleave4.nxv16i32( splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1)) + ret %1 +} + define <20 x i32> @fold_vector_interleave5() { ; CHECK-LABEL: define <20 x i32> @fold_vector_interleave5() { ; CHECK-NEXT: ret <20 x i32> @@ -75,6 +133,22 @@ define <20 x i32> @fold_vector_interleave5() { ret <20 x i32> %1 } +define @fold_scalable_vector_interleave5() { +; CHECK-LABEL: define @fold_scalable_vector_interleave5() { +; CHECK-NEXT: ret zeroinitializer +; + %1 = call @llvm.vector.interleave5.nxv20i32( zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer) + ret %1 +} + +define @fold_scalable_vector_interleave5_splat() { +; CHECK-LABEL: define @fold_scalable_vector_interleave5_splat() { +; CHECK-NEXT: ret splat (i32 1) +; + %1 = call @llvm.vector.interleave5.nxv20i32( splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1)) + ret %1 +} + define <24 x i32> @fold_vector_interleave6() { ; CHECK-LABEL: define <24 x i32> @fold_vector_interleave6() { ; CHECK-NEXT: ret <24 x i32> @@ -83,6 +157,22 @@ define <24 x i32> @fold_vector_interleave6() { ret <24 x i32> %1 } +define @fold_scalable_vector_interleave6() { +; CHECK-LABEL: define @fold_scalable_vector_interleave6() { +; CHECK-NEXT: ret zeroinitializer +; + %1 = call @llvm.vector.interleave6.nxv24i32( zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer) + ret %1 +} + +define @fold_scalable_vector_interleave6_splat() { +; CHECK-LABEL: define @fold_scalable_vector_interleave6_splat() { +; CHECK-NEXT: ret splat (i32 1) +; + %1 = call @llvm.vector.interleave6.nxv24i32( splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1)) + ret %1 +} + define <28 x i32> @fold_vector_interleave7() { ; CHECK-LABEL: define <28 x i32> @fold_vector_interleave7() { ; CHECK-NEXT: ret <28 x i32> @@ -91,6 +181,22 @@ define <28 x i32> @fold_vector_interleave7() { ret <28 x i32> %1 } +define @fold_scalable_vector_interleave7() { +; CHECK-LABEL: define @fold_scalable_vector_interleave7() { +; CHECK-NEXT: ret zeroinitializer +; + %1 = call @llvm.vector.interleave7.nxv28i32( zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer) + ret %1 +} + +define @fold_scalable_vector_interleave7_splat() { +; CHECK-LABEL: define @fold_scalable_vector_interleave7_splat() { +; CHECK-NEXT: ret splat (i32 1) +; + %1 = call @llvm.vector.interleave7.nxv28i32( splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1)) + ret %1 +} + define <32 x i32> @fold_vector_interleave8() { ; CHECK-LABEL: define <32 x i32> @fold_vector_interleave8() { ; CHECK-NEXT: ret <32 x i32> @@ -99,6 +205,22 @@ define <32 x i32> @fold_vector_interleave8() { ret <32 x i32> %1 } +define @fold_scalable_vector_interleave8() { +; CHECK-LABEL: define @fold_scalable_vector_interleave8() { +; CHECK-NEXT: ret zeroinitializer +; + %1 = call @llvm.vector.interleave8.nxv32i32( zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer, zeroinitializer) + ret %1 +} + +define @fold_scalable_vector_interleave8_splat() { +; CHECK-LABEL: define @fold_scalable_vector_interleave8_splat() { +; CHECK-NEXT: ret splat (i32 1) +; + %1 = call @llvm.vector.interleave8.nxv32i32( splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1), splat (i32 1)) + ret %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> , <4 x i32> }