diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 14 | ||||
| -rw-r--r-- | llvm/test/Transforms/InterleavedAccess/ARM/interleaved-accesses.ll | 21 |
2 files changed, 35 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 4ef58e1e178..6e674d96db3 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -13290,6 +13290,11 @@ bool ARMTargetLowering::lowerInterleavedLoad( if (!Subtarget->hasNEON() || (VecSize != 64 && VecSize != 128) || EltIs64Bits) return false; + // Skip if the vector has f16 elements: even though we could do an i16 vldN, + // we can't hold the f16 vectors and will end up converting via f32. + if (EltTy->isHalfTy()) + return false; + // A pointer vector can not be the return type of the ldN intrinsics. Need to // load integer vectors first and then convert to pointer vectors. if (EltTy->isPointerTy()) @@ -13307,6 +13312,8 @@ bool ARMTargetLowering::lowerInterleavedLoad( Ops.push_back(Builder.CreateBitCast(LI->getPointerOperand(), Int8Ptr)); Ops.push_back(Builder.getInt32(LI->getAlignment())); + assert(isTypeLegal(EVT::getEVT(VecTy)) && "Illegal vldN vector type!"); + Type *Tys[] = { VecTy, Int8Ptr }; Function *VldnFunc = Intrinsic::getDeclaration(LI->getModule(), LoadInts[Factor - 2], Tys); @@ -13380,6 +13387,11 @@ bool ARMTargetLowering::lowerInterleavedStore(StoreInst *SI, EltIs64Bits) return false; + // Skip if the vector has f16 elements: even though we could do an i16 vldN, + // we can't hold the f16 vectors and will end up converting via f32. + if (EltTy->isHalfTy()) + return false; + Value *Op0 = SVI->getOperand(0); Value *Op1 = SVI->getOperand(1); IRBuilder<> Builder(SI); @@ -13406,6 +13418,8 @@ bool ARMTargetLowering::lowerInterleavedStore(StoreInst *SI, Type *Int8Ptr = Builder.getInt8PtrTy(SI->getPointerAddressSpace()); Ops.push_back(Builder.CreateBitCast(SI->getPointerOperand(), Int8Ptr)); + assert(isTypeLegal(EVT::getEVT(SubVecTy)) && "Illegal vstN vector type!"); + Type *Tys[] = { Int8Ptr, SubVecTy }; Function *VstNFunc = Intrinsic::getDeclaration( SI->getModule(), StoreInts[Factor - 2], Tys); diff --git a/llvm/test/Transforms/InterleavedAccess/ARM/interleaved-accesses.ll b/llvm/test/Transforms/InterleavedAccess/ARM/interleaved-accesses.ll index 3a0bc04f503..1d747d12704 100644 --- a/llvm/test/Transforms/InterleavedAccess/ARM/interleaved-accesses.ll +++ b/llvm/test/Transforms/InterleavedAccess/ARM/interleaved-accesses.ll @@ -387,6 +387,27 @@ define void @store_address_space(<4 x i32> addrspace(1)* %ptr, <2 x i32> %v0, <2 ret void } +define void @load_f16_factor2(<8 x half>* %ptr) { +; ALL-LABEL: @load_f16_factor2( +; ALL-NOT: @llvm.arm.neon +; ALL: ret void +; + %interleaved.vec = load <8 x half>, <8 x half>* %ptr, align 4 + %v0 = shufflevector <8 x half> %interleaved.vec, <8 x half> undef, <4 x i32> <i32 0, i32 2, i32 4, i32 6> + %v1 = shufflevector <8 x half> %interleaved.vec, <8 x half> undef, <4 x i32> <i32 1, i32 3, i32 5, i32 7> + ret void +} + +define void @store_f16_factor2(<8 x half>* %ptr, <4 x half> %v0, <4 x half> %v1) { +; ALL-LABEL: @store_f16_factor2( +; ALL-NOT: @llvm.arm.neon +; ALL: ret void +; + %interleaved.vec = shufflevector <4 x half> %v0, <4 x half> %v1, <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7> + store <8 x half> %interleaved.vec, <8 x half>* %ptr, align 4 + ret void +} + define void @load_illegal_factor2(<3 x float>* %ptr) nounwind { ; ALL-LABEL: @load_illegal_factor2( ; ALL-NOT: @llvm.arm.neon |

