Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp	(revision 175389)
+++ lib/CodeGen/TargetInfo.cpp	(working copy)
@@ -4792,7 +4792,37 @@
   return AddrTyped;
 }
 
+//===----------------------------------------------------------------------===//
+// SPIR ABI Implementation
+//===----------------------------------------------------------------------===//
 
+namespace {
+
+class SPIRTargetCodeGenInfo : public TargetCodeGenInfo {
+public:
+  SPIRTargetCodeGenInfo(CodeGenTypes &CGT)
+    : TargetCodeGenInfo(new DefaultABIInfo(CGT)) {}
+    
+  virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                                   CodeGen::CodeGenModule &M) const;
+};
+
+void SPIRTargetCodeGenInfo::
+SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+                    CodeGen::CodeGenModule &M) const{
+  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+  if (!FD) return;
+
+  llvm::Function *F = cast<llvm::Function>(GV);
+
+  if (FD->hasAttr<OpenCLKernelAttr>())
+    F->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
+  else
+    F->setCallingConv(llvm::CallingConv::SPIR_FUNC);
+}
+
+}
+
 const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
   if (TheTargetCodeGenInfo)
     return *TheTargetCodeGenInfo;
@@ -4907,5 +4937,8 @@
   }
   case llvm::Triple::hexagon:
     return *(TheTargetCodeGenInfo = new HexagonTargetCodeGenInfo(Types));
+  case llvm::Triple::spir:
+  case llvm::Triple::spir64:
+    return *(TheTargetCodeGenInfo = new SPIRTargetCodeGenInfo(Types));
   }
 }
Index: test/CodeGenOpenCL/spir-abi.cl
===================================================================
--- test/CodeGenOpenCL/spir-abi.cl	(revision 0)
+++ test/CodeGenOpenCL/spir-abi.cl	(revision 0)
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 %s -triple "spir-unknown-unknown" -emit-llvm -o - -O0 | FileCheck %s
+// RUN: %clang_cc1 %s -triple "spir64-unknown-unknown" -emit-llvm -o - -O0 | FileCheck %s
+
+typedef struct {
+  int i;
+} small_struct;
+
+typedef struct {
+  int i[256];
+} big_struct;
+
+typedef __attribute__(( ext_vector_type(2) )) short short2;
+typedef __attribute__(( ext_vector_type(2) )) float float2;
+typedef __attribute__(( ext_vector_type(4) )) float float4;
+typedef __attribute__(( ext_vector_type(16) )) long long16;
+
+small_struct foo1(small_struct st) { return st; }
+// CHECK: define cc75 void @foo1(%struct.small_struct* noalias sret %agg.result, %struct.small_struct* byval %st)
+
+big_struct foo2(big_struct st) { return st; }
+// CHECK: define cc75 void @foo2(%struct.big_struct* noalias sret %agg.result, %struct.big_struct* byval %st)
+
+char foo3(char c) { return c; }
+// CHECK: define cc75 signext i8 @foo3(i8 signext %c)
+
+long foo4(long l) { return l; }
+// CHECK: define cc75 i64 @foo4(i64 %l)
+
+short2 foo5(short2 s2) { return s2; }
+// CHECK: define cc75 <2 x i16> @foo5(<2 x i16> %s2)
+
+float2 foo6(float2 f2) { return f2; }
+// CHECK: define cc75 <2 x float> @foo6(<2 x float> %f2)
+
+float4 foo7(float4 f4) { return f4; }
+// CHECK: define cc75 <4 x float> @foo7(<4 x float> %f4)
+
+long16 foo8(long16 l16) { return l16; }
+// CHECK: define cc75 <16 x i64> @foo8(<16 x i64> %l16)
+
+void kernel ker() {}
+// CHECK: define cc76 void @ker()
