Clang and AArch64 backend patches to support shll/shl and vmovl instructions and ACLE functions
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188452 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index d1dd7a0..def818f 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -1620,6 +1620,37 @@
llvm_unreachable("Invalid NeonTypeFlags element type!");
}
+static Value *EmitExtendedSHL(CodeGenFunction &CGF,
+ SmallVectorImpl<Value*> &Ops,
+ llvm::VectorType *VTy, bool usgn, bool isHigh) {
+ IRBuilder<> Builder = CGF.Builder;
+ if (isHigh){
+ unsigned NumElts = VTy->getNumElements();
+ unsigned EltBits = VTy->getElementType()->getPrimitiveSizeInBits();
+ llvm::Type *EltTy =
+ llvm::IntegerType::get(VTy->getContext(), EltBits / 2);
+ // The source operand type has twice as many elements of half the size.
+ llvm::Type *SrcTy = llvm::VectorType::get(EltTy, NumElts * 2);
+ SmallVector<Constant*, 8> Indices;
+ for (unsigned i = 0; i != NumElts; i++)
+ Indices.push_back(Builder.getInt32(i + NumElts));
+ Value *SV = llvm::ConstantVector::get(Indices);
+ Value *Undef = llvm::UndefValue::get(SrcTy);
+ Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
+ Ops[0] = Builder.CreateShuffleVector(Ops[0], Undef, SV);
+ } else {
+ llvm::Type *SrcTy = llvm::VectorType::getTruncatedElementVectorType(VTy);
+ Ops[0] = Builder.CreateBitCast(Ops[0], SrcTy);
+ }
+
+ if (usgn)
+ Ops[0] = Builder.CreateZExt(Ops[0], VTy);
+ else
+ Ops[0] = Builder.CreateSExt(Ops[0], VTy);
+ Ops[1] = CGF.EmitNeonShiftVector(Ops[1], VTy, false);
+ return Builder.CreateShl(Ops[0], Ops[1], "vshl_n");
+}
+
Value *CodeGenFunction::EmitNeonSplat(Value *V, Constant *C) {
unsigned nElts = cast<llvm::VectorType>(V->getType())->getNumElements();
Value* SV = llvm::ConstantVector::getSplat(nElts, C);
@@ -1862,6 +1893,18 @@
return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrdmulh_v, E);
case AArch64::BI__builtin_neon_vqrdmulhq_v:
return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vqrdmulhq_v, E);
+ case AArch64::BI__builtin_neon_vshl_n_v:
+ return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshl_n_v, E);
+ case AArch64::BI__builtin_neon_vshlq_n_v:
+ return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vshlq_n_v, E);
+ case AArch64::BI__builtin_neon_vmovl_v:
+ return EmitARMBuiltinExpr(ARM::BI__builtin_neon_vmovl_v, E);
+ case AArch64::BI__builtin_neon_vshll_n_v:
+ return EmitExtendedSHL(*this, Ops, VTy, usgn, false);
+ case AArch64::BI__builtin_neon_vmovl_high_v:
+ Ops.push_back(ConstantInt::get(Int32Ty, 0));
+ case AArch64::BI__builtin_neon_vshll_high_n_v:
+ return EmitExtendedSHL(*this, Ops, VTy, usgn, true);
// AArch64-only builtins
case AArch64::BI__builtin_neon_vfms_v: