@@ -2740,6 +2740,16 @@ void CodeGenModule::EmitDeferred() {
2740
2740
CurDeclsToEmit.swap (DeferredDeclsToEmit);
2741
2741
2742
2742
for (GlobalDecl &D : CurDeclsToEmit) {
2743
+ // Emit a dummy __host__ function if a legit one is not already present in
2744
+ // case of SYCL compilation of CUDA sources.
2745
+ if (LangOpts.CUDA && !LangOpts.CUDAIsDevice && LangOpts.SYCLIsHost ) {
2746
+ GlobalDecl OtherD;
2747
+ if (lookupRepresentativeDecl (getMangledName (D), OtherD) &&
2748
+ (D.getCanonicalDecl ().getDecl () !=
2749
+ OtherD.getCanonicalDecl ().getDecl ())) {
2750
+ continue ;
2751
+ }
2752
+ }
2743
2753
const ValueDecl *VD = cast<ValueDecl>(D.getDecl ());
2744
2754
// If emitting for SYCL device, emit the deferred alias
2745
2755
// as well as what it aliases.
@@ -3381,11 +3391,17 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
3381
3391
// size and host-side address in order to provide access to
3382
3392
// their device-side incarnations.
3383
3393
3384
- // So device-only functions are the only things we skip.
3394
+ // So device-only functions are the only things we skip, except for SYCL .
3385
3395
if (isa<FunctionDecl>(Global) && !Global->hasAttr <CUDAHostAttr>() &&
3386
- Global->hasAttr <CUDADeviceAttr>())
3396
+ Global->hasAttr <CUDADeviceAttr>()) {
3397
+ // In SYCL, every (CUDA) __device__ function needs to have a __host__
3398
+ // counterpart that will be emitted in case of it is not already
3399
+ // present.
3400
+ if (LangOpts.SYCLIsHost && MustBeEmitted (Global) &&
3401
+ MayBeEmittedEagerly (Global))
3402
+ addDeferredDeclToEmit (GD);
3387
3403
return ;
3388
-
3404
+ }
3389
3405
assert ((isa<FunctionDecl>(Global) || isa<VarDecl>(Global)) &&
3390
3406
" Expected Variable or Function" );
3391
3407
}
0 commit comments