Author: jlebar Date: Thu Jan 5 10:53:21 2017 New Revision: 291135 URL: http://llvm.org/viewvc/llvm-project?rev=291135&view=rev Log: [CUDA] More correctly inherit primitive types from the host during device compilation.
Summary: CUDA lets users share structs between the host and device, so for that and other reasons, primitive types such as ptrdiff_t should be the same on both sides of the compilation. Our code to do this wasn't entirely successful. In particular, we did a bunch of work during the NVPTXTargetInfo constructor, only to override it in the NVPTX{32,64}TargetInfo constructors. It worked well enough on Linux and Mac, but Windows is LLP64, which is different enough to break it. This patch removes the NVPTX{32,64}TargetInfo classes entirely and fixes the bug described above. Reviewers: tra Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D28322 Modified: cfe/trunk/lib/Basic/Targets.cpp cfe/trunk/test/Preprocessor/cuda-types.cu Modified: cfe/trunk/lib/Basic/Targets.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets.cpp?rev=291135&r1=291134&r2=291135&view=diff ============================================================================== --- cfe/trunk/lib/Basic/Targets.cpp (original) +++ cfe/trunk/lib/Basic/Targets.cpp Thu Jan 5 10:53:21 2017 @@ -1751,30 +1751,57 @@ class NVPTXTargetInfo : public TargetInf static const char *const GCCRegNames[]; static const Builtin::Info BuiltinInfo[]; CudaArch GPU; + std::unique_ptr<TargetInfo> HostTarget; public: - NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) + NVPTXTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts, + unsigned TargetPointerWidth) : TargetInfo(Triple) { + assert((TargetPointerWidth == 32 || TargetPointerWidth == 64) && + "NVPTX only supports 32- and 64-bit modes."); + TLSSupported = false; - LongWidth = LongAlign = 64; AddrSpaceMap = &NVPTXAddrSpaceMap; UseAddrSpaceMapMangling = true; + // Define available target features // These must be defined in sorted order! NoAsmVariants = true; GPU = CudaArch::SM_20; + if (TargetPointerWidth == 32) + resetDataLayout("e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"); + else + resetDataLayout("e-i64:64-v16:16-v32:32-n16:32:64"); + // If possible, get a TargetInfo for our host triple, so we can match its // types. llvm::Triple HostTriple(Opts.HostTriple); - if (HostTriple.isNVPTX()) - return; - std::unique_ptr<TargetInfo> HostTarget( - AllocateTarget(llvm::Triple(Opts.HostTriple), Opts)); + if (!HostTriple.isNVPTX()) + HostTarget.reset(AllocateTarget(llvm::Triple(Opts.HostTriple), Opts)); + + // If no host target, make some guesses about the data layout and return. if (!HostTarget) { + LongWidth = LongAlign = TargetPointerWidth; + PointerWidth = PointerAlign = TargetPointerWidth; + switch (TargetPointerWidth) { + case 32: + SizeType = TargetInfo::UnsignedInt; + PtrDiffType = TargetInfo::SignedInt; + IntPtrType = TargetInfo::SignedInt; + break; + case 64: + SizeType = TargetInfo::UnsignedLong; + PtrDiffType = TargetInfo::SignedLong; + IntPtrType = TargetInfo::SignedLong; + break; + default: + llvm_unreachable("TargetPointerWidth must be 32 or 64"); + } return; } + // Copy properties from host target. PointerWidth = HostTarget->getPointerWidth(/* AddrSpace = */ 0); PointerAlign = HostTarget->getPointerAlign(/* AddrSpace = */ 0); BoolWidth = HostTarget->getBoolWidth(); @@ -1953,31 +1980,6 @@ ArrayRef<const char *> NVPTXTargetInfo:: return llvm::makeArrayRef(GCCRegNames); } -class NVPTX32TargetInfo : public NVPTXTargetInfo { -public: - NVPTX32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : NVPTXTargetInfo(Triple, Opts) { - LongWidth = LongAlign = 32; - PointerWidth = PointerAlign = 32; - SizeType = TargetInfo::UnsignedInt; - PtrDiffType = TargetInfo::SignedInt; - IntPtrType = TargetInfo::SignedInt; - resetDataLayout("e-p:32:32-i64:64-v16:16-v32:32-n16:32:64"); - } -}; - -class NVPTX64TargetInfo : public NVPTXTargetInfo { -public: - NVPTX64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) - : NVPTXTargetInfo(Triple, Opts) { - PointerWidth = PointerAlign = 64; - SizeType = TargetInfo::UnsignedLong; - PtrDiffType = TargetInfo::SignedLong; - IntPtrType = TargetInfo::SignedLong; - resetDataLayout("e-i64:64-v16:16-v32:32-n16:32:64"); - } -}; - static const unsigned AMDGPUAddrSpaceMap[] = { 1, // opencl_global 3, // opencl_local @@ -8735,9 +8737,9 @@ static TargetInfo *AllocateTarget(const } case llvm::Triple::nvptx: - return new NVPTX32TargetInfo(Triple, Opts); + return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/32); case llvm::Triple::nvptx64: - return new NVPTX64TargetInfo(Triple, Opts); + return new NVPTXTargetInfo(Triple, Opts, /*TargetPointerWidth=*/64); case llvm::Triple::amdgcn: case llvm::Triple::r600: Modified: cfe/trunk/test/Preprocessor/cuda-types.cu URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Preprocessor/cuda-types.cu?rev=291135&r1=291134&r2=291135&view=diff ============================================================================== --- cfe/trunk/test/Preprocessor/cuda-types.cu (original) +++ cfe/trunk/test/Preprocessor/cuda-types.cu Thu Jan 5 10:53:21 2017 @@ -28,3 +28,19 @@ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \ // RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/powerpc64-device-defines-filtered // RUN: diff %T/powerpc64-host-defines-filtered %T/powerpc64-device-defines-filtered + +// RUN: %clang --cuda-host-only -nocudainc -target i386-windows-msvc -x cuda -E -dM -o - /dev/null \ +// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \ +// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-msvc-host-defines-filtered +// RUN: %clang --cuda-device-only -nocudainc -nocudalib -target i386-windows-msvc -x cuda -E -dM -o - /dev/null \ +// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \ +// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-msvc-device-defines-filtered +// RUN: diff %T/i386-msvc-host-defines-filtered %T/i386-msvc-device-defines-filtered + +// RUN: %clang --cuda-host-only -nocudainc -target x86_64-windows-msvc -x cuda -E -dM -o - /dev/null \ +// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \ +// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-msvc-host-defines-filtered +// RUN: %clang --cuda-device-only -nocudainc -nocudalib -target x86_64-windows-msvc -x cuda -E -dM -o - /dev/null \ +// RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \ +// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-msvc-device-defines-filtered +// RUN: diff %T/x86_64-msvc-host-defines-filtered %T/x86_64-msvc-device-defines-filtered _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits