Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1773,6 +1773,9 @@ Group, HelpText<"Generate additional code for specified of debugger ABI (AMDGPU only)">, MetaVarName<"">; +def mnew_addr : Flag<["-"], "mnew-addr">, + Group, + HelpText<"Use new address space mapping for AMDGPU target">; def mvsx : Flag<["-"], "mvsx">, Group; def mno_vsx : Flag<["-"], "mno-vsx">, Group; Index: lib/Basic/Targets.cpp =================================================================== --- lib/Basic/Targets.cpp +++ lib/Basic/Targets.cpp @@ -1997,16 +1997,6 @@ return llvm::makeArrayRef(GCCRegNames); } -static const unsigned AMDGPUAddrSpaceMap[] = { - 1, // opencl_global - 3, // opencl_local - 2, // opencl_constant - 4, // opencl_generic - 1, // cuda_device - 2, // cuda_constant - 3 // cuda_shared -}; - // If you edit the description strings, make sure you update // getPointerWidthV(). @@ -2014,15 +2004,65 @@ "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; -static const char *const DataLayoutStringSI = +static const char *const DataLayoutStringSIOld = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32" "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; +static const char *const DataLayoutStringSINew = + "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32" + "-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128" + "-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64"; + class AMDGPUTargetInfo final : public TargetInfo { static const Builtin::Info BuiltinInfo[]; static const char * const GCCRegNames[]; + struct AddrSpace { + unsigned Generic, Global, Local, Constant, Private; + bool UseNew; + AddrSpace(bool UseNew_ = false){ + reset(UseNew_); + } + void reset(bool UseNew_) { + UseNew = UseNew_; + if (UseNew) { + Generic = 0; + Global = 1; + Local = 3; + Constant = 4; + Private = 5; + } else { + Generic = 4; + Global = 1; + Local = 3; + Constant = 2; + Private = 0; + } + } + const LangAS::Map *getMap() { + static LangAS::Map OldMap = { + 1, // opencl_global + 3, // opencl_local + 2, // opencl_constant + 4, // opencl_generic + 1, // cuda_device + 2, // cuda_constant + 3 // cuda_shared + }; + static LangAS::Map NewMap = { + 1, // opencl_global + 3, // opencl_local + 4, // opencl_constant + 0, // opencl_generic + 1, // cuda_device + 4, // cuda_constant + 3 // cuda_shared + }; + return UseNew ? &NewMap : &OldMap; + } + }; + /// \brief The GPU profiles supported by the AMDGPU target. enum GPUKind { GK_NONE, @@ -2044,6 +2084,7 @@ bool hasFMAF:1; bool hasLDEXPF:1; bool hasFullSpeedFP32Denorms:1; + bool UseNewAddrMap:1; static bool isAMDGCN(const llvm::Triple &TT) { return TT.getArch() == llvm::Triple::amdgcn; @@ -2056,17 +2097,29 @@ hasFP64(false), hasFMAF(false), hasLDEXPF(false), - hasFullSpeedFP32Denorms(false){ + hasFullSpeedFP32Denorms(false), + UseNewAddrMap(false){ if (getTriple().getArch() == llvm::Triple::amdgcn) { hasFP64 = true; hasFMAF = true; hasLDEXPF = true; } + // At this stage, Opt.Features has not been populated yet. + for (auto &I:Opts.FeaturesAsWritten) { + if (I == "+new-addr") { + UseNewAddrMap = true; + } else if (I == "-new-addr") { + UseNewAddrMap = false; + } + } + AS.reset(UseNewAddrMap); resetDataLayout(getTriple().getArch() == llvm::Triple::amdgcn ? - DataLayoutStringSI : DataLayoutStringR600); + (UseNewAddrMap ? DataLayoutStringSINew : + DataLayoutStringSIOld) + : DataLayoutStringR600); - AddrSpaceMap = &AMDGPUAddrSpaceMap; + AddrSpaceMap = AS.getMap(); UseAddrSpaceMapMangling = true; } @@ -2074,14 +2127,10 @@ if (GPU <= GK_CAYMAN) return 32; - switch(AddrSpace) { - default: - return 64; - case 0: - case 3: - case 5: - return 32; + if (AddrSpace == AS.Private || AddrSpace == AS.Local) { + return 32; } + return 64; } uint64_t getMaxPointerWidth() const override { @@ -2300,6 +2349,8 @@ uint64_t getNullPointerValue(unsigned AS) const override { return AS == LangAS::opencl_local ? ~0 : 0; } + + AddrSpace AS; }; const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = { Index: test/CodeGenOpenCL/amdgpu-new-addr.cl =================================================================== --- /dev/null +++ test/CodeGenOpenCL/amdgpu-new-addr.cl @@ -0,0 +1,7 @@ +// RUN: %clang_cc1 %s -O0 -triple amdgcn -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -O0 -triple amdgcn -target-feature "+new-addr" -emit-llvm -o - | FileCheck -check-prefix=NEW %s + +// CHECK: target datalayout = "e-p:32:32-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64" +// NEW: target datalayout = "e-p:64:64-p1:64:64-p2:64:64-p3:32:32-p4:64:64-p5:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64" +void foo(void) {} +