diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 6eb129436f337..9a2895e24d000 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -38,6 +38,23 @@ static const unsigned SPIRAddrSpaceMap[] = { 4, // sycl_generic }; +static const unsigned SYCLAddrSpaceMap[] = { + 4, // Default + 1, // opencl_global + 3, // opencl_local + 2, // opencl_constant + 0, // opencl_private + 4, // opencl_generic + 0, // cuda_device + 0, // cuda_constant + 0, // cuda_shared + 1, // sycl_global + 3, // sycl_local + 2, // sycl_constant + 0, // sycl_private + 4, // sycl_generic +}; + class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo { public: SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &) @@ -45,7 +62,12 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo { TLSSupported = false; VLASupported = false; LongWidth = LongAlign = 64; - AddrSpaceMap = &SPIRAddrSpaceMap; + if (Triple.getEnvironment() == llvm::Triple::SYCLDevice && + getenv("ENABLE_INFER_AS")) { + AddrSpaceMap = &SYCLAddrSpaceMap; + } else { + AddrSpaceMap = &SPIRAddrSpaceMap; + } UseAddrSpaceMapMangling = true; HasLegalHalfType = true; HasFloat16 = true; diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 6e6d6556e94d6..852de2d0be5a0 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -840,7 +840,8 @@ void EmitAssemblyHelper::EmitAssembly(BackendAction Action, case Backend_EmitBC: if (LangOpts.SYCLIsDevice) { - PerModulePasses.add(createASFixerPass()); + if (!getenv("ENABLE_INFER_AS")) + PerModulePasses.add(createASFixerPass()); PerModulePasses.add(createDeadCodeEliminationPass()); } if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) { @@ -1188,7 +1189,8 @@ void EmitAssemblyHelper::EmitAssemblyWithNewPassManager( case Backend_EmitBC: if (LangOpts.SYCLIsDevice) { - CodeGenPasses.add(createASFixerPass()); + if (!getenv("ENABLE_INFER_AS")) + CodeGenPasses.add(createASFixerPass()); CodeGenPasses.add(createDeadCodeEliminationPass()); } if (CodeGenOpts.PrepareForThinLTO && !CodeGenOpts.DisableLLVMPasses) { diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 2a47d9bb993f8..38660e3cc137b 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4278,6 +4278,22 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (!CallArgs.getCleanupsToDeactivate().empty()) deactivateArgCleanupsBeforeCall(*this, CallArgs); + // Addrspace cast to generic if necessary + if (getenv("ENABLE_INFER_AS")) { + for (unsigned i = 0; i < IRFuncTy->getNumParams(); ++i) { + if (auto *PtrTy = dyn_cast(IRCallArgs[i]->getType())) { + auto *ExpectedPtrType = + cast(IRFuncTy->getParamType(i)); + unsigned ValueAS = PtrTy->getAddressSpace(); + unsigned ExpectedAS = ExpectedPtrType->getAddressSpace(); + if (ValueAS != ExpectedAS) { + IRCallArgs[i] = Builder.CreatePointerBitCastOrAddrSpaceCast( + IRCallArgs[i], ExpectedPtrType); + } + } + } + } + // Assert that the arguments we computed match up. The IR verifier // will catch this, but this is a common enough source of problems // during IRGen changes that it's way better for debugging to catch diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index f45b28098558d..a568797d9eb83 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -316,7 +316,7 @@ Address CodeGenFunction::GetAddressOfBaseClass( EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(), DerivedTy, DerivedAlign, SkippedChecks); } - return Builder.CreateBitCast(Value, BasePtrTy); + return Builder.CreatePointerBitCastOrAddrSpaceCast(Value, BasePtrTy); } llvm::BasicBlock *origBB = nullptr; diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 6b559455fde30..f32f21e10b519 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1089,10 +1089,8 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E, CodeGenFunction::CFITCK_UnrelatedCast, CE->getBeginLoc()); } - return CE->getCastKind() != CK_AddressSpaceConversion - ? Builder.CreateBitCast(Addr, ConvertType(E->getType())) - : Builder.CreateAddrSpaceCast(Addr, - ConvertType(E->getType())); + return Builder.CreatePointerBitCastOrAddrSpaceCast( + Addr, ConvertType(E->getType())); } break; @@ -1741,6 +1739,18 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, return; } + if (getenv("ENABLE_INFER_AS")) { + if (auto *PtrTy = dyn_cast(Value->getType())) { + auto *ExpectedPtrType = + cast(Addr.getType()->getElementType()); + unsigned ValueAS = PtrTy->getAddressSpace(); + unsigned ExpectedAS = ExpectedPtrType->getAddressSpace(); + if (ValueAS != ExpectedAS) { + Value = + Builder.CreatePointerBitCastOrAddrSpaceCast(Value, ExpectedPtrType); + } + } + } llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile); if (isNontemporal) { llvm::MDNode *Node = diff --git a/clang/test/CodeGenSYCL/address-space-new.cpp b/clang/test/CodeGenSYCL/address-space-new.cpp new file mode 100644 index 0000000000000..15df1b64e032d --- /dev/null +++ b/clang/test/CodeGenSYCL/address-space-new.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -disable-llvm-passes -emit-llvm -x c++ %s -o - | FileCheck %s --check-prefix=CHECK-DEFAULT +// RUN: ENABLE_INFER_AS=1 %clang_cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -disable-llvm-passes -emit-llvm -x c++ %s -o - | FileCheck %s --check-prefix=CHECK-NEW + + +void test() { + int i = 0; + int *pptr = &i; + // CHECK-DEFAULT: store i32* %i, i32** %pptr + // CHECK-NEW: %[[GEN:[0-9]+]] = addrspacecast i32* %i to i32 addrspace(4)* + // CHECK-NEW: store i32 addrspace(4)* %[[GEN]], i32 addrspace(4)** %pptr +} + + +template +__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) { + kernelFunc(); +} + + +int main() { + kernel_single_task([]() { test(); }); + return 0; +}