[PATCH] D56509: [AST] Remove ASTContext from getThisType (NFC)

2019-01-10 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael accepted this revision.
mikael added a comment.
This revision is now accepted and ready to land.

The changes looks good to me.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56509/new/

https://reviews.llvm.org/D56509



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55656: [OpenCL] Address space for default class members

2018-12-13 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked an inline comment as done.
mikael added inline comments.



Comment at: lib/Sema/SemaInit.cpp:4539
+  if (InitCategory.isPRValue() || InitCategory.isXValue())
+T1Quals.removeAddressSpace();
+

This is probably not the correct way to solve this. But it fixes the issues 
that i get. 

The code that triggers this issue is found in 
test/CodeGenOpenCLCXX/addrspace-of-this.cl:47

```
C c3 = c1 + c2;
```

So the original (InitializedEntity) Entity.getType()  looks like:

```
RValueReferenceType 0x717470 '__generic class C &&'
`-QualType 0x717458 '__generic class C' __generic
  `-RecordType 0x717160 'class C'
`-CXXRecord 0x7170d0 'C'
```

It might be so that we actually want to qualify the RValueReferenceType rather 
than the RecordType here. 


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55656/new/

https://reviews.llvm.org/D55656



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D55656: [OpenCL] Address space for default class members

2018-12-13 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael created this revision.
mikael added reviewers: Anastasia, rjmccall.
Herald added subscribers: cfe-commits, yaxunl.

- Implicity and explicity defaulted class members
- Resolved the FIXMEs in addrspace-of-this.cl


Repository:
  rC Clang

https://reviews.llvm.org/D55656

Files:
  include/clang/Sema/Sema.h
  lib/AST/ASTContext.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaInit.cpp
  test/CodeGenOpenCLCXX/addrspace-of-this.cl
  test/CodeGenOpenCLCXX/explicitly-defaulted-methods.cl
  test/CodeGenOpenCLCXX/implicitly-defaulted-methods.cl

Index: test/CodeGenOpenCLCXX/implicitly-defaulted-methods.cl
===
--- /dev/null
+++ test/CodeGenOpenCLCXX/implicitly-defaulted-methods.cl
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0
+// expected-no-diagnostics
+
+// Test implicitly defaulted special member functions and their invocation.
+// The 'this' address space is expected to be generic.
+
+// CHECK-LABEL:  _Z3foov
+// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %0)
+
+// CHECK-LABEL: _ZNU3AS41CC1Ev(%class.C addrspace(4)* %this)
+// CHECK:   %this.addr = alloca %class.C addrspace(4)*, align 4
+// CHECK:   store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1) #4
+// CHECK:   ret void
+
+class C {
+public:
+  int a = 0;
+};
+
+extern C&& bar();
+
+__kernel void foo() {
+  C c;
+  C c2(c);
+  C c3(bar());
+  C c5 = bar();
+  C c6 = c;
+  // To force constructors to be CodeGen:ed
+  int x = c6.a + c.a;
+}
+
Index: test/CodeGenOpenCLCXX/explicitly-defaulted-methods.cl
===
--- /dev/null
+++ test/CodeGenOpenCLCXX/explicitly-defaulted-methods.cl
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s
+// expected-no-diagnostics
+
+// Test explicitly defaulted special member functions and their invocation.
+// The 'this' address space is expected to be generic.
+
+// FIXME: Other address spaces?
+
+// CHECK-LABEL:  _Z3foov
+// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %0)
+
+// CHECK-LABEL: @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this)
+// CHECK:   %this.addr = alloca %class.C addrspace(4)*, align 4
+// CHECK:   store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   ret void
+
+class C {
+public:
+  C() {}
+  C(const C &) = default;
+  C(C &&) = default;
+  C =(const C &) = default;
+  C =(C&&) & = default;
+};
+
+extern C&& bar();
+
+__kernel void foo() {
+  C c;
+  C c2(c);
+  C c3(bar());
+  C c5 = bar();
+  C c6 = c;
+}
Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl
===
--- test/CodeGenOpenCLCXX/addrspace-of-this.cl
+++ test/CodeGenOpenCLCXX/addrspace-of-this.cl
@@ -9,18 +9,21 @@
 public:
   int v;
   C() { v = 2; }
-  // FIXME: Does not work yet.
-  // C(C &) { v = c.v; }
+  C(C &) { v = c.v; }
   C(const C ) { v = c.v; }
   C =(const C ) {
 v = c.v;
 return *this;
   }
-  // FIXME: Does not work yet.
-  //C =(C&& c) & {
-  //  v = c.v;
-  //  return *this;
-  //}
+  C =(C &) & {
+v = c.v;
+return *this;
+  }
+
+  C operator+(const C& c) {
+v += c.v;
+return *this;
+  }
 
   int get() { return v; }
 
@@ -41,15 +44,13 @@
   C c1(c);
   C c2;
   c2 = c1;
-  // FIXME: Does not work yet.
-  // C c3 = c1 + c2;
-  // C c4(foo());
-  // C c5 = foo();
-
+  C c3 = c1 + c2;
+  C c4(foo());
+  C c5 = foo();
 }
 
 // CHECK-LABEL: @__cxx_global_var_init()
-// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4
+// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
 
 // Test that the address space is __generic for the constructor
 // CHECK-LABEL: @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %this)
@@ -57,7 +58,7 @@
 // CHECK:   %this.addr = alloca %class.C addrspace(4)*, align 4
 // CHECK:   store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4
 // CHECK:   %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4
-// CHECK:   call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1) #4
+// CHECK:   call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1)
 // CHECK:   ret void
 
 // CHECK-LABEL: @_Z12test__globalv()
@@ -74,13 +75,29 @@
 
 // Test the address space of 'this' when invoking a constructor.
 // CHECK:   %1 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
-// CHECK:   call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %1) 

[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-12 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael added a comment.

Seems like my this commit broke: 
http://lab.llvm.org:8011/builders/lldb-x86_64-ubuntu-14.04-buildserver/builds/33176

But since I don't really know what anything about lldb, I probably won't be 
able to fix it fast enough.

  
/lldb-buildbot/buildServerSlave/lldb-android-buildserver/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp:2208:24:
 error: no viable overloaded '='
proto_info.TypeQuals = type_quals;
 ^ ~~
  
/lldb-buildbot/buildServerSlave/lldb-android-buildserver/llvm/tools/clang/include/clang/AST/Type.h:141:7:
 note: candidate function (the implicit copy assignment operator) not viable: 
no known conversion from 'unsigned int' to 'const clang::Qualifiers' for 1st 
argument
  class Qualifiers {
^
  
/lldb-buildbot/buildServerSlave/lldb-android-buildserver/llvm/tools/clang/include/clang/AST/Type.h:141:7:
 note: candidate function (the implicit move assignment operator) not viable: 
no known conversion from 'unsigned int' to 'clang::Qualifiers' for 1st argument
  1 error generated.

I think it can be easily solved by Qualifiers::fromFastMask(type_quals); also 
updating the variable name since it changed.

But I know nothing about lldb, so I better revert this patch for now.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-12 Thread Mikael Nilsson via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC348927: [OpenCL] Add generic AS to this pointer 
(authored by mikael, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D54862?vs=177477=177846#toc

Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862

Files:
  include/clang/AST/CanonicalType.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/Type.h
  include/clang/Sema/Sema.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDeclCXX.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGValue.h
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseCXXInlineMethods.cpp
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseOpenMP.cpp
  lib/Sema/SemaCodeComplete.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CodeGenOpenCLCXX/addrspace-of-this.cl
  test/CodeGenOpenCLCXX/template-address-spaces.cl
  test/SemaOpenCLCXX/address-space-templates.cl
  tools/libclang/CIndex.cpp

Index: lib/Index/USRGeneration.cpp
===
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -270,7 +270,8 @@
   if (const CXXMethodDecl *MD = dyn_cast(D)) {
 if (MD->isStatic())
   Out << 'S';
-if (unsigned quals = MD->getTypeQualifiers())
+// FIXME: OpenCL: Need to consider address spaces
+if (unsigned quals = MD->getTypeQualifiers().getCVRUQualifiers())
   Out << (char)('0' + quals);
 switch (MD->getRefQualifier()) {
 case RQ_None: break;
Index: lib/CodeGen/CGClass.cpp
===
--- lib/CodeGen/CGClass.cpp
+++ lib/CodeGen/CGClass.cpp
@@ -16,6 +16,7 @@
 #include "CGDebugInfo.h"
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
+#include "TargetInfo.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
@@ -2012,8 +2013,19 @@
  bool NewPointerIsChecked) {
   CallArgList Args;
 
+  LangAS SlotAS = E->getType().getAddressSpace();
+  QualType ThisType = D->getThisType(getContext());
+  LangAS ThisAS = ThisType.getTypePtr()->getPointeeType().getAddressSpace();
+  llvm::Value *ThisPtr = This.getPointer();
+  if (SlotAS != ThisAS) {
+unsigned TargetThisAS = getContext().getTargetAddressSpace(ThisAS);
+llvm::Type *NewType =
+ThisPtr->getType()->getPointerElementType()->getPointerTo(TargetThisAS);
+ThisPtr = getTargetHooks().performAddrSpaceCast(*this, This.getPointer(),
+ThisAS, SlotAS, NewType);
+  }
   // Push the this ptr.
-  Args.add(RValue::get(This.getPointer()), D->getThisType(getContext()));
+  Args.add(RValue::get(ThisPtr), D->getThisType(getContext()));
 
   // If this is a trivial constructor, emit a memcpy now before we lose
   // the alignment information on the argument.
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -2617,9 +2617,9 @@
   const FunctionProtoType *FPT =
   Ty->getPointeeType()->getAs();
   return DBuilder.createMemberPointerType(
-  getOrCreateInstanceMethodType(CGM.getContext().getPointerType(QualType(
-Ty->getClass(), FPT->getTypeQuals())),
-FPT, U),
+  getOrCreateInstanceMethodType(
+  CXXMethodDecl::getThisType(FPT, Ty->getMostRecentCXXRecordDecl()),
+  FPT, U),
   ClassType, Size, /*Align=*/0, Flags);
 }
 
Index: lib/CodeGen/CGDeclCXX.cpp
===
--- lib/CodeGen/CGDeclCXX.cpp
+++ lib/CodeGen/CGDeclCXX.cpp
@@ -26,7 +26,10 @@
 
 static void EmitDeclInit(CodeGenFunction , const VarDecl ,
  ConstantAddress DeclPtr) {
-  assert(D.hasGlobalStorage() && "VarDecl must have global storage!");
+  assert(
+  (D.hasGlobalStorage() ||
+   (D.hasLocalStorage() && CGF.getContext().getLangOpts().OpenCLCPlusPlus)) &&
+  "VarDecl must have global or local (in the case of OpenCL) storage!");
   assert(!D.getType()->isReferenceType() &&
  "Should not call EmitDeclInit on a reference!");
 
Index: lib/CodeGen/CGValue.h

[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-11 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked an inline comment as done.
mikael added inline comments.



Comment at: lib/Sema/SemaType.cpp:5169
+TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator , Scope *S,
+   const DeclContext *DC) {
   // Determine the type of the declarator. Not all forms of declarator

Anastasia wrote:
> Rather than passing `DeclContext` you can get it from the `Declarator` using 
> `getContext()` method.
Declarator::getContext() returns an enumeration DeclaratorContext which is not 
enough in this case.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-11 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked an inline comment as done.
mikael added inline comments.



Comment at: test/SemaOpenCLCXX/address-space-templates.cl:7
   T f1(); // expected-error{{function type may not be qualified with an 
address space}}
-  void f2(T); // expected-error{{parameter may not be qualified with an 
address space}}
+  // FIXME: Should only get the error message once.
+  void f2(T); // expected-error{{parameter may not be qualified with an 
address space}} expected-error{{parameter may not be qualified with an address 
space}}

Anastasia wrote:
> mikael wrote:
> > This was the remaining issue that I have not solved yet. It looked like 
> > this issue was not so trivial so I think it makes sense to postpone it.
> Do you know why it appears twice?
I believe the main issue is that  we have some code that does the following in 
SemaTemplateInstantiateDecl.cpp:

```
OldTL.getAs()
```

But the implementation of getAs returns nullptr if you have local modifiers. So 
since this code will always return nullptr we end up taking a different paths.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-10 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked 4 inline comments as done.
mikael added inline comments.



Comment at: lib/Sema/SemaDecl.cpp:3196
+
+QualType AdjustedQT = QualType(AdjustedType, 0);
+LangAS AS = Old->getType().getAddressSpace();

When merging the class function and the file context function the address space 
was lost here.



Comment at: lib/Sema/SemaType.cpp:4831
+if (state.getSema().getLangOpts().OpenCLCPlusPlus &&
+((DC && DC->isRecord()) ||
+ state.getDeclarator().getContext() ==

The first issue was that if a function is declared outside of a class this code 
did not deduce it. Now it does.



Comment at: lib/Sema/TreeTransform.h:4277
   //   cv-qualifiers are ignored.
-  if (T->isFunctionType())
+  // OpenCL: The address space should not be ignored.
+  if (T->isFunctionType()) {

Another place where the address space was removed.



Comment at: test/SemaOpenCLCXX/address-space-templates.cl:7
   T f1(); // expected-error{{function type may not be qualified with an 
address space}}
-  void f2(T); // expected-error{{parameter may not be qualified with an 
address space}}
+  // FIXME: Should only get the error message once.
+  void f2(T); // expected-error{{parameter may not be qualified with an 
address space}} expected-error{{parameter may not be qualified with an address 
space}}

This was the remaining issue that I have not solved yet. It looked like this 
issue was not so trivial so I think it makes sense to postpone it.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-10 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael added a comment.

I rebased on Friday, and noticed that I broke two tests:

Failing Tests (2):

  Clang :: CodeGenOpenCLCXX/template-address-spaces.cl
  Clang :: SemaOpenCLCXX/address-space-templates.cl

This upload contains a few extra fixes.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-10 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael updated this revision to Diff 177477.
mikael marked an inline comment as not done.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862

Files:
  include/clang/AST/CanonicalType.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/Type.h
  include/clang/Sema/Sema.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDeclCXX.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGValue.h
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseCXXInlineMethods.cpp
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseOpenMP.cpp
  lib/Sema/SemaCodeComplete.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CodeGenOpenCLCXX/addrspace-of-this.cl
  test/CodeGenOpenCLCXX/template-address-spaces.cl
  test/SemaOpenCLCXX/address-space-templates.cl
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -8370,7 +8370,7 @@
   const Decl *D = cxcursor::getCursorDecl(C);
   const CXXMethodDecl *Method =
   D ? dyn_cast_or_null(D->getAsFunction()) : nullptr;
-  return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
+  return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0;
 }
 
 unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
Index: test/SemaOpenCLCXX/address-space-templates.cl
===
--- test/SemaOpenCLCXX/address-space-templates.cl
+++ test/SemaOpenCLCXX/address-space-templates.cl
@@ -4,7 +4,9 @@
 struct S {
   T a;// expected-error{{field may not be qualified with an address space}}
   T f1(); // expected-error{{function type may not be qualified with an address space}}
-  void f2(T); // expected-error{{parameter may not be qualified with an address space}}
+  // FIXME: Should only get the error message once.
+  void f2(T); // expected-error{{parameter may not be qualified with an address space}} expected-error{{parameter may not be qualified with an address space}}
+
 };
 
 template 
Index: test/CodeGenOpenCLCXX/template-address-spaces.cl
===
--- test/CodeGenOpenCLCXX/template-address-spaces.cl
+++ test/CodeGenOpenCLCXX/template-address-spaces.cl
@@ -9,13 +9,16 @@
 template
 T S::foo() { return a;}
 
-//CHECK: %struct.S = type { i32 }
-//CHECK: %struct.S.0 = type { i32 addrspace(4)* }
-//CHECK: %struct.S.1 = type { i32 addrspace(1)* }
+// CHECK: %struct.S = type { i32 }
+// CHECK: %struct.S.0 = type { i32 addrspace(4)* }
+// CHECK: %struct.S.1 = type { i32 addrspace(1)* }
 
-//CHECK: i32 @_ZN1SIiE3fooEv(%struct.S* %this)
-//CHECK: i32 addrspace(4)* @_ZN1SIPU3AS4iE3fooEv(%struct.S.0* %this)
-//CHECK: i32 addrspace(1)* @_ZN1SIPU3AS1iE3fooEv(%struct.S.1* %this)
+// CHECK:  %0 = addrspacecast %struct.S* %sint to %struct.S addrspace(4)*
+// CHECK:  %call = call i32 @_ZNU3AS41SIiE3fooEv(%struct.S addrspace(4)* %0) #1
+// CHECK:  %1 = addrspacecast %struct.S.0* %sintptr to %struct.S.0 addrspace(4)*
+// CHECK:  %call1 = call i32 addrspace(4)* @_ZNU3AS41SIPU3AS4iE3fooEv(%struct.S.0 addrspace(4)* %1) #1
+// CHECK:  %2 = addrspacecast %struct.S.1* %sintptrgl to %struct.S.1 addrspace(4)*
+// CHECK:  %call2 = call i32 addrspace(1)* @_ZNU3AS41SIPU3AS1iE3fooEv(%struct.S.1 addrspace(4)* %2) #1
 
 void bar(){
   S sint;
Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl
===
--- /dev/null
+++ test/CodeGenOpenCLCXX/addrspace-of-this.cl
@@ -0,0 +1,154 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s
+// expected-no-diagnostics
+
+// Test that the 'this' pointer is in the __generic address space.
+
+// FIXME: Add support for __constant address space.
+
+class C {
+public:
+  int v;
+  C() { v = 2; }
+  // FIXME: Does not work yet.
+  // C(C &) { v = c.v; }
+  C(const C ) { v = c.v; }
+  C =(const C ) {
+v = c.v;
+return *this;
+  }
+  // FIXME: Does not work yet.
+  //C =(C&& c) & {
+  //  v = c.v;
+  //  return *this;
+  //}
+
+  int get() { return v; }
+
+  int outside();
+};
+
+int C::outside() {
+  return v;
+}
+
+extern C&& foo();
+
+__global C c;
+
+__kernel void test__global() {
+  int i = c.get();
+  int i2 = c.outside();
+  C c1(c);
+  C c2;
+  c2 = c1;
+  // FIXME: 

[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-06 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked an inline comment as done and an inline comment as not done.
mikael added inline comments.



Comment at: lib/AST/Type.cpp:2950
+   FunctionTypeBits.HasExtQuals = 0;
+  }
 }

mikael wrote:
> rjmccall wrote:
> > The indentation here is messed up.
> > 
> > You seem to be mixing up "fast qualifiers" with "CVR qualifiers" in a few 
> > places.  That's currently correct, in the sense that the fast qualifiers 
> > are currently defined to be the CVR qualifiers, but the point of the 
> > distinction is that we might want to change that (and we have in fact 
> > explored that in the past).  I think you should make `FunctionTypeBits` 
> > only claim to store the fast qualifiers, which mostly just means updating a 
> > few field / accessor names and changing things like the 
> > `getCVRQualifiers()` call right above this to be `getFastQualifiers()`.
> > 
> > If there are places where it's convenient to assume that the CVR qualifiers 
> > are exactly the fast qualifiers, it's okay to static_assert that, but you 
> > should make sure to static_assert it in each place you assume it.
> I'll change it, but I do have a question related to this:
> 
> Can we make any assumptions with the "fast qualifiers"? I'd like it if we can 
> assume that they fit in 3 bits. Otherwise I think I also need an assertion 
> here.
I solved it like this in the end:

* I defined the FastTypeQuals to get the size of Qualifiers::FastWidth to make 
it dependent on possible changes to the fast flags.
* Then I put a static_assertion to guard the hastConst(), hasVolatile() and 
hasRestrict() methods.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-06 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael updated this revision to Diff 176943.
mikael added a comment.

- Added FIXME's.
- Fixed the latest comments.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862

Files:
  include/clang/AST/CanonicalType.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/Type.h
  include/clang/Sema/Sema.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDeclCXX.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGValue.h
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseCXXInlineMethods.cpp
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseOpenMP.cpp
  lib/Sema/SemaCodeComplete.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CodeGenOpenCLCXX/addrspace-of-this.cl
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -8370,7 +8370,7 @@
   const Decl *D = cxcursor::getCursorDecl(C);
   const CXXMethodDecl *Method =
   D ? dyn_cast_or_null(D->getAsFunction()) : nullptr;
-  return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
+  return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0;
 }
 
 unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl
===
--- /dev/null
+++ test/CodeGenOpenCLCXX/addrspace-of-this.cl
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s
+// expected-no-diagnostics
+
+// Test that the 'this' pointer is in the __generic address space.
+
+// FIXME: Add support for __constant address space.
+
+class C {
+public:
+  int v;
+  C() { v = 2; }
+  C(const C ) { v = c.v; }
+  C =(const C ) {
+v = c.v;
+return *this;
+  }
+  int get() { return v; }
+};
+
+__global C c;
+
+__kernel void test__global() {
+  int i = c.get();
+  C c1(c);
+  C c2;
+  c2 = c1;
+}
+
+// CHECK-LABEL: @__cxx_global_var_init()
+// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4
+
+// Test that the address space is __generic for the constructor
+// CHECK-LABEL: @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %this)
+// CHECK: entry:
+// CHECK:   %this.addr = alloca %class.C addrspace(4)*, align 4
+// CHECK:   store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1) #4
+// CHECK:   ret void
+
+// CHECK-LABEL: @_Z12test__globalv()
+
+// Test the address space of 'this' when invoking a method.
+// CHECK: %call = call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking copy-constructor.
+// CHECK: %0 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* %0, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking a constructor.
+// CHECK:   %1 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK:   call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %1) #4
+
+// Test the address space of 'this' when invoking assignment operator.
+// CHECK:   %2 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK:   %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK:   %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) %2)
+
+#define TEST(AS) \
+  __kernel void test##AS() { \
+AS C c;  \
+int i = c.get(); \
+C c1(c); \
+C c2;\
+c2 = c1; \
+  }
+
+TEST(__local)
+
+// CHECK-LABEL: _Z11test__localv
+// CHECK: @__cxa_guard_acquire
+
+// Test the address space of 'this' when invoking a method.
+// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when 

[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-06 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked 3 inline comments as done.
mikael added inline comments.



Comment at: lib/AST/Type.cpp:2950
+   FunctionTypeBits.HasExtQuals = 0;
+  }
 }

rjmccall wrote:
> The indentation here is messed up.
> 
> You seem to be mixing up "fast qualifiers" with "CVR qualifiers" in a few 
> places.  That's currently correct, in the sense that the fast qualifiers are 
> currently defined to be the CVR qualifiers, but the point of the distinction 
> is that we might want to change that (and we have in fact explored that in 
> the past).  I think you should make `FunctionTypeBits` only claim to store 
> the fast qualifiers, which mostly just means updating a few field / accessor 
> names and changing things like the `getCVRQualifiers()` call right above this 
> to be `getFastQualifiers()`.
> 
> If there are places where it's convenient to assume that the CVR qualifiers 
> are exactly the fast qualifiers, it's okay to static_assert that, but you 
> should make sure to static_assert it in each place you assume it.
I'll change it, but I do have a question related to this:

Can we make any assumptions with the "fast qualifiers"? I'd like it if we can 
assume that they fit in 3 bits. Otherwise I think I also need an assertion here.



Comment at: lib/CodeGen/CGDebugInfo.cpp:2593
+  getOrCreateInstanceMethodType(
+  CXXMethodDecl::getThisType(FPT, Ty->getMostRecentCXXRecordDecl()),
+  FPT, U),

rjmccall wrote:
> Why is this `getMostRecentCXXRecordDecl` instead of `getClass`?
Your initial comment suggested to send in a record rather than a type. But I 
see now that it may make more sense to use the type directly instead. Will 
update it.



Comment at: lib/CodeGen/CGDeclCXX.cpp:32
+   (D.hasLocalStorage() && 
CGF.getContext().getLangOpts().OpenCLCPlusPlus)) &&
+  "VarDecl must have global or local (in the case of OpenCL) storage!");
   assert(!D.getType()->isReferenceType() &&

rjmccall wrote:
> What causes OpenCL C++ declarations to go down this path?
It goes there when we defined an object  in __local address space.  From the 
spec "The constructors of a objects in local memory should only be initialized 
once".  This is the same case as with C++ 11 static local variables.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-05 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked an inline comment as done.
mikael added inline comments.



Comment at: lib/AST/ItaniumMangle.cpp:1507
+Qualifiers MethodQuals = Qualifiers::fromCVRUMask(
+Method->getTypeQualifiers().getCVRUQualifiers());
 // We do not consider restrict a distinguishing attribute for overloading

rjmccall wrote:
> Anastasia wrote:
> > rjmccall wrote:
> > > You can overload based on the address space, right?  I think it needs to 
> > > be mangled.
> > Does this refer to our earlier discussion 
> > https://reviews.llvm.org/D54862#inline-484509
> > 
> > We don't have a way to qualify methods with an address space yet? I was 
> > going to send an RFC to `cfe-dev` for this but if you think it would be ok 
> > to go ahead with an implementation, I am happy with it. Either way would it 
> > be better to do this in a separate patch?
> I'm fine with delaying implementation on these two issues until a later patch 
> since, as you say, they can't be tested well until we support arbitrary 
> address-space qualifiers.  Please at least leave FIXMEs for them.
I actually did update this, since we can test the mangling of __generic in the 
test.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-05 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael updated this revision to Diff 176831.
mikael added a comment.

I uploaded a new patch for most of the comments. I did leave some things out 
since they need clarification.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862

Files:
  include/clang/AST/CanonicalType.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/Type.h
  include/clang/Sema/Sema.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDeclCXX.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGValue.h
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseCXXInlineMethods.cpp
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseOpenMP.cpp
  lib/Sema/SemaCodeComplete.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CodeGenOpenCLCXX/addrspace-of-this.cl
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -8370,7 +8370,7 @@
   const Decl *D = cxcursor::getCursorDecl(C);
   const CXXMethodDecl *Method =
   D ? dyn_cast_or_null(D->getAsFunction()) : nullptr;
-  return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
+  return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0;
 }
 
 unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl
===
--- /dev/null
+++ test/CodeGenOpenCLCXX/addrspace-of-this.cl
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s
+// expected-no-diagnostics
+
+// Test that the 'this' pointer is in the __generic address space.
+
+// FIXME: Add support for __constant address space.
+
+class C {
+public:
+  int v;
+  C() { v = 2; }
+  C(const C ) { v = c.v; }
+  C =(const C ) {
+v = c.v;
+return *this;
+  }
+  int get() { return v; }
+};
+
+__global C c;
+
+__kernel void test__global() {
+  int i = c.get();
+  C c1(c);
+  C c2;
+  c2 = c1;
+}
+
+// CHECK-LABEL: @__cxx_global_var_init()
+// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4
+
+// Test that the address space is __generic for the constructor
+// CHECK-LABEL: @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %this)
+// CHECK: entry:
+// CHECK:   %this.addr = alloca %class.C addrspace(4)*, align 4
+// CHECK:   store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   call void @_ZNU3AS41CC2Ev(%class.C addrspace(4)* %this1) #4
+// CHECK:   ret void
+
+// CHECK-LABEL: @_Z12test__globalv()
+
+// Test the address space of 'this' when invoking a method.
+// CHECK: %call = call i32 @_ZNU3AS41C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking copy-constructor.
+// CHECK: %0 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK: call void @_ZNU3AS41CC1ERU3AS4KS_(%class.C addrspace(4)* %0, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking a constructor.
+// CHECK:   %1 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK:   call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* %1) #4
+
+// Test the address space of 'this' when invoking assignment operator.
+// CHECK:   %2 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK:   %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK:   %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZNU3AS41CaSERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) %2)
+
+#define TEST(AS) \
+  __kernel void test##AS() { \
+AS C c;  \
+int i = c.get(); \
+C c1(c); \
+C c2;\
+c2 = c1; \
+  }
+
+TEST(__local)
+
+// CHECK-LABEL: _Z11test__localv
+// CHECK: @__cxa_guard_acquire
+
+// Test the address space of 'this' when invoking a method.
+// CHECK: call void @_ZNU3AS41CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to 

[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-05 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked an inline comment as done and an inline comment as not done.
mikael added a comment.

Thanks for the feedback, I'll work on fixing the issues!




Comment at: lib/Sema/SemaOverload.cpp:1146
+unsigned OldQuals = OldMethod->getTypeQualifiers().getCVRUQualifiers();
+unsigned NewQuals = NewMethod->getTypeQualifiers().getCVRUQualifiers();
 if (!getLangOpts().CPlusPlus14 && NewMethod->isConstexpr() &&

rjmccall wrote:
> This is an algorithm that I think you need to get right and which shouldn't 
> drop address spaces.
But with this patch we can only have __generic address space for methods. So if 
I try to implement something here I can't really test it? Or am I missing 
something?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-04 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked an inline comment as done.
mikael added inline comments.



Comment at: lib/Sema/SemaType.cpp:4816
+// OpenCLCPlusPlus: A class member function has an address space.
+if (state.getSema().getLangOpts().OpenCLCPlusPlus &&
+state.getDeclarator().getContext() ==

Anastasia wrote:
> Can this be moved into `deduceOpenCLImplicitAddrSpace`?
deduceOpenCLImplicitAddrSpace is only wrapping a type with an address space. I 
also need to make sure the FunctionProtoType gets generated with the address 
space.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-12-04 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael updated this revision to Diff 176596.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862

Files:
  include/clang/AST/CanonicalType.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/Type.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDeclCXX.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGValue.h
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseCXXInlineMethods.cpp
  lib/Sema/SemaCodeComplete.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CodeGenOpenCLCXX/addrspace-of-this.cl
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -8370,7 +8370,7 @@
   const Decl *D = cxcursor::getCursorDecl(C);
   const CXXMethodDecl *Method =
   D ? dyn_cast_or_null(D->getAsFunction()) : nullptr;
-  return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
+  return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0;
 }
 
 unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl
===
--- /dev/null
+++ test/CodeGenOpenCLCXX/addrspace-of-this.cl
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s
+// expected-no-diagnostics
+
+// Test that the 'this' pointer is in the __generic address space.
+
+// FIXME: Add support for __constant address space.
+
+class C {
+public:
+  int v;
+  C() { v = 2; }
+  C(const C ) { v = c.v; }
+  C =(const C ) {
+v = c.v;
+return *this;
+  }
+  int get() { return v; }
+};
+
+__global C c;
+
+__kernel void test__global() {
+  int i = c.get();
+  C c1(c);
+  C c2;
+  c2 = c1;
+}
+
+// CHECK-LABEL: @__cxx_global_var_init()
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4
+
+// Test that the address space is __generic for the constructor
+// CHECK-LABEL: @_ZN1CC1Ev(%class.C addrspace(4)* %this)
+// CHECK: entry:
+// CHECK:   %this.addr = alloca %class.C addrspace(4)*, align 4
+// CHECK:   store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   call void @_ZN1CC2Ev(%class.C addrspace(4)* %this1) #4
+// CHECK:   ret void
+
+// CHECK-LABEL: @_Z12test__globalv()
+
+// Test the address space of 'this' when invoking a method.
+// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking copy-constructor.
+// CHECK: %0 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %0, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking a constructor.
+// CHECK:   %1 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK:   call void @_ZN1CC1Ev(%class.C addrspace(4)* %1) #4
+
+// Test the address space of 'this' when invoking assignment operator.
+// CHECK:   %2 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK:   %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK:   %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZN1CaSERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) %2)
+
+#define TEST(AS) \
+  __kernel void test##AS() { \
+AS C c;  \
+int i = c.get(); \
+C c1(c); \
+C c2;\
+c2 = c1; \
+  }
+
+TEST(__local)
+
+// CHECK-LABEL: _Z11test__localv
+// CHECK: @__cxa_guard_acquire
+
+// Test the address space of 'this' when invoking a method.
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking copy-constructor.
+// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking a constructor.
+// CHECK: %3 = addrspacecast %class.C* 

[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-11-30 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked an inline comment as done.
mikael added inline comments.



Comment at: lib/Sema/SemaOverload.cpp:5254
+  if (!Context.hasSameType(From->getType(), DestType)) {
+if (From->getType().getAddressSpace() != DestType.getAddressSpace())
+  From = ImpCastExprToType(From, DestType, CK_AddressSpaceConversion,

Note that this change allowed me to revert some of the CG changes.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-11-30 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael updated this revision to Diff 176063.
Herald added subscribers: arphaman, eraman.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862

Files:
  include/clang/AST/DeclCXX.h
  include/clang/AST/Type.h
  lib/AST/DeclCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CGDeclCXX.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseCXXInlineMethods.cpp
  lib/Sema/SemaCodeComplete.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Sema/SemaType.cpp
  test/CodeGenOpenCLCXX/addrspace-of-this.cl
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -8370,7 +8370,7 @@
   const Decl *D = cxcursor::getCursorDecl(C);
   const CXXMethodDecl *Method =
   D ? dyn_cast_or_null(D->getAsFunction()) : nullptr;
-  return (Method && (Method->getTypeQualifiers() & Qualifiers::Const)) ? 1 : 0;
+  return (Method && Method->getTypeQualifiers().hasConst()) ? 1 : 0;
 }
 
 unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl
===
--- /dev/null
+++ test/CodeGenOpenCLCXX/addrspace-of-this.cl
@@ -0,0 +1,129 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s
+// expected-no-diagnostics
+
+// Test that the 'this' pointer is in the __generic address space.
+
+// FIXME: Add support for __constant address space.
+
+class C {
+public:
+  int v;
+  C() { v = 2; }
+  C(const C ) { v = c.v; }
+  C =(const C ) {
+v = c.v;
+return *this;
+  }
+  int get() { return v; }
+};
+
+__global C c;
+
+__kernel void test__global() {
+  int i = c.get();
+  C c1(c);
+  C c2;
+  c2 = c1;
+}
+
+// CHECK-LABEL: @__cxx_global_var_init()
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4
+
+// Test that the address space is __generic for the constructor
+// CHECK-LABEL: @_ZN1CC1Ev(%class.C addrspace(4)* %this)
+// CHECK: entry:
+// CHECK:   %this.addr = alloca %class.C addrspace(4)*, align 4
+// CHECK:   store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   call void @_ZN1CC2Ev(%class.C addrspace(4)* %this1) #4
+// CHECK:   ret void
+
+// CHECK-LABEL: @_Z12test__globalv()
+
+// Test the address space of 'this' when invoking a method.
+// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking copy-constructor.
+// CHECK: %0 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %0, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking a constructor.
+// CHECK:   %1 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK:   call void @_ZN1CC1Ev(%class.C addrspace(4)* %1) #4
+
+// Test the address space of 'this' when invoking assignment operator.
+// CHECK:   %2 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK:   %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK:   %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZN1CaSERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) %2)
+
+#define TEST(AS) \
+  __kernel void test##AS() { \
+AS C c;  \
+int i = c.get(); \
+C c1(c); \
+C c2;\
+c2 = c1; \
+  }
+
+TEST(__local)
+
+// CHECK-LABEL: _Z11test__localv
+// CHECK: @__cxa_guard_acquire
+
+// Test the address space of 'this' when invoking a method.
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking copy-constructor.
+// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking a constructor.
+// CHECK: %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %3)
+
+// Test the address space of 'this' when invoking assignment operator.
+// CHECK:  %4 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK:  %5 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK:  %call1 = call 

[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-11-28 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael updated this revision to Diff 175646.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862

Files:
  lib/AST/DeclCXX.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGClass.cpp
  lib/CodeGen/CGDeclCXX.cpp
  lib/CodeGen/CGExprCXX.cpp
  lib/Sema/SemaType.cpp
  test/CodeGenOpenCLCXX/addrspace-of-this.cl

Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl
===
--- /dev/null
+++ test/CodeGenOpenCLCXX/addrspace-of-this.cl
@@ -0,0 +1,140 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s
+// expected-no-diagnostics
+
+// Test that the 'this' pointer is in the __generic address space.
+
+// FIXME: Add support for __constant address space.
+
+class C {
+public:
+  int v;
+  C() { v = 2; }
+  C(const C ) { v = c.v; }
+  C =(const C ) {
+v = c.v;
+return *this;
+  }
+  int get() { return v; }
+};
+
+__global C c;
+
+__kernel void test__global() {
+  int i = c.get();
+  C c1(c);
+  C c2;
+  c2 = c1;
+}
+
+// CHECK-LABEL: @__cxx_global_var_init()
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4
+
+// Test that the address space is __generic for the constructor
+// CHECK-LABEL: @_ZN1CC1Ev(%class.C addrspace(4)* %this)
+// CHECK: entry:
+// CHECK:   %this.addr = alloca %class.C addrspace(4)*, align 4
+// CHECK:   store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   call void @_ZN1CC2Ev(%class.C addrspace(4)* %this1) #4
+// CHECK:   ret void
+
+// CHECK-LABEL: @_Z12test__globalv()
+
+// Test the address space of 'this' when invoking a method.
+// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking copy-constructor.
+// CHECK: %0 = addrspacecast %class.C* %c1 to %class.C* addrspace(4)*
+// CHECK: %1 = bitcast %class.C* addrspace(4)* %0 to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %1, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking a constructor.
+// CHECK:   %2 = addrspacecast %class.C* %c2 to %class.C* addrspace(4)*
+// CHECK:   %3 = bitcast %class.C* addrspace(4)* %2 to %class.C addrspace(4)*
+// CHECK:   call void @_ZN1CC1Ev(%class.C addrspace(4)* %3) #4
+
+// Test the address space of 'this' when invoking assignment operator.
+// CHECK:   %4 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK:   %5 = addrspacecast %class.C* %c2 to %class.C* addrspace(4)*
+// CHECK:   %6 = bitcast %class.C* addrspace(4)* %5 to %class.C addrspace(4)*
+// CHECK:   %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZN1CaSERU3AS4KS_(%class.C addrspace(4)* %6, %class.C addrspace(4)* dereferenceable(4) %4)
+
+#define TEST(AS) \
+  __kernel void test##AS() { \
+AS C c;  \
+int i = c.get(); \
+C c1(c); \
+C c2;\
+c2 = c1; \
+  }
+
+TEST(__local)
+
+// CHECK-LABEL: _Z11test__localv
+// CHECK: @__cxa_guard_acquire
+
+// Test the address space of 'this' when invoking a method.
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking copy-constructor.
+// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking a constructor.
+// CHECK: %4 = addrspacecast %class.C* %c2 to %class.C* addrspace(4)*
+// CHECK: %5 = bitcast %class.C* addrspace(4)* %4 to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %5)
+
+// Test the address space of 'this' when invoking assignment operator.
+// CHECK:  %6 = addrspacecast %class.C* %c1 to %class.C addrspace(4)*
+// CHECK:  %7 = addrspacecast %class.C* %c2 to %class.C* addrspace(4)*
+// CHECK:  %call1 = call dereferenceable(4) %class.C addrspace(4)* @_ZN1CaSERU3AS4KS_(%class.C addrspace(4)* %8, %class.C addrspace(4)* dereferenceable(4) %6)
+
+TEST(__private)
+
+// CHECK-LABEL: @_Z13test__privatev
+
+// Test the address space of 'this' when invoking a method.
+// CHECK:   %2 = addrspacecast %class.C* %c to %class.C* addrspace(4)*
+// CHECK:   %3 = bitcast %class.C* addrspace(4)* %2 to %class.C addrspace(4)*
+// CHECK:   %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* %3)
+
+// Test the address space of 'this' when invoking a copy-constructor.
+// CHECK:   %5 = addrspacecast %class.C* %c to %class.C 

[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-11-27 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael marked an inline comment as done.
mikael added inline comments.



Comment at: lib/CodeGen/CGCall.cpp:4035
+  V = Builder.CreatePointerBitCastOrAddrSpaceCast(V, DestTy);
+}
 

rjmccall wrote:
> Always use the `performAddrSpaceConversion` target hook if there's a semantic 
> address-space conversion required.  But really, this doesn't seem like the 
> right place to be doing this; it ought to happen higher up when we're adding 
> the `this` argument to the call, either explicitly in IRGen or implicitly by 
> expecting the object expression to already yield a value in the right address 
> space.
> 
> I could definitely believe that we don't currently create `CastExpr`s for 
> simple qualification conversions of the object argument of a C++ method call, 
> since (ignoring these address-space conversions) they're always trivial.
Thanks for the input! It seems like the name `performAddrSpaceConversion` does 
not exist in the code-base though.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54862/new/

https://reviews.llvm.org/D54862



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54862: [OpenCL] Add generic AS to 'this' pointer

2018-11-23 Thread Mikael Nilsson via Phabricator via cfe-commits
mikael created this revision.
mikael added a reviewer: Anastasia.
Herald added subscribers: cfe-commits, yaxunl.

Address spaces are cast into generic before invoking the constructor.


Repository:
  rC Clang

https://reviews.llvm.org/D54862

Files:
  lib/AST/DeclCXX.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CGDeclCXX.cpp
  test/CodeGenOpenCLCXX/addrspace-of-this.cl

Index: test/CodeGenOpenCLCXX/addrspace-of-this.cl
===
--- /dev/null
+++ test/CodeGenOpenCLCXX/addrspace-of-this.cl
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 %s -triple spir-unknown-unknown -cl-std=c++ -emit-llvm -pedantic -verify -O0 -o - | FileCheck %s
+// expected-no-diagnostics
+
+// Test that the 'this' pointer is in the __generic address space.
+
+// FIXME: Add support for __constant address space.
+
+class C {
+public:
+  int v;
+  C() { v = 2; }
+  C(const C ) { v = c.v; }
+  C =(const C ) {
+v = c.v;
+return *this;
+  }
+  int get() { return v; }
+};
+
+__global C c;
+
+__kernel void test__global() {
+  int i = c.get();
+  C c2 = c;
+  C c3(c);
+}
+
+// CHECK-LABEL: @__cxx_global_var_init()
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*)) #4
+
+// Test that the address space is __generic for the constructor
+// CHECK-LABEL: @_ZN1CC1Ev(%class.C addrspace(4)* %this)
+// CHECK: entry:
+// CHECK:   %this.addr = alloca %class.C addrspace(4)*, align 4
+// CHECK:   store %class.C addrspace(4)* %this, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   %this1 = load %class.C addrspace(4)*, %class.C addrspace(4)** %this.addr, align 4
+// CHECK:   call void @_ZN1CC2Ev(%class.C addrspace(4)* %this1) #4
+// CHECK:   ret void
+
+// CHECK-LABEL: @_Z12test__globalv()
+
+// Test the address space of 'this' when accessing a method.
+// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking copy-constructor.
+// CHECK:   %0 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK:   call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %0, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+// Test the address space of 'this' when invoking assignment operator.
+// CHECK:   %1 = addrspacecast %class.C* %c3 to %class.C addrspace(4)*
+// CHECK:   call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %1, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(1)* @c to %class.C addrspace(4)*))
+
+The following checkers are testing similar things like the __global test but for other address spaces.
+
+#define TEST(AS) \
+  __kernel void test##AS() { \
+AS C c;  \
+int i = c.get(); \
+C c2 = c;\
+C c3(c); \
+  }
+
+TEST(__local)
+
+// CHECK-LABEL: _Z11test__localv
+// CHECK: @__cxa_guard_acquire
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+// CHECK: %2 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %2, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+// CHECK: %3 = addrspacecast %class.C* %c3 to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) addrspacecast (%class.C addrspace(3)* @_ZZ11test__localvE1c to %class.C addrspace(4)*))
+
+TEST(__private)
+
+// CHECK-LABEL: @_Z13test__privatev
+// CHECK-NOT: @__cxa_guard_acquire
+// CHECK: %0 = addrspacecast %class.C* %c to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %0)
+// CHECK: %1 = addrspacecast %class.C* %c to %class.C addrspace(4)*
+// CHECK: %call = call i32 @_ZN1C3getEv(%class.C addrspace(4)* %1)
+// CHECK: %2 = addrspacecast %class.C* %c to %class.C addrspace(4)*
+// CHECK: %3 = addrspacecast %class.C* %c2 to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %3, %class.C addrspace(4)* dereferenceable(4) %2)
+// CHECK: %4 = addrspacecast %class.C* %c to %class.C addrspace(4)*
+// CHECK: %5 = addrspacecast %class.C* %c3 to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1ERU3AS4KS_(%class.C addrspace(4)* %5, %class.C addrspace(4)* dereferenceable(4) %4)
+
+TEST()
+
+// CHECK-LABEL: @_Z4testv()
+// CHECK: %0 = addrspacecast %class.C* %c to %class.C addrspace(4)*
+// CHECK: call void @_ZN1CC1Ev(%class.C addrspace(4)* %0)
+// CHECK: %1 = addrspacecast %class.C* %c to %class.C addrspace(4)*
+// CHECK: %call = call i32