From fd841159cfcebb1142971cf87672775bb70a831c Mon Sep 17 00:00:00 2001
From: Pekka Jaaskelainen <pekka.jaaskelainen@tut.fi>
Date: Thu, 17 Nov 2016 17:30:56 +0000
Subject: [PATCH] Merge 286819 and 286821: [OpenCL] always use SPIR address
 spaces for kernel_arg_addr_space MD

git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_39@287239 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/CodeGen/CodeGenFunction.cpp               | 22 ++++++++++++++++---
 .../kernel-arg-info-single-as.cl              |  9 ++++++++
 2 files changed, 28 insertions(+), 3 deletions(-)
 create mode 100644 test/CodeGenOpenCL/kernel-arg-info-single-as.cl

diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 183ee12ea23..eed4ee0eac8 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -436,6 +436,23 @@ void CodeGenFunction::EmitMCountInstrumentation() {
   EmitNounwindRuntimeCall(MCountFn);
 }
 
+// Returns the address space id that should be produced to the
+// kernel_arg_addr_space metadata. This is always fixed to the ids
+// as specified in the SPIR 2.0 specification in order to differentiate
+// for example in clGetKernelArgInfo() implementation between the address
+// spaces with targets without unique mapping to the OpenCL address spaces
+// (basically all single AS CPUs).
+static unsigned ArgInfoAddressSpace(unsigned LangAS) {
+  switch (LangAS) {
+  case LangAS::opencl_global:   return 1;
+  case LangAS::opencl_constant: return 2;
+  case LangAS::opencl_local:    return 3;
+  case LangAS::opencl_generic:  return 4; // Not in SPIR 2.0 specs.
+  default:
+    return 0; // Assume private.
+  }
+}
+
 // OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument
 // information in the program executable. The argument information stored
 // includes the argument name, its type, the address and access qualifiers used.
@@ -476,7 +493,7 @@ static void GenOpenCLArgMetadata(const FunctionDecl *FD, llvm::Function *Fn,
 
       // Get address qualifier.
       addressQuals.push_back(llvm::ConstantAsMetadata::get(Builder.getInt32(
-          ASTCtx.getTargetAddressSpace(pointeeTy.getAddressSpace()))));
+        ArgInfoAddressSpace(pointeeTy.getAddressSpace()))));
 
       // Get argument type name.
       std::string typeName =
@@ -513,8 +530,7 @@ static void GenOpenCLArgMetadata(const FunctionDecl *FD, llvm::Function *Fn,
       uint32_t AddrSpc = 0;
       bool isPipe = ty->isPipeType();
       if (ty->isImageType() || isPipe)
-        AddrSpc =
-          CGM.getContext().getTargetAddressSpace(LangAS::opencl_global);
+        AddrSpc = ArgInfoAddressSpace(LangAS::opencl_global);
 
       addressQuals.push_back(
           llvm::ConstantAsMetadata::get(Builder.getInt32(AddrSpc)));
diff --git a/test/CodeGenOpenCL/kernel-arg-info-single-as.cl b/test/CodeGenOpenCL/kernel-arg-info-single-as.cl
new file mode 100644
index 00000000000..595c97464e3
--- /dev/null
+++ b/test/CodeGenOpenCL/kernel-arg-info-single-as.cl
@@ -0,0 +1,9 @@
+// Test that the kernel argument info always refers to SPIR address spaces,
+// even if the target has only one address space like x86_64 does.
+// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple x86_64-unknown-unknown -cl-kernel-arg-info | FileCheck %s
+
+kernel void foo(__global int * G, __constant int *C, __local int *L) {
+  *G = *C + *L;
+}
+// CHECK: !kernel_arg_addr_space ![[MD123:[0-9]+]]
+// CHECK: ![[MD123]] = !{i32 1, i32 2, i32 3}
-- 
GitLab