Index: lib/CodeGen/CGBuiltin.cpp
===================================================================
--- lib/CodeGen/CGBuiltin.cpp	(revision 98541)
+++ lib/CodeGen/CGBuiltin.cpp	(working copy)
@@ -1004,5 +1004,133 @@
 
 Value *CodeGenFunction::EmitPPCBuiltinExpr(unsigned BuiltinID,
                                            const CallExpr *E) {
+  llvm::SmallVector<Value*, 4> Ops;
+
+  for (unsigned i = 0, e = E->getNumArgs(); i != e; i++)
+    Ops.push_back(EmitScalarExpr(E->getArg(i)));
+
+  switch (BuiltinID) {
+  default: return 0;
+
+  // vec_add
+  case PPC::BI__builtin_altivec_vaddubm:
+  case PPC::BI__builtin_altivec_vadduhm:
+  case PPC::BI__builtin_altivec_vadduwm:
+  case PPC::BI__builtin_altivec_vaddfp:
+    return Builder.CreateAdd(Ops[0], Ops[1], "vadd");
+
+  // vec_adds
+  case PPC::BI__builtin_altivec_vaddsbs:
+  case PPC::BI__builtin_altivec_vaddshs:
+  case PPC::BI__builtin_altivec_vaddsws:
+  case PPC::BI__builtin_altivec_vaddubs:
+  case PPC::BI__builtin_altivec_vadduhs:
+  case PPC::BI__builtin_altivec_vadduws:
+  {
+    const char *name = 0;
+    Intrinsic::ID ID = Intrinsic::not_intrinsic;
+    switch (BuiltinID) {
+    default: assert(0 && "Unsupported vavg intrinsic!");
+    case PPC::BI__builtin_altivec_vaddsbs:
+      name = "vaddsbs";
+      ID = Intrinsic::ppc_altivec_vaddsbs;
+      break;
+    case PPC::BI__builtin_altivec_vaddshs:
+      name = "vaddshs";
+      ID = Intrinsic::ppc_altivec_vaddshs;
+      break;
+    case PPC::BI__builtin_altivec_vaddsws:
+      name = "vaddsws";
+      ID = Intrinsic::ppc_altivec_vaddsws;
+      break;
+    case PPC::BI__builtin_altivec_vaddubs:
+      name = "vaddubs";
+      ID = Intrinsic::ppc_altivec_vaddubs;
+      break;
+    case PPC::BI__builtin_altivec_vadduhs:
+      name = "vadduhs";
+      ID = Intrinsic::ppc_altivec_vadduhs;
+      break;
+    case PPC::BI__builtin_altivec_vadduws:
+      name = "vadduws";
+      ID = Intrinsic::ppc_altivec_vadduws;
+      break;
+    }
+    llvm::Function *F = CGM.getIntrinsic(ID);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
+  }
+
+  // vec_sub
+  case PPC::BI__builtin_altivec_vsububm:
+  case PPC::BI__builtin_altivec_vsubuhm:
+  case PPC::BI__builtin_altivec_vsubuwm:
+  case PPC::BI__builtin_altivec_vsubfp:
+    return Builder.CreateSub(Ops[0], Ops[1], "vsub");
+
+  // vec_subs
+  case PPC::BI__builtin_altivec_vsubsbs:
+  case PPC::BI__builtin_altivec_vsubshs:
+  case PPC::BI__builtin_altivec_vsubsws:
+  case PPC::BI__builtin_altivec_vsububs:
+  case PPC::BI__builtin_altivec_vsubuhs:
+  case PPC::BI__builtin_altivec_vsubuws:
+  {
+    const char *name = 0;
+    Intrinsic::ID ID = Intrinsic::not_intrinsic;
+    switch (BuiltinID) {
+    default: assert(0 && "Unsupported vavg intrinsic!");
+    case PPC::BI__builtin_altivec_vsubsbs:
+      name = "vsubsbs";
+      ID = Intrinsic::ppc_altivec_vsubsbs;
+      break;
+    case PPC::BI__builtin_altivec_vsubshs:
+      name = "vsubshs";
+      ID = Intrinsic::ppc_altivec_vsubshs;
+      break;
+    case PPC::BI__builtin_altivec_vsubsws:
+      name = "vsubsws";
+      ID = Intrinsic::ppc_altivec_vsubsws;
+      break;
+    case PPC::BI__builtin_altivec_vsububs:
+      name = "vsububs";
+      ID = Intrinsic::ppc_altivec_vsububs;
+      break;
+    case PPC::BI__builtin_altivec_vsubuhs:
+      name = "vsubuhs";
+      ID = Intrinsic::ppc_altivec_vsubuhs;
+      break;
+    case PPC::BI__builtin_altivec_vsubuws:
+      name = "vsubuws";
+      ID = Intrinsic::ppc_altivec_vsubuws;
+      break;
+    }
+    llvm::Function *F = CGM.getIntrinsic(ID);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), name);
+  }
+
+  // vec_st
+  case PPC::BI__builtin_altivec_stvx:
+  case PPC::BI__builtin_altivec_stvxl:
+  {
+    Ops[2] = Builder.CreateBitCast(Ops[2], llvm::Type::getInt8PtrTy(VMContext));
+    Ops[1] = !isa<Constant>(Ops[1]) || !cast<Constant>(Ops[1])->isNullValue()
+           ? Builder.CreateGEP(Ops[2], Ops[1], "tmp") : Ops[2];
+    Ops.pop_back();
+
+    Intrinsic::ID ID = Intrinsic::not_intrinsic;
+
+    switch (BuiltinID) {
+    default: assert(0 && "Unsupported vavg intrinsic!");
+    case PPC::BI__builtin_altivec_stvx:
+      ID = Intrinsic::ppc_altivec_stvx;
+      break;
+    case PPC::BI__builtin_altivec_stvxl:
+      ID = Intrinsic::ppc_altivec_stvxl;
+      break;
+    }
+    llvm::Function *F = CGM.getIntrinsic(ID);
+    return Builder.CreateCall(F, &Ops[0], &Ops[0] + Ops.size(), "");
+  }
+  }
   return 0;
 }
