diff --git a/llvm/lib/CodeGen/InterleavedAccessPass.cpp b/llvm/lib/CodeGen/InterleavedAccessPass.cpp index c2839d4c60680..de6f5add74dbe 100644 --- a/llvm/lib/CodeGen/InterleavedAccessPass.cpp +++ b/llvm/lib/CodeGen/InterleavedAccessPass.cpp @@ -256,7 +256,7 @@ static bool isReInterleaveMask(ShuffleVectorInst *SVI, unsigned &Factor, static Value *getMaskOperand(IntrinsicInst *II) { switch (II->getIntrinsicID()) { default: - llvm_unreachable("Unexpected intrinsic"); + return nullptr; case Intrinsic::vp_load: return II->getOperand(1); case Intrinsic::masked_load: @@ -382,8 +382,11 @@ bool InterleavedAccessImpl::lowerInterleavedLoad( if (LI) { LLVM_DEBUG(dbgs() << "IA: Found an interleaved load: " << *Load << "\n"); } else { + Value *MaskOperand = getMaskOperand(II); + if (!MaskOperand) + llvm_unreachable("unsupported intrinsic"); // Check mask operand. Handle both all-true/false and interleaved mask. - Mask = getMask(getMaskOperand(II), Factor, VecTy); + Mask = getMask(MaskOperand, Factor, VecTy); if (!Mask) return false; @@ -534,10 +537,12 @@ bool InterleavedAccessImpl::lowerInterleavedStore( if (SI) { LLVM_DEBUG(dbgs() << "IA: Found an interleaved store: " << *Store << "\n"); } else { + Value *MaskOperand = getMaskOperand(II); + if (!MaskOperand) + llvm_unreachable("unsupported intrinsic"); // Check mask operand. Handle both all-true/false and interleaved mask. unsigned LaneMaskLen = NumStoredElements / Factor; - Mask = getMask(getMaskOperand(II), Factor, - ElementCount::getFixed(LaneMaskLen)); + Mask = getMask(MaskOperand, Factor, ElementCount::getFixed(LaneMaskLen)); if (!Mask) return false; @@ -634,9 +639,12 @@ bool InterleavedAccessImpl::lowerDeinterleaveIntrinsic( << " and factor = " << Factor << "\n"); } else { assert(II); + Value *MaskOperand = getMaskOperand(II); + if (!MaskOperand) + return false; // Check mask operand. Handle both all-true/false and interleaved mask. - Mask = getMask(getMaskOperand(II), Factor, getDeinterleavedVectorType(DI)); + Mask = getMask(MaskOperand, Factor, getDeinterleavedVectorType(DI)); if (!Mask) return false; @@ -673,8 +681,11 @@ bool InterleavedAccessImpl::lowerInterleaveIntrinsic( Value *Mask = nullptr; if (II) { + Value *MaskOperand = getMaskOperand(II); + if (!MaskOperand) + return false; // Check mask operand. Handle both all-true/false and interleaved mask. - Mask = getMask(getMaskOperand(II), Factor, + Mask = getMask(MaskOperand, Factor, cast(InterleaveValues[0]->getType())); if (!Mask) return false; diff --git a/llvm/test/CodeGen/X86/x86-interleaved-access.ll b/llvm/test/CodeGen/X86/x86-interleaved-access.ll index 7cddebdca5cca..de6b18c134464 100644 --- a/llvm/test/CodeGen/X86/x86-interleaved-access.ll +++ b/llvm/test/CodeGen/X86/x86-interleaved-access.ll @@ -1897,3 +1897,15 @@ define <2 x i64> @PR37616(ptr %a0) nounwind { %shuffle = shufflevector <16 x i64> %load, <16 x i64> undef, <2 x i32> ret <2 x i64> %shuffle } + +define { <8 x float>, <8 x float> } @interleave_deinterleave2() { +; AVX-LABEL: interleave_deinterleave2: +; AVX: # %bb.0: # %.entry +; AVX-NEXT: vxorps %xmm0, %xmm0, %xmm0 +; AVX-NEXT: vxorps %xmm1, %xmm1, %xmm1 +; AVX-NEXT: retq +.entry: + %0 = call <16 x float> @llvm.vector.interleave2.v16f32(<8 x float> zeroinitializer, <8 x float> zeroinitializer) + %1 = call { <8 x float>, <8 x float> } @llvm.vector.deinterleave2.v16f32(<16 x float> %0) + ret { <8 x float>, <8 x float> } %1 +}