yaxunl created this revision. yaxunl added a reviewer: tra. When implicit HD function calls a function in device compilation, if one candidate is an implicit HD function, current solution rule is:
D wins over HD and H HD and H are equal this caused regression when there is an otherwise worse D candidate This patch changes that to D, HD and H are all equal The rationale is that we already know for host compilation there is already a valid candidate in HD and H candidates that will not cause error. Allowing HD and H gives us a fall back candidate that will not cause error. If D wins, that means D has to be a better match otherwise, therefore D should also be a valid candidate that will not cause error. In this way, we can guarantee no regression. https://reviews.llvm.org/D80450 Files: clang/lib/Sema/SemaOverload.cpp clang/test/SemaCUDA/function-overload.cu Index: clang/test/SemaCUDA/function-overload.cu =================================================================== --- clang/test/SemaCUDA/function-overload.cu +++ clang/test/SemaCUDA/function-overload.cu @@ -541,3 +541,51 @@ } }; } + +// Implicit HD candidate competes with device candidate. +// a and b have implicit HD copy ctor. In copy ctor of b, ctor of a is resolved. +// copy ctor of a should win over a(short), otherwise there will be ambiguity +// due to conversion operator. +namespace TestImplicitHDWithD { + struct a { + __attribute__((device)) a(short); + __attribute__((device)) operator unsigned() const; + __attribute__((device)) operator int() const; + }; + struct b { + a d; + }; + void f(b g) { b e = g; } +} + +// Implicit HD candidate competes with host candidate. +// a and b have implicit HD copy ctor. In copy ctor of b, ctor of a is resolved. +// copy ctor of a should win over a(short), otherwise there will be ambiguity +// due to conversion operator. +namespace TestImplicitHDWithH { + struct a { + a(short); + __attribute__((device)) operator unsigned() const; + __attribute__((device)) operator int() const; + }; + struct b { + a d; + }; + void f(b g) { b e = g; } +} + +// Implicit HD candidate comptes with HD candidate. +// a and b have implicit HD copy ctor. In copy ctor of b, ctor of a is resolved. +// copy ctor of a should win over a(short), otherwise there will be ambiguity +// due to conversion operator. +namespace TestImplicitHDWithHD { + struct a { + __attribute__((host,device)) a(short); + __attribute__((device)) operator unsigned() const; + __attribute__((device)) operator int() const; + }; + struct b { + a d; + }; + void f(b g) { b e = g; } +} Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -9534,7 +9534,7 @@ auto EmitThreshold = (S.getLangOpts().CUDAIsDevice && IsCallerImplicitHD && (IsCand1ImplicitHD || IsCand2ImplicitHD)) - ? Sema::CFP_HostDevice + ? Sema::CFP_Never : Sema::CFP_WrongSide; auto Cand1Emittable = P1 > EmitThreshold; auto Cand2Emittable = P2 > EmitThreshold;
Index: clang/test/SemaCUDA/function-overload.cu =================================================================== --- clang/test/SemaCUDA/function-overload.cu +++ clang/test/SemaCUDA/function-overload.cu @@ -541,3 +541,51 @@ } }; } + +// Implicit HD candidate competes with device candidate. +// a and b have implicit HD copy ctor. In copy ctor of b, ctor of a is resolved. +// copy ctor of a should win over a(short), otherwise there will be ambiguity +// due to conversion operator. +namespace TestImplicitHDWithD { + struct a { + __attribute__((device)) a(short); + __attribute__((device)) operator unsigned() const; + __attribute__((device)) operator int() const; + }; + struct b { + a d; + }; + void f(b g) { b e = g; } +} + +// Implicit HD candidate competes with host candidate. +// a and b have implicit HD copy ctor. In copy ctor of b, ctor of a is resolved. +// copy ctor of a should win over a(short), otherwise there will be ambiguity +// due to conversion operator. +namespace TestImplicitHDWithH { + struct a { + a(short); + __attribute__((device)) operator unsigned() const; + __attribute__((device)) operator int() const; + }; + struct b { + a d; + }; + void f(b g) { b e = g; } +} + +// Implicit HD candidate comptes with HD candidate. +// a and b have implicit HD copy ctor. In copy ctor of b, ctor of a is resolved. +// copy ctor of a should win over a(short), otherwise there will be ambiguity +// due to conversion operator. +namespace TestImplicitHDWithHD { + struct a { + __attribute__((host,device)) a(short); + __attribute__((device)) operator unsigned() const; + __attribute__((device)) operator int() const; + }; + struct b { + a d; + }; + void f(b g) { b e = g; } +} Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -9534,7 +9534,7 @@ auto EmitThreshold = (S.getLangOpts().CUDAIsDevice && IsCallerImplicitHD && (IsCand1ImplicitHD || IsCand2ImplicitHD)) - ? Sema::CFP_HostDevice + ? Sema::CFP_Never : Sema::CFP_WrongSide; auto Cand1Emittable = P1 > EmitThreshold; auto Cand2Emittable = P2 > EmitThreshold;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits