Forces the SPIR kernel calling convention for OpenCL C kernels
by default. This is to make the host-visible functions always
to have 1:1 arguments with the clSetKernelArgument() calls and
to avoid the need for target-specific handling while still enabling
target-specific CC/ABI and optimizations for the rest of the
program.

Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp	(revision 292207)
+++ lib/Basic/Targets.cpp	(working copy)
@@ -2801,6 +2801,7 @@
     case CC_Swift:
     case CC_X86Pascal:
     case CC_IntelOclBicc:
+    case CC_OpenCLKernel:
       return CCCR_OK;
     default:
       return CCCR_Warning;
@@ -4380,6 +4381,7 @@
     case CC_X86_64Win64:
     case CC_PreserveMost:
     case CC_PreserveAll:
+    case CC_OpenCLKernel:
       return CCCR_OK;
     default:
       return CCCR_Warning;
@@ -4447,6 +4449,7 @@
     case CC_X86VectorCall:
     case CC_IntelOclBicc:
     case CC_X86_64SysV:
+    case CC_OpenCLKernel:
       return CCCR_OK;
     default:
       return CCCR_Warning;
@@ -5386,6 +5389,7 @@
     case CC_AAPCS:
     case CC_AAPCS_VFP:
     case CC_Swift:
+    case CC_OpenCLKernel:
       return CCCR_OK;
     default:
       return CCCR_Warning;
@@ -5543,6 +5547,7 @@
     case CC_X86VectorCall:
       return CCCR_Ignore;
     case CC_C:
+    case CC_OpenCLKernel:
       return CCCR_OK;
     default:
       return CCCR_Warning;
@@ -5853,6 +5858,7 @@
     case CC_Swift:
     case CC_PreserveMost:
     case CC_PreserveAll:
+    case CC_OpenCLKernel:
       return CCCR_OK;
     default:
       return CCCR_Warning;
@@ -7048,6 +7054,15 @@
   ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {
     return None;
   }
+  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
+    switch (CC) {
+      default:
+        return CCCR_Warning;
+      case CC_C:
+      case CC_OpenCLKernel:
+        return CCCR_OK;
+    }
+  }
 };
 
 class BPFTargetInfo : public TargetInfo {
Index: lib/CodeGen/ABIInfo.h
===================================================================
--- lib/CodeGen/ABIInfo.h	(revision 292207)
+++ lib/CodeGen/ABIInfo.h	(working copy)
@@ -146,7 +146,6 @@
       return info->supportsSwift();
     }
   };
-
 }  // end namespace CodeGen
 }  // end namespace clang
 
Index: lib/CodeGen/CGCall.cpp
===================================================================
--- lib/CodeGen/CGCall.cpp	(revision 292207)
+++ lib/CodeGen/CGCall.cpp	(working copy)
@@ -665,6 +665,12 @@
                                  signature.getRequiredArgs());
 }
 
+namespace clang {
+namespace CodeGen {
+void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI);
+}
+}
+
 /// Arrange the argument and result information for an abstract value
 /// of a given function type.  This is the method which all of the
 /// above functions ultimately defer to.
@@ -699,12 +705,16 @@
   bool inserted = FunctionsBeingProcessed.insert(FI).second;
   (void)inserted;
   assert(inserted && "Recursively being processed?");
-  
+
   // Compute ABI information.
-  if (info.getCC() != CC_Swift) {
+  if (CC == llvm::CallingConv::SPIR_KERNEL) {
+    // Force target independent argument handling for the host visible
+    // kernel functions.
+    computeSPIRKernelABIInfo(CGM, *FI);
+  } else if (info.getCC() == CC_Swift) {
+    swiftcall::computeABIInfo(CGM, *FI);
+  } else {
     getABIInfo().computeInfo(*FI);
-  } else {
-    swiftcall::computeABIInfo(CGM, *FI);
   }
 
   // Loop over all of the computed argument and return value info.  If any of
Index: lib/CodeGen/TargetInfo.cpp
===================================================================
--- lib/CodeGen/TargetInfo.cpp	(revision 292207)
+++ lib/CodeGen/TargetInfo.cpp	(working copy)
@@ -373,7 +373,16 @@
 }
 
 unsigned TargetCodeGenInfo::getOpenCLKernelCallingConv() const {
-  return llvm::CallingConv::C;
+  // OpenCL kernels are called via explicit runtime APIs with arguments
+  // set with clSetKernelArg(). Return SPIR_KERNEL by default as the
+  // kernel calling convention to ensure the finger print is fixed such way
+  // that each OpenCL argument gets one matching argument in the produced
+  // kernel function argument list. In case using the C calling conv here,
+  // clSetKernelArg() might breaks depending on the target's specific
+  // conventions as different targets might split structs passed as values
+  // to multiple function arguments etc.
+  // See: https://github.com/pocl/pocl/issues/1
+  return llvm::CallingConv::SPIR_KERNEL;
 }
 static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);
 
@@ -7514,8 +7523,18 @@
                     CodeGen::CodeGenModule &M) const override;
   unsigned getOpenCLKernelCallingConv() const override;
 };
+
 } // End anonymous namespace.
 
+namespace clang {
+namespace CodeGen {
+void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI) {
+  DefaultABIInfo SPIRABI(CGM.getTypes());
+  SPIRABI.computeInfo(FI);
+}
+}
+}
+
 /// Emit SPIR specific metadata: OpenCL and SPIR version.
 void SPIRTargetCodeGenInfo::emitTargetMD(const Decl *D, llvm::GlobalValue *GV,
                                          CodeGen::CodeGenModule &CGM) const {
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp	(revision 292207)
+++ lib/Sema/SemaType.cpp	(working copy)
@@ -3192,16 +3192,11 @@
     for (const AttributeList *Attr = D.getDeclSpec().getAttributes().getList();
          Attr; Attr = Attr->getNext()) {
       if (Attr->getKind() == AttributeList::AT_OpenCLKernel) {
-        llvm::Triple::ArchType arch = S.Context.getTargetInfo().getTriple().getArch();
-        if (arch == llvm::Triple::spir || arch == llvm::Triple::spir64 ||
-            arch == llvm::Triple::amdgcn) {
-          CC = CC_OpenCLKernel;
-        }
+        CC = CC_OpenCLKernel;
         break;
       }
     }
   }
-
   return CC;
 }
 
