[llvm] r294818 - [ARM] Don't lower f16 interleaved accesses.

Ahmed Bougacha via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 10 17:53:01 PST 2017


Author: ab
Date: Fri Feb 10 19:53:00 2017
New Revision: 294818

URL: http://llvm.org/viewvc/llvm-project?rev=294818&view=rev
Log:
[ARM] Don't lower f16 interleaved accesses.

There are no vldN/vstN f16 variants, even with +fullfp16.
We could use the i16 variants, but, in practice, even with +fullfp16,
the f16 sequence leading to the i16 shuffle usually gets scalarized.
We'd need to improve our support for f16 codegen before getting there.

Reject f16 interleaved accesses.  If we try to emit the f16 intrinsics,
we'll just end up with a selection failure.

Modified:
    llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
    llvm/trunk/test/Transforms/InterleavedAccess/ARM/interleaved-accesses.ll

Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=294818&r1=294817&r2=294818&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Fri Feb 10 19:53:00 2017
@@ -13290,6 +13290,11 @@ bool ARMTargetLowering::lowerInterleaved
   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::lowerInterleaved
   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::lowerInterleaved
       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::lowerInterleaved
   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);

Modified: llvm/trunk/test/Transforms/InterleavedAccess/ARM/interleaved-accesses.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InterleavedAccess/ARM/interleaved-accesses.ll?rev=294818&r1=294817&r2=294818&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InterleavedAccess/ARM/interleaved-accesses.ll (original)
+++ llvm/trunk/test/Transforms/InterleavedAccess/ARM/interleaved-accesses.ll Fri Feb 10 19:53:00 2017
@@ -387,6 +387,27 @@ define void @store_address_space(<4 x i3
   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




More information about the llvm-commits mailing list