]> granicus.if.org Git - clang/commitdiff
Translate NEON vmull, vmlal, and vmlsl builtins to llvm multiply-add/sub
authorBob Wilson <bob.wilson@apple.com>
Wed, 1 Sep 2010 23:20:27 +0000 (23:20 +0000)
committerBob Wilson <bob.wilson@apple.com>
Wed, 1 Sep 2010 23:20:27 +0000 (23:20 +0000)
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

lib/CodeGen/CGBuiltin.cpp

index 08993c30e8ea6922e8f9a688c9ce0b55ac165696..9c858e4a935503c462f1324e11f599c3ff7ac08c 100644 (file)
@@ -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;