[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-12-07 Thread Artem Belevich via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL288962: [CUDA] Improve target attribute checking for 
function templates. (authored by tra).

Changed prior to commit:
  https://reviews.llvm.org/D25809?vs=80522=80635#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D25809

Files:
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/Sema/SemaCUDA.cpp
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/lib/Sema/SemaOverload.cpp
  cfe/trunk/lib/Sema/SemaTemplate.cpp
  cfe/trunk/test/CodeGenCUDA/launch-bounds.cu
  cfe/trunk/test/SemaCUDA/function-overload.cu
  cfe/trunk/test/SemaCUDA/function-template-overload.cu
  cfe/trunk/test/SemaCUDA/target_attr_inheritance.cu

Index: cfe/trunk/lib/Sema/SemaOverload.cpp
===
--- cfe/trunk/lib/Sema/SemaOverload.cpp
+++ cfe/trunk/lib/Sema/SemaOverload.cpp
@@ -580,6 +580,7 @@
   case Sema::TDK_TooManyArguments:
   case Sema::TDK_TooFewArguments:
   case Sema::TDK_MiscellaneousDeductionFailure:
+  case Sema::TDK_CUDATargetMismatch:
 Result.Data = nullptr;
 break;
 
@@ -647,6 +648,7 @@
   case Sema::TDK_TooFewArguments:
   case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_FailedOverloadResolution:
+  case Sema::TDK_CUDATargetMismatch:
 break;
 
   case Sema::TDK_Inconsistent:
@@ -689,6 +691,7 @@
   case Sema::TDK_DeducedMismatch:
   case Sema::TDK_NonDeducedMismatch:
   case Sema::TDK_FailedOverloadResolution:
+  case Sema::TDK_CUDATargetMismatch:
 return TemplateParameter();
 
   case Sema::TDK_Incomplete:
@@ -720,6 +723,7 @@
   case Sema::TDK_Underqualified:
   case Sema::TDK_NonDeducedMismatch:
   case Sema::TDK_FailedOverloadResolution:
+  case Sema::TDK_CUDATargetMismatch:
 return nullptr;
 
   case Sema::TDK_DeducedMismatch:
@@ -747,6 +751,7 @@
   case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_FailedOverloadResolution:
+  case Sema::TDK_CUDATargetMismatch:
 return nullptr;
 
   case Sema::TDK_Inconsistent:
@@ -774,6 +779,7 @@
   case Sema::TDK_InvalidExplicitArguments:
   case Sema::TDK_SubstitutionFailure:
   case Sema::TDK_FailedOverloadResolution:
+  case Sema::TDK_CUDATargetMismatch:
 return nullptr;
 
   case Sema::TDK_Inconsistent:
@@ -1139,20 +1145,11 @@
 
 CUDAFunctionTarget NewTarget = IdentifyCUDATarget(New),
OldTarget = IdentifyCUDATarget(Old);
-if (NewTarget == CFT_InvalidTarget || NewTarget == CFT_Global)
+if (NewTarget == CFT_InvalidTarget)
   return false;
 
 assert((OldTarget != CFT_InvalidTarget) && "Unexpected invalid target.");
 
-// Don't allow HD and global functions to overload other functions with the
-// same signature.  We allow overloading based on CUDA attributes so that
-// functions can have different implementations on the host and device, but
-// HD/global functions "exist" in some sense on both the host and device, so
-// should have the same implementation on both sides.
-if ((NewTarget == CFT_HostDevice) || (OldTarget == CFT_HostDevice) ||
-(NewTarget == CFT_Global) || (OldTarget == CFT_Global))
-  return false;
-
 // Allow overloading of functions with same signature and different CUDA
 // target attributes.
 return NewTarget != OldTarget;
@@ -9713,6 +9710,10 @@
 S.Diag(Templated->getLocation(), diag::note_ovl_candidate_bad_deduction);
 MaybeEmitInheritedConstructorNote(S, Found);
 return;
+  case Sema::TDK_CUDATargetMismatch:
+S.Diag(Templated->getLocation(),
+   diag::note_cuda_ovl_candidate_target_mismatch);
+return;
   }
 }
 
@@ -9969,6 +9970,7 @@
   case Sema::TDK_DeducedMismatch:
   case Sema::TDK_NonDeducedMismatch:
   case Sema::TDK_MiscellaneousDeductionFailure:
+  case Sema::TDK_CUDATargetMismatch:
 return 3;
 
   case Sema::TDK_InstantiationDepth:
Index: cfe/trunk/lib/Sema/SemaTemplate.cpp
===
--- cfe/trunk/lib/Sema/SemaTemplate.cpp
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp
@@ -7043,6 +7043,19 @@
 continue;
   }
 
+  // Target attributes are part of function signature during cuda
+  // compilation, so deduced template must also have matching CUDA
+  // target. Given that regular template deduction does not take
+  // target attributes into account, we perform target match check
+  // here and reject candidates that have different target.
+  if (LangOpts.CUDA &&
+  IdentifyCUDATarget(Specialization) != IdentifyCUDATarget(FD)) {
+FailedCandidates.addCandidate().set(
+I.getPair(), FunTmpl->getTemplatedDecl(),
+MakeDeductionFailureInfo(Context, TDK_CUDATargetMismatch, Info));
+continue;
+  }
+
   // Record this candidate.
   if (ExplicitTemplateArgs)
 ConvertedTemplateArgs[Specialization] = 

[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-12-07 Thread Justin Lebar via Phabricator via cfe-commits
jlebar added a comment.

> I've reverted to 75652

Did you forget to arc diff?

Anyway if it's just that if statement, lgtm.


https://reviews.llvm.org/D25809



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


[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-12-07 Thread Artem Belevich via Phabricator via cfe-commits
tra added a comment.

In https://reviews.llvm.org/D25809#615485, @jlebar wrote:

> If you would like me to have another look at this, is it possible to make an 
> interdiff of your changes between this and the last version I reviewed?  
> phab's interdiff is useless because it straddles a rebase.


I've reverted to 75652 which is the revision you've approved with a new if() to 
limit our overloading checks to FunctionDecls only.
It's a the very end of SemaCUDA.cpp (line 864):
https://reviews.llvm.org/differential/changeset/?ref=590934%2F556303=ignore-most


https://reviews.llvm.org/D25809



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


[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-12-06 Thread Justin Lebar via Phabricator via cfe-commits
jlebar added a comment.

If you would like me to have another look at this, is it possible to make an 
interdiff of your changes between this and the last version I reviewed?  phab's 
interdiff is useless because it straddles a rebase.


https://reviews.llvm.org/D25809



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


[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-12-06 Thread Justin Lebar via Phabricator via cfe-commits
jlebar added a comment.

(Alternatively I'm happy not to have another look if you don't think you need 
it.)


https://reviews.llvm.org/D25809



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


[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-12-06 Thread Artem Belevich via Phabricator via cfe-commits
tra updated this revision to Diff 80522.
tra added a comment.

Removed HD overloading checks for using declarations.
'using' exposes number of issues with the way we handle overloading of HD 
functions vs H/D.
The issues will be addressed in a separate patch.


https://reviews.llvm.org/D25809

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaCUDA.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  test/CodeGenCUDA/launch-bounds.cu
  test/SemaCUDA/function-overload.cu
  test/SemaCUDA/function-template-overload.cu
  test/SemaCUDA/target_attr_inheritance.cu

Index: test/SemaCUDA/target_attr_inheritance.cu
===
--- test/SemaCUDA/target_attr_inheritance.cu
+++ /dev/null
@@ -1,29 +0,0 @@
-// Verifies correct inheritance of target attributes during template
-// instantiation and specialization.
-
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
-
-#include "Inputs/cuda.h"
-
-// Function must inherit target attributes during instantiation, but not during
-// specialization.
-template  __host__ __device__ T function_template(const T );
-
-// Specialized functions have their own attributes.
-// expected-note@+1 {{candidate function not viable: call to __host__ function from __device__ function}}
-template <> __host__ float function_template(const float );
-
-// expected-note@+1 {{candidate function not viable: call to __device__ function from __host__ function}}
-template <> __device__ double function_template(const double );
-
-__host__ void hf() {
-  function_template(1.0f); // OK. Specialization is __host__.
-  function_template(2.0); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(1);   // OK. Instantiated function template is HD.
-}
-__device__ void df() {
-  function_template(3.0f); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(4.0); // OK. Specialization is __device__.
-  function_template(1);   // OK. Instantiated function template is HD.
-}
Index: test/SemaCUDA/function-template-overload.cu
===
--- /dev/null
+++ test/SemaCUDA/function-template-overload.cu
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
+
+#include "Inputs/cuda.h"
+
+struct HType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'DType'}}
+struct DType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'HType'}}
+struct HDType {};
+
+template  __host__ HType overload_h_d(T a) { return HType(); }
+// expected-note@-1 2 {{candidate template ignored: could not match 'HType' against 'DType'}}
+// expected-note@-2 2 {{candidate template ignored: target attributes do not match}}
+template  __device__ DType overload_h_d(T a) { return DType(); }
+// expected-note@-1 2 {{candidate template ignored: could not match 'DType' against 'HType'}}
+// expected-note@-2 2 {{candidate template ignored: target attributes do not match}}
+
+// Check explicit instantiation.
+template  __device__ __host__ DType overload_h_d(int a); // There's no HD template...
+// expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}}
+template  __device__ __host__ HType overload_h_d(int a); // There's no HD template...
+// expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}}
+template  __device__ DType overload_h_d(int a); // OK. instantiates D
+template  __host__ HType overload_h_d(int a); // OK. instantiates H
+
+// Check explicit specialization.
+template  <> __device__ __host__ DType overload_h_d(long a); // There's no HD template...
+// expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}}
+template  <> __device__ __host__ HType overload_h_d(long a); // There's no HD template...
+// expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}}
+template  <> __device__ DType overload_h_d(long a); // OK. instantiates D
+template  <> __host__ HType overload_h_d(long a); // OK. instantiates H
+
+
+// Can't overload HD template with H or D template, though functions are OK.
+template  __host__ __device__ HDType overload_hd(T a) { return HDType(); }
+// expected-note@-1 {{previous declaration is here}}
+// expected-note@-2 2 {{candidate template ignored: could not match 'HDType' against 

[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-25 Thread Justin Lebar via cfe-commits
jlebar added a comment.

Is it possible to write a testcase for the using-declaration change?


https://reviews.llvm.org/D25809



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


[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-25 Thread Artem Belevich via cfe-commits
tra updated this revision to Diff 75816.
tra added a comment.

- handle using declarations found in the overload set we check.


https://reviews.llvm.org/D25809

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaCUDA.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  test/CodeGenCUDA/launch-bounds.cu
  test/SemaCUDA/function-overload.cu
  test/SemaCUDA/function-template-overload.cu
  test/SemaCUDA/target_attr_inheritance.cu

Index: test/SemaCUDA/target_attr_inheritance.cu
===
--- test/SemaCUDA/target_attr_inheritance.cu
+++ /dev/null
@@ -1,29 +0,0 @@
-// Verifies correct inheritance of target attributes during template
-// instantiation and specialization.
-
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
-
-#include "Inputs/cuda.h"
-
-// Function must inherit target attributes during instantiation, but not during
-// specialization.
-template  __host__ __device__ T function_template(const T );
-
-// Specialized functions have their own attributes.
-// expected-note@+1 {{candidate function not viable: call to __host__ function from __device__ function}}
-template <> __host__ float function_template(const float );
-
-// expected-note@+1 {{candidate function not viable: call to __device__ function from __host__ function}}
-template <> __device__ double function_template(const double );
-
-__host__ void hf() {
-  function_template(1.0f); // OK. Specialization is __host__.
-  function_template(2.0); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(1);   // OK. Instantiated function template is HD.
-}
-__device__ void df() {
-  function_template(3.0f); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(4.0); // OK. Specialization is __device__.
-  function_template(1);   // OK. Instantiated function template is HD.
-}
Index: test/SemaCUDA/function-template-overload.cu
===
--- /dev/null
+++ test/SemaCUDA/function-template-overload.cu
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
+
+#include "Inputs/cuda.h"
+
+struct HType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'DType'}}
+struct DType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'HType'}}
+struct HDType {};
+
+template  __host__ HType overload_h_d(T a) { return HType(); }
+// expected-note@-1 2 {{candidate template ignored: could not match 'HType' against 'DType'}}
+// expected-note@-2 2 {{candidate template ignored: target attributes do not match}}
+template  __device__ DType overload_h_d(T a) { return DType(); }
+// expected-note@-1 2 {{candidate template ignored: could not match 'DType' against 'HType'}}
+// expected-note@-2 2 {{candidate template ignored: target attributes do not match}}
+
+// Check explicit instantiation.
+template  __device__ __host__ DType overload_h_d(int a); // There's no HD template...
+// expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}}
+template  __device__ __host__ HType overload_h_d(int a); // There's no HD template...
+// expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}}
+template  __device__ DType overload_h_d(int a); // OK. instantiates D
+template  __host__ HType overload_h_d(int a); // OK. instantiates H
+
+// Check explicit specialization.
+template  <> __device__ __host__ DType overload_h_d(long a); // There's no HD template...
+// expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}}
+template  <> __device__ __host__ HType overload_h_d(long a); // There's no HD template...
+// expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}}
+template  <> __device__ DType overload_h_d(long a); // OK. instantiates D
+template  <> __host__ HType overload_h_d(long a); // OK. instantiates H
+
+
+// Can't overload HD template with H or D template, though functions are OK.
+template  __host__ __device__ HDType overload_hd(T a) { return HDType(); }
+// expected-note@-1 {{previous declaration is here}}
+// expected-note@-2 2 {{candidate template ignored: could not match 'HDType' against 'HType'}}
+template  __device__ HDType overload_hd(T a);
+// expected-error@-1 {{__device__ function 'overload_hd' cannot overload __host__ 

[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-24 Thread Artem Belevich via cfe-commits
tra added inline comments.



Comment at: lib/Sema/SemaCUDA.cpp:791
+  CUDAFunctionTarget NewTarget = IdentifyCUDATarget(NewFD);
+  for (auto OldND : Previous) {
+FunctionDecl *OldFD = OldND->getAsFunction();

jlebar wrote:
> tra wrote:
> > jlebar wrote:
> > > If this is just a Decl* or NamedDecl*, can we write out the type?
> > I'm not sure what exactly you'd like to see. Diags will print out the line 
> > and target info for both sides.
> > Could you give me example of existing diagnostics that would be similar to 
> > what you want?
> Sorry, I just meant for you to change "auto" to the actual type.
Ah! That would be `NamedDecl *` Done..



Comment at: lib/Sema/SemaTemplate.cpp:7047
+  // target. Given that regular template deduction does not take
+  // it into account, we perform target match check here and
+  // reject candidates that have different target.

jlebar wrote:
> what is "it"?  Do you mean "the function signature", or something else?
it = "target attributes"


https://reviews.llvm.org/D25809



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


[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-24 Thread Artem Belevich via cfe-commits
tra updated this revision to Diff 75652.
tra marked an inline comment as done.
tra added a comment.

Addressed remaining nits.


https://reviews.llvm.org/D25809

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaCUDA.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  test/CodeGenCUDA/launch-bounds.cu
  test/SemaCUDA/function-overload.cu
  test/SemaCUDA/function-template-overload.cu
  test/SemaCUDA/target_attr_inheritance.cu

Index: test/SemaCUDA/target_attr_inheritance.cu
===
--- test/SemaCUDA/target_attr_inheritance.cu
+++ /dev/null
@@ -1,29 +0,0 @@
-// Verifies correct inheritance of target attributes during template
-// instantiation and specialization.
-
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
-
-#include "Inputs/cuda.h"
-
-// Function must inherit target attributes during instantiation, but not during
-// specialization.
-template  __host__ __device__ T function_template(const T );
-
-// Specialized functions have their own attributes.
-// expected-note@+1 {{candidate function not viable: call to __host__ function from __device__ function}}
-template <> __host__ float function_template(const float );
-
-// expected-note@+1 {{candidate function not viable: call to __device__ function from __host__ function}}
-template <> __device__ double function_template(const double );
-
-__host__ void hf() {
-  function_template(1.0f); // OK. Specialization is __host__.
-  function_template(2.0); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(1);   // OK. Instantiated function template is HD.
-}
-__device__ void df() {
-  function_template(3.0f); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(4.0); // OK. Specialization is __device__.
-  function_template(1);   // OK. Instantiated function template is HD.
-}
Index: test/SemaCUDA/function-template-overload.cu
===
--- /dev/null
+++ test/SemaCUDA/function-template-overload.cu
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
+
+#include "Inputs/cuda.h"
+
+struct HType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'DType'}}
+struct DType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'HType'}}
+struct HDType {};
+
+template  __host__ HType overload_h_d(T a) { return HType(); }
+// expected-note@-1 2 {{candidate template ignored: could not match 'HType' against 'DType'}}
+// expected-note@-2 2 {{candidate template ignored: target attributes do not match}}
+template  __device__ DType overload_h_d(T a) { return DType(); }
+// expected-note@-1 2 {{candidate template ignored: could not match 'DType' against 'HType'}}
+// expected-note@-2 2 {{candidate template ignored: target attributes do not match}}
+
+// Check explicit instantiation.
+template  __device__ __host__ DType overload_h_d(int a); // There's no HD template...
+// expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}}
+template  __device__ __host__ HType overload_h_d(int a); // There's no HD template...
+// expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}}
+template  __device__ DType overload_h_d(int a); // OK. instantiates D
+template  __host__ HType overload_h_d(int a); // OK. instantiates H
+
+// Check explicit specialization.
+template  <> __device__ __host__ DType overload_h_d(long a); // There's no HD template...
+// expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}}
+template  <> __device__ __host__ HType overload_h_d(long a); // There's no HD template...
+// expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}}
+template  <> __device__ DType overload_h_d(long a); // OK. instantiates D
+template  <> __host__ HType overload_h_d(long a); // OK. instantiates H
+
+
+// Can't overload HD template with H or D template, though functions are OK.
+template  __host__ __device__ HDType overload_hd(T a) { return HDType(); }
+// expected-note@-1 {{previous declaration is here}}
+// expected-note@-2 2 {{candidate template ignored: could not match 'HDType' against 'HType'}}
+template  __device__ HDType overload_hd(T a);
+// expected-error@-1 {{__device__ function 'overload_hd' cannot overload __host__ 

[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-21 Thread Justin Lebar via cfe-commits
jlebar accepted this revision.
jlebar added inline comments.
This revision is now accepted and ready to land.



Comment at: lib/Sema/SemaCUDA.cpp:87
+
+  if ((HasHostAttr && HasDeviceAttr) || ForceCUDAHostDeviceDepth > 0)
+return CFT_HostDevice;

tra wrote:
> jlebar wrote:
> > Checking ForceCUDAHostDeviceDepth here is...yeah.  Especially because the 
> > other overload of this function doesn't do it.
> > 
> > I know you get rid of it in the next patch, but how much work would it be 
> > to get rid of it here?  It definitely makes this patch harder to check.
> OK. Moved the check to the place where I use it.
Thank you -- I appreciate that.  :)



Comment at: lib/Sema/SemaCUDA.cpp:791
+  CUDAFunctionTarget NewTarget = IdentifyCUDATarget(NewFD);
+  for (auto OldND : Previous) {
+FunctionDecl *OldFD = OldND->getAsFunction();

tra wrote:
> jlebar wrote:
> > If this is just a Decl* or NamedDecl*, can we write out the type?
> I'm not sure what exactly you'd like to see. Diags will print out the line 
> and target info for both sides.
> Could you give me example of existing diagnostics that would be similar to 
> what you want?
Sorry, I just meant for you to change "auto" to the actual type.



Comment at: lib/Sema/SemaCUDA.cpp:793
+FunctionDecl *OldFD = OldND->getAsFunction();
+if (!OldFD || OldFD->isFunctionTemplateSpecialization())
+  continue;

tra wrote:
> jlebar wrote:
> > Please add a comment explaining why we ignore template specializations.
> That's another check that's no longer needed as the only template 
> instantiations/specializations that end up in the overload set are those that 
> were instantiated from templates with matching target.
> 
Even better.  :)



Comment at: lib/Sema/SemaTemplate.cpp:7047
+  // target. Given that regular template deduction does not take
+  // it into account, we perform target match check here and
+  // reject candidates that have different target.

what is "it"?  Do you mean "the function signature", or something else?


https://reviews.llvm.org/D25809



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


[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-21 Thread Artem Belevich via cfe-commits
tra updated this revision to Diff 75516.
tra added a comment.

removed pragma check from IdentifyCUDATarget for real.


https://reviews.llvm.org/D25809

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaCUDA.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  test/CodeGenCUDA/launch-bounds.cu
  test/SemaCUDA/function-overload.cu
  test/SemaCUDA/function-template-overload.cu
  test/SemaCUDA/target_attr_inheritance.cu

Index: test/SemaCUDA/target_attr_inheritance.cu
===
--- test/SemaCUDA/target_attr_inheritance.cu
+++ /dev/null
@@ -1,29 +0,0 @@
-// Verifies correct inheritance of target attributes during template
-// instantiation and specialization.
-
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
-
-#include "Inputs/cuda.h"
-
-// Function must inherit target attributes during instantiation, but not during
-// specialization.
-template  __host__ __device__ T function_template(const T );
-
-// Specialized functions have their own attributes.
-// expected-note@+1 {{candidate function not viable: call to __host__ function from __device__ function}}
-template <> __host__ float function_template(const float );
-
-// expected-note@+1 {{candidate function not viable: call to __device__ function from __host__ function}}
-template <> __device__ double function_template(const double );
-
-__host__ void hf() {
-  function_template(1.0f); // OK. Specialization is __host__.
-  function_template(2.0); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(1);   // OK. Instantiated function template is HD.
-}
-__device__ void df() {
-  function_template(3.0f); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(4.0); // OK. Specialization is __device__.
-  function_template(1);   // OK. Instantiated function template is HD.
-}
Index: test/SemaCUDA/function-template-overload.cu
===
--- /dev/null
+++ test/SemaCUDA/function-template-overload.cu
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
+
+#include "Inputs/cuda.h"
+
+struct HType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'DType'}}
+struct DType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'HType'}}
+struct HDType {};
+
+template  __host__ HType overload_h_d(T a) { return HType(); }
+// expected-note@-1 2 {{candidate template ignored: could not match 'HType' against 'DType'}}
+// expected-note@-2 2 {{candidate template ignored: target attributes do not match}}
+template  __device__ DType overload_h_d(T a) { return DType(); }
+// expected-note@-1 2 {{candidate template ignored: could not match 'DType' against 'HType'}}
+// expected-note@-2 2 {{candidate template ignored: target attributes do not match}}
+
+// Check explicit instantiation.
+template  __device__ __host__ DType overload_h_d(int a); // There's no HD template...
+// expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}}
+template  __device__ __host__ HType overload_h_d(int a); // There's no HD template...
+// expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}}
+template  __device__ DType overload_h_d(int a); // OK. instantiates D
+template  __host__ HType overload_h_d(int a); // OK. instantiates H
+
+// Check explicit specialization.
+template  <> __device__ __host__ DType overload_h_d(long a); // There's no HD template...
+// expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}}
+template  <> __device__ __host__ HType overload_h_d(long a); // There's no HD template...
+// expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}}
+template  <> __device__ DType overload_h_d(long a); // OK. instantiates D
+template  <> __host__ HType overload_h_d(long a); // OK. instantiates H
+
+
+// Can't overload HD template with H or D template, though functions are OK.
+template  __host__ __device__ HDType overload_hd(T a) { return HDType(); }
+// expected-note@-1 {{previous declaration is here}}
+// expected-note@-2 2 {{candidate template ignored: could not match 'HDType' against 'HType'}}
+template  __device__ HDType overload_hd(T a);
+// expected-error@-1 {{__device__ function 'overload_hd' cannot overload __host__ 

[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-21 Thread Artem Belevich via cfe-commits
tra added inline comments.



Comment at: lib/Sema/SemaCUDA.cpp:87
+
+  if ((HasHostAttr && HasDeviceAttr) || ForceCUDAHostDeviceDepth > 0)
+return CFT_HostDevice;

jlebar wrote:
> Checking ForceCUDAHostDeviceDepth here is...yeah.  Especially because the 
> other overload of this function doesn't do it.
> 
> I know you get rid of it in the next patch, but how much work would it be to 
> get rid of it here?  It definitely makes this patch harder to check.
OK. Moved the check to the place where I use it.



Comment at: lib/Sema/SemaCUDA.cpp:791
+  CUDAFunctionTarget NewTarget = IdentifyCUDATarget(NewFD);
+  for (auto OldND : Previous) {
+FunctionDecl *OldFD = OldND->getAsFunction();

jlebar wrote:
> If this is just a Decl* or NamedDecl*, can we write out the type?
I'm not sure what exactly you'd like to see. Diags will print out the line and 
target info for both sides.
Could you give me example of existing diagnostics that would be similar to what 
you want?



Comment at: lib/Sema/SemaCUDA.cpp:793
+FunctionDecl *OldFD = OldND->getAsFunction();
+if (!OldFD || OldFD->isFunctionTemplateSpecialization())
+  continue;

jlebar wrote:
> Please add a comment explaining why we ignore template specializations.
That's another check that's no longer needed as the only template 
instantiations/specializations that end up in the overload set are those that 
were instantiated from templates with matching target.




Comment at: lib/Sema/SemaTemplate.cpp:8117
+if (LangOpts.CUDA &&
+IdentifyCUDATarget(Specialization) != IdentifyCUDATarget(Attr)) {
+  FailedCandidates.addCandidate().set(

jlebar wrote:
> Can we just pass D here (and thus not write the new overload of 
> IdentifyCUDATarget)?
Nope. D is a Declarator which is very different form FunctionDecl.
It carries info about what we've parsed, but we didn't construct a FunctionDecl 
from it yet.


https://reviews.llvm.org/D25809



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


[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-21 Thread Artem Belevich via cfe-commits
tra updated this revision to Diff 75515.
tra marked 5 inline comments as done.
tra added a comment.

addressed jlebar's comments.


https://reviews.llvm.org/D25809

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaCUDA.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  test/CodeGenCUDA/launch-bounds.cu
  test/SemaCUDA/function-overload.cu
  test/SemaCUDA/function-template-overload.cu
  test/SemaCUDA/target_attr_inheritance.cu

Index: test/SemaCUDA/target_attr_inheritance.cu
===
--- test/SemaCUDA/target_attr_inheritance.cu
+++ /dev/null
@@ -1,29 +0,0 @@
-// Verifies correct inheritance of target attributes during template
-// instantiation and specialization.
-
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
-
-#include "Inputs/cuda.h"
-
-// Function must inherit target attributes during instantiation, but not during
-// specialization.
-template  __host__ __device__ T function_template(const T );
-
-// Specialized functions have their own attributes.
-// expected-note@+1 {{candidate function not viable: call to __host__ function from __device__ function}}
-template <> __host__ float function_template(const float );
-
-// expected-note@+1 {{candidate function not viable: call to __device__ function from __host__ function}}
-template <> __device__ double function_template(const double );
-
-__host__ void hf() {
-  function_template(1.0f); // OK. Specialization is __host__.
-  function_template(2.0); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(1);   // OK. Instantiated function template is HD.
-}
-__device__ void df() {
-  function_template(3.0f); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(4.0); // OK. Specialization is __device__.
-  function_template(1);   // OK. Instantiated function template is HD.
-}
Index: test/SemaCUDA/function-template-overload.cu
===
--- /dev/null
+++ test/SemaCUDA/function-template-overload.cu
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
+
+#include "Inputs/cuda.h"
+
+struct HType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'DType'}}
+struct DType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'HType'}}
+struct HDType {};
+
+template  __host__ HType overload_h_d(T a) { return HType(); }
+// expected-note@-1 2 {{candidate template ignored: could not match 'HType' against 'DType'}}
+// expected-note@-2 2 {{candidate template ignored: target attributes do not match}}
+template  __device__ DType overload_h_d(T a) { return DType(); }
+// expected-note@-1 2 {{candidate template ignored: could not match 'DType' against 'HType'}}
+// expected-note@-2 2 {{candidate template ignored: target attributes do not match}}
+
+// Check explicit instantiation.
+template  __device__ __host__ DType overload_h_d(int a); // There's no HD template...
+// expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}}
+template  __device__ __host__ HType overload_h_d(int a); // There's no HD template...
+// expected-error@-1 {{explicit instantiation of 'overload_h_d' does not refer to a function template, variable template, member function, member class, or static data member}}
+template  __device__ DType overload_h_d(int a); // OK. instantiates D
+template  __host__ HType overload_h_d(int a); // OK. instantiates H
+
+// Check explicit specialization.
+template  <> __device__ __host__ DType overload_h_d(long a); // There's no HD template...
+// expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}}
+template  <> __device__ __host__ HType overload_h_d(long a); // There's no HD template...
+// expected-error@-1 {{no function template matches function template specialization 'overload_h_d'}}
+template  <> __device__ DType overload_h_d(long a); // OK. instantiates D
+template  <> __host__ HType overload_h_d(long a); // OK. instantiates H
+
+
+// Can't overload HD template with H or D template, though functions are OK.
+template  __host__ __device__ HDType overload_hd(T a) { return HDType(); }
+// expected-note@-1 {{previous declaration is here}}
+// expected-note@-2 2 {{candidate template ignored: could not match 'HDType' against 'HType'}}
+template  __device__ HDType overload_hd(T a);
+// expected-error@-1 {{__device__ function 'overload_hd' cannot overload 

[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-21 Thread Justin Lebar via cfe-commits
jlebar added inline comments.



Comment at: test/SemaCUDA/function-template-overload.cu:44
+// explicitly specialize or instantiate function tempaltes.
+template <> __host__ HType overload_hd(int a);
+// expected-error@-1 {{no function template matches function template 
specialization 'overload_hd'}}

jlebar wrote:
> Please ignore the above comment; it is not correct, but I cannot delete it or 
> edit it in phab.  :-/
(Wow, it also didn't submit the comment I was referring to.  How broken.)


https://reviews.llvm.org/D25809



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


[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-21 Thread Justin Lebar via cfe-commits
jlebar added inline comments.



Comment at: lib/Sema/SemaCUDA.cpp:87
+
+  if ((HasHostAttr && HasDeviceAttr) || ForceCUDAHostDeviceDepth > 0)
+return CFT_HostDevice;

Checking ForceCUDAHostDeviceDepth here is...yeah.  Especially because the other 
overload of this function doesn't do it.

I know you get rid of it in the next patch, but how much work would it be to 
get rid of it here?  It definitely makes this patch harder to check.



Comment at: lib/Sema/SemaCUDA.cpp:790
+   LookupResult ) {
+  CUDAFunctionTarget NewTarget = IdentifyCUDATarget(NewFD);
+  for (auto OldND : Previous) {

Nit, can we assert that we're in cuda mode?



Comment at: lib/Sema/SemaCUDA.cpp:791
+  CUDAFunctionTarget NewTarget = IdentifyCUDATarget(NewFD);
+  for (auto OldND : Previous) {
+FunctionDecl *OldFD = OldND->getAsFunction();

If this is just a Decl* or NamedDecl*, can we write out the type?



Comment at: lib/Sema/SemaCUDA.cpp:793
+FunctionDecl *OldFD = OldND->getAsFunction();
+if (!OldFD || OldFD->isFunctionTemplateSpecialization())
+  continue;

Please add a comment explaining why we ignore template specializations.



Comment at: lib/Sema/SemaTemplate.cpp:7044
 
+  // Filter out matches that have different target.
+  if (LangOpts.CUDA &&

Can we have a better comment here?  (And, can we expand upon it in D25845?)



Comment at: lib/Sema/SemaTemplate.cpp:8117
+if (LangOpts.CUDA &&
+IdentifyCUDATarget(Specialization) != IdentifyCUDATarget(Attr)) {
+  FailedCandidates.addCandidate().set(

Can we just pass D here (and thus not write the new overload of 
IdentifyCUDATarget)?



Comment at: test/SemaCUDA/function-template-overload.cu:34
+
+// Can't overload HD template with H or D template, though functions are OK.
+template  __host__ __device__ HDType overload_hd(T a) { return 
HDType(); }

"though non-template functions are OK"?



Comment at: test/SemaCUDA/function-template-overload.cu:44
+// explicitly specialize or instantiate function tempaltes.
+template <> __host__ HType overload_hd(int a);
+// expected-error@-1 {{no function template matches function template 
specialization 'overload_hd'}}

This is OK:

  template  __host__ __device__ HDType overload_hd(T a);
  template <> __host__ HType overload_hd(int a);

but this is not OK:

  template  __host__ HType overload_h_d(T a) { return HType(); }
  template  __device__ DType overload_h_d(T a) { return DType(); }
  template  <> __device__ __host__ DType overload_h_d(long a);

Is the rule that you *can* specialize an HD function template as H or D, but 
you can't go in reverse?  If so, I am not getting that from the commit message 
or comments here.

Like in D25705, please clarify this somewhere in the code (and commit message) 
if this isn't just me blatantly misreading things (which is possible).



Comment at: test/SemaCUDA/function-template-overload.cu:44
+// explicitly specialize or instantiate function tempaltes.
+template <> __host__ HType overload_hd(int a);
+// expected-error@-1 {{no function template matches function template 
specialization 'overload_hd'}}

Please ignore the above comment; it is not correct, but I cannot delete it or 
edit it in phab.  :-/


https://reviews.llvm.org/D25809



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


[PATCH] D25809: [CUDA] Improved target attribute-based overloading.

2016-10-19 Thread Artem Belevich via cfe-commits
tra created this revision.
tra added reviewers: jlebar, rsmith.
tra added a subscriber: cfe-commits.

Current behavior:

- __host__ __device__ (HD) functions are considered to be redeclarations of 
`__host__` (H) of `__device__` (D) functions with same signature.
- Target attributes are not taken into account during selection of function 
template during explicit instantiation and specialization.

Issues:
a) It's possible for a H or D function to inherit HD attributes from a HD 
declaration which results in those functions being silently treated as HD in 
the rest of the code which leads to clang accepting the code instead of 
diagnosing it as an error.
b) If we have definitions of HD and a H or D function, compiler complains about 
redefinition of the same function, which is misleading.
c) It is impossible to disambiguate across target-overloaded function templates 
during explicit instantiation/specialization.

Changes in this patch:
a) treat HD functions as overloads and add Sema checks to explicitly diagnose 
attempts to overload HD functions with H or D ones.
b) Require matching target attributes for explicit function template 
instantiation/specialization and narrow list of candidates to templates with 
the same target. Diagnose rejected candidates.

The changes (a) and (b) can be split into separate patches, but both must be 
committed simultaneously as
(a) alone further breaks function template instantiation/specialization when 
target attributes are involved and (b) is half-broken until (a) is in place and 
prevents HD attributes merging into functions with H or D attributes.

Open issues:

- It's not clear how to handle explicit specialization of constexpr function 
templates:
  - Implicit target attributes of constexpr functions and templates change 
depending on whether -fno-cuda-host-device-constexpr is in effect.
  - C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr function 
can differ from the template declaration with respect to the constexpr 
specifier.

One idea is to only match explicitly written target attributes when we choose 
candidate templates. This makes it easier to tell which template we instantiate 
based only on what's in the source we compile.


https://reviews.llvm.org/D25809

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaCUDA.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  test/CodeGenCUDA/launch-bounds.cu
  test/SemaCUDA/function-overload.cu
  test/SemaCUDA/function-template-overload.cu
  test/SemaCUDA/target_attr_inheritance.cu

Index: test/SemaCUDA/target_attr_inheritance.cu
===
--- test/SemaCUDA/target_attr_inheritance.cu
+++ /dev/null
@@ -1,29 +0,0 @@
-// Verifies correct inheritance of target attributes during template
-// instantiation and specialization.
-
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
-// RUN: %clang_cc1 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
-
-#include "Inputs/cuda.h"
-
-// Function must inherit target attributes during instantiation, but not during
-// specialization.
-template  __host__ __device__ T function_template(const T );
-
-// Specialized functions have their own attributes.
-// expected-note@+1 {{candidate function not viable: call to __host__ function from __device__ function}}
-template <> __host__ float function_template(const float );
-
-// expected-note@+1 {{candidate function not viable: call to __device__ function from __host__ function}}
-template <> __device__ double function_template(const double );
-
-__host__ void hf() {
-  function_template(1.0f); // OK. Specialization is __host__.
-  function_template(2.0); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(1);   // OK. Instantiated function template is HD.
-}
-__device__ void df() {
-  function_template(3.0f); // expected-error {{no matching function for call to 'function_template'}}
-  function_template(4.0); // OK. Specialization is __device__.
-  function_template(1);   // OK. Instantiated function template is HD.
-}
Index: test/SemaCUDA/function-template-overload.cu
===
--- /dev/null
+++ test/SemaCUDA/function-template-overload.cu
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only -fcuda-is-device -verify %s
+
+#include "Inputs/cuda.h"
+
+struct HType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'DType'}}
+struct DType {}; // expected-note-re 6 {{candidate constructor {{.*}} not viable: no known conversion from 'HType'}}
+struct HDType {};
+
+template  __host__ HType overload_h_d(T a) { return HType(); }
+// expected-note@-1 2 {{candidate