diff --git a/llvm/lib/Analysis/ConstantFolding.cpp b/llvm/lib/Analysis/ConstantFolding.cpp index da32542cf7870..a13df6c5bf552 100755 --- a/llvm/lib/Analysis/ConstantFolding.cpp +++ b/llvm/lib/Analysis/ConstantFolding.cpp @@ -1659,6 +1659,12 @@ bool llvm::canConstantFoldCallTo(const CallBase *Call, const Function *F) { case Intrinsic::vector_extract: case Intrinsic::vector_insert: 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: case Intrinsic::vector_deinterleave2: // Target intrinsics case Intrinsic::amdgcn_perm: @@ -4207,16 +4213,23 @@ static Constant *ConstantFoldFixedVectorCall( } return ConstantVector::get(Result); } - case Intrinsic::vector_interleave2: { + 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: { unsigned NumElements = cast(Operands[0]->getType())->getNumElements(); + unsigned NumOperands = Operands.size(); for (unsigned I = 0; I < NumElements; ++I) { - Constant *Elt0 = Operands[0]->getAggregateElement(I); - Constant *Elt1 = Operands[1]->getAggregateElement(I); - if (!Elt0 || !Elt1) - return nullptr; - Result[2 * I] = Elt0; - Result[2 * I + 1] = Elt1; + for (unsigned J = 0; J < NumOperands; ++J) { + Constant *Elt = Operands[J]->getAggregateElement(I); + if (!Elt) + return nullptr; + Result[NumOperands * I + J] = Elt; + } } return ConstantVector::get(Result); } diff --git a/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll b/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll index 14543f339db5d..848f0d17ff373 100644 --- a/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll +++ b/llvm/test/Transforms/InstSimplify/ConstProp/vector-calls.ll @@ -51,6 +51,54 @@ define <8 x i32> @fold_vector_interleave2() { ret <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> +; + %1 = call <12 x i32> @llvm.vector.interleave3.v12i32(<4 x i32> , <4 x i32> , <4 x i32> ) + ret <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> +; + %1 = call <16 x i32> @llvm.vector.interleave4.v16i32(<4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> ) + ret <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> +; + %1 = call <20 x i32> @llvm.vector.interleave5.v20i32(<4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> ) + ret <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> +; + %1 = call <24 x i32> @llvm.vector.interleave6.v24i32(<4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> ) + ret <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> +; + %1 = call <28 x i32> @llvm.vector.interleave7.v28i32(<4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> ) + ret <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> +; + %1 = call <32 x i32> @llvm.vector.interleave8.v32i32(<4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> , <4 x i32> ) + ret <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> , <4 x i32> }