aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2010-09-01 23:20:27 +0000
committerBob Wilson <bob.wilson@apple.com>2010-09-01 23:20:27 +0000
commitbf346e95f1d60f37fb37d89c288e1daa7839fc01 (patch)
tree0b91d269ba123ab826dd1e0ced521e141270d18d /lib/CodeGen
parentc6a518a7271bbd6d0f606ba5c1b1b9c668bbdcb0 (diff)
Translate NEON vmull, vmlal, and vmlsl builtins to llvm multiply-add/sub
with zext/sext operations, instead of to llvm intrinsics. I have a plan to avoid the clang builtins for these, but it is going to take a little longer and I want to get the NEON intrinsics updated before the 2.8 release. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112764 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGBuiltin.cpp42
1 files changed, 32 insertions, 10 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 08993c30e8..9c858e4a93 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -1406,15 +1406,29 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
Int = usgn ? Intrinsic::arm_neon_vminu : Intrinsic::arm_neon_vmins;
return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmin");
case ARM::BI__builtin_neon_vmlal_lane_v:
- splat = true;
+ Ops[2] = EmitNeonSplat(Ops[2], cast<Constant>(Ops[3]));
case ARM::BI__builtin_neon_vmlal_v:
- Int = usgn ? Intrinsic::arm_neon_vmlalu : Intrinsic::arm_neon_vmlals;
- return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlal", splat);
+ if (usgn) {
+ Ops[1] = Builder.CreateZExt(Ops[1], Ty);
+ Ops[2] = Builder.CreateZExt(Ops[2], Ty);
+ } else {
+ Ops[1] = Builder.CreateSExt(Ops[1], Ty);
+ Ops[2] = Builder.CreateSExt(Ops[2], Ty);
+ }
+ Ops[1] = Builder.CreateMul(Ops[1], Ops[2]);
+ return Builder.CreateAdd(Ops[0], Ops[1], "vmlal");
case ARM::BI__builtin_neon_vmlsl_lane_v:
- splat = true;
+ Ops[2] = EmitNeonSplat(Ops[2], cast<Constant>(Ops[3]));
case ARM::BI__builtin_neon_vmlsl_v:
- Int = usgn ? Intrinsic::arm_neon_vmlslu : Intrinsic::arm_neon_vmlsls;
- return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlsl", splat);
+ if (usgn) {
+ Ops[1] = Builder.CreateZExt(Ops[1], Ty);
+ Ops[2] = Builder.CreateZExt(Ops[2], Ty);
+ } else {
+ Ops[1] = Builder.CreateSExt(Ops[1], Ty);
+ Ops[2] = Builder.CreateSExt(Ops[2], Ty);
+ }
+ Ops[1] = Builder.CreateMul(Ops[1], Ops[2]);
+ return Builder.CreateSub(Ops[0], Ops[1], "vmlsl");
case ARM::BI__builtin_neon_vmovl_v:
if (usgn)
return Builder.CreateZExt(Ops[0], Ty, "vmovl");
@@ -1422,11 +1436,19 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
case ARM::BI__builtin_neon_vmovn_v:
return Builder.CreateTrunc(Ops[0], Ty, "vmovn");
case ARM::BI__builtin_neon_vmull_lane_v:
- splat = true;
+ Ops[1] = EmitNeonSplat(Ops[1], cast<Constant>(Ops[2]));
case ARM::BI__builtin_neon_vmull_v:
- Int = usgn ? Intrinsic::arm_neon_vmullu : Intrinsic::arm_neon_vmulls;
- Int = poly ? (unsigned)Intrinsic::arm_neon_vmullp : Int;
- return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vmlal", splat);
+ if (poly)
+ return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vmullp, &Ty, 1),
+ Ops, "vmull");
+ if (usgn) {
+ Ops[0] = Builder.CreateZExt(Ops[0], Ty);
+ Ops[1] = Builder.CreateZExt(Ops[1], Ty);
+ } else {
+ Ops[0] = Builder.CreateSExt(Ops[0], Ty);
+ Ops[1] = Builder.CreateSExt(Ops[1], Ty);
+ }
+ return Builder.CreateMul(Ops[0], Ops[1], "vmull");
case ARM::BI__builtin_neon_vpadal_v:
case ARM::BI__builtin_neon_vpadalq_v:
Int = usgn ? Intrinsic::arm_neon_vpadalu : Intrinsic::arm_neon_vpadals;