diff options
author | dim <dim@FreeBSD.org> | 2012-08-19 10:33:04 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2012-08-19 10:33:04 +0000 |
commit | cc73504950eb7b5dff2dded9bedd67bc36d64641 (patch) | |
tree | 5b9c2fa9d79942fbdce3d618e37e27c18263af9a /lib/CodeGen/CGBuiltin.cpp | |
parent | 554bcb69c2d785a011a30e7db87a36a87fe7db10 (diff) | |
download | FreeBSD-src-cc73504950eb7b5dff2dded9bedd67bc36d64641.zip FreeBSD-src-cc73504950eb7b5dff2dded9bedd67bc36d64641.tar.gz |
Vendor import of clang trunk r162107:
http://llvm.org/svn/llvm-project/cfe/trunk@162107
Diffstat (limited to 'lib/CodeGen/CGBuiltin.cpp')
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 65c782e..59ed313 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -229,6 +229,35 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, return RValue::get(Result); } + + case Builtin::BI__builtin_conj: + case Builtin::BI__builtin_conjf: + case Builtin::BI__builtin_conjl: { + ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); + Value *Real = ComplexVal.first; + Value *Imag = ComplexVal.second; + Value *Zero = + Imag->getType()->isFPOrFPVectorTy() + ? llvm::ConstantFP::getZeroValueForNegation(Imag->getType()) + : llvm::Constant::getNullValue(Imag->getType()); + + Imag = Builder.CreateFSub(Zero, Imag, "sub"); + return RValue::getComplex(std::make_pair(Real, Imag)); + } + case Builtin::BI__builtin_creal: + case Builtin::BI__builtin_crealf: + case Builtin::BI__builtin_creall: { + ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); + return RValue::get(ComplexVal.first); + } + + case Builtin::BI__builtin_cimag: + case Builtin::BI__builtin_cimagf: + case Builtin::BI__builtin_cimagl: { + ComplexPairTy ComplexVal = EmitComplexExpr(E->getArg(0)); + return RValue::get(ComplexVal.second); + } + case Builtin::BI__builtin_ctzs: case Builtin::BI__builtin_ctz: case Builtin::BI__builtin_ctzl: @@ -1720,8 +1749,29 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, Ops.push_back(GetPointeeAlignmentValue(E->getArg(0))); return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty), Ops, "vld1"); - case ARM::BI__builtin_neon_vld1_lane_v: - case ARM::BI__builtin_neon_vld1q_lane_v: { + case ARM::BI__builtin_neon_vld1q_lane_v: + // Handle 64-bit integer elements as a special case. Use shuffles of + // one-element vectors to avoid poor code for i64 in the backend. + if (VTy->getElementType()->isIntegerTy(64)) { + // Extract the other lane. + Ops[1] = Builder.CreateBitCast(Ops[1], Ty); + int Lane = cast<ConstantInt>(Ops[2])->getZExtValue(); + Value *SV = llvm::ConstantVector::get(ConstantInt::get(Int32Ty, 1-Lane)); + Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); + // Load the value as a one-element vector. + Ty = llvm::VectorType::get(VTy->getElementType(), 1); + Function *F = CGM.getIntrinsic(Intrinsic::arm_neon_vld1, Ty); + Value *Ld = Builder.CreateCall2(F, Ops[0], + GetPointeeAlignmentValue(E->getArg(0))); + // Combine them. + SmallVector<Constant*, 2> Indices; + Indices.push_back(ConstantInt::get(Int32Ty, 1-Lane)); + Indices.push_back(ConstantInt::get(Int32Ty, Lane)); + SV = llvm::ConstantVector::get(Indices); + return Builder.CreateShuffleVector(Ops[1], Ld, SV, "vld1q_lane"); + } + // fall through + case ARM::BI__builtin_neon_vld1_lane_v: { Ops[1] = Builder.CreateBitCast(Ops[1], Ty); Ty = llvm::PointerType::getUnqual(VTy->getElementType()); Ops[0] = Builder.CreateBitCast(Ops[0], Ty); @@ -2086,8 +2136,19 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID, Ops.push_back(GetPointeeAlignmentValue(E->getArg(0))); return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, Ty), Ops, ""); - case ARM::BI__builtin_neon_vst1_lane_v: - case ARM::BI__builtin_neon_vst1q_lane_v: { + case ARM::BI__builtin_neon_vst1q_lane_v: + // Handle 64-bit integer elements as a special case. Use a shuffle to get + // a one-element vector and avoid poor code for i64 in the backend. + if (VTy->getElementType()->isIntegerTy(64)) { + Ops[1] = Builder.CreateBitCast(Ops[1], Ty); + Value *SV = llvm::ConstantVector::get(cast<llvm::Constant>(Ops[2])); + Ops[1] = Builder.CreateShuffleVector(Ops[1], Ops[1], SV); + Ops[2] = GetPointeeAlignmentValue(E->getArg(0)); + return Builder.CreateCall(CGM.getIntrinsic(Intrinsic::arm_neon_vst1, + Ops[1]->getType()), Ops); + } + // fall through + case ARM::BI__builtin_neon_vst1_lane_v: { Ops[1] = Builder.CreateBitCast(Ops[1], Ty); Ops[1] = Builder.CreateExtractElement(Ops[1], Ops[2]); Ty = llvm::PointerType::getUnqual(Ops[1]->getType()); |