Translate NEON vaddl, vaddw, vsubl, and vsubw builtins to llvm add/sub
with zext/sext operations, instead of to llvm intrinsics.  (We can also
get rid of the clang builtins and handle these entirely in the arm_neon.h
header if there is a way to express vector sext/zext in C.)


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@112413 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 3a4d0fa..279b685 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -1149,11 +1149,20 @@
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vaddhn, &Ty, 1),
                         Ops, "vaddhn");
   case ARM::BI__builtin_neon_vaddl_v:
-    Int = usgn ? Intrinsic::arm_neon_vaddlu : Intrinsic::arm_neon_vaddls;
-    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaddl");
+    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.CreateAdd(Ops[0], Ops[1], "vaddl");
   case ARM::BI__builtin_neon_vaddw_v:
-    Int = usgn ? Intrinsic::arm_neon_vaddws : Intrinsic::arm_neon_vaddwu;
-    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vaddw");
+    if (usgn)
+      Ops[1] = Builder.CreateZExt(Ops[1], Ty);
+    else
+      Ops[1] = Builder.CreateSExt(Ops[1], Ty);
+    return Builder.CreateAdd(Ops[0], Ops[1], "vaddw");
   case ARM::BI__builtin_neon_vcale_v:
     std::swap(Ops[0], Ops[1]);
   case ARM::BI__builtin_neon_vcage_v: {
@@ -1660,11 +1669,20 @@
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vsubhn, &Ty, 1),
                         Ops, "vsubhn");
   case ARM::BI__builtin_neon_vsubl_v:
-    Int = usgn ? Intrinsic::arm_neon_vsublu : Intrinsic::arm_neon_vsubls;
-    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vsubl");
+    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.CreateSub(Ops[0], Ops[1], "vsubl");
   case ARM::BI__builtin_neon_vsubw_v:
-    Int = usgn ? Intrinsic::arm_neon_vsubws : Intrinsic::arm_neon_vsubwu;
-    return EmitNeonCall(CGM.getIntrinsic(Int, &Ty, 1), Ops, "vsubw");
+    if (usgn)
+      Ops[1] = Builder.CreateZExt(Ops[1], Ty);
+    else
+      Ops[1] = Builder.CreateSExt(Ops[1], Ty);
+    return Builder.CreateSub(Ops[0], Ops[1], "vsubw");
   case ARM::BI__builtin_neon_vtbl1_v:
     return EmitNeonCall(CGM.getIntrinsic(Intrinsic::arm_neon_vtbl1),
                         Ops, "vtbl1");