Index: clang/include/clang/Basic/Cuda.h =================================================================== --- clang/include/clang/Basic/Cuda.h +++ clang/include/clang/Basic/Cuda.h @@ -75,6 +75,9 @@ /// Get the earliest CudaVersion that supports the given CudaArch. CudaVersion MinVersionForCudaArch(CudaArch A); +/// Get the lowest CudaArch supported by this CudaVersion. +CudaArch MinArchForCudaVersion(CudaVersion V); + } // namespace clang #endif Index: clang/include/clang/Basic/DiagnosticDriverKinds.td =================================================================== --- clang/include/clang/Basic/DiagnosticDriverKinds.td +++ clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -33,6 +33,11 @@ "GPU arch %1 requires CUDA version at least %3, but installation at %0 is %2. " "Use --cuda-path to specify a different CUDA install, or pass " "--no-cuda-version-check.">; +def err_drv_cuda_arch_too_low : Error< + "CUDA version %2 does not support compiling for GPU archs earlier than %3, " + "so cannot compile for %1. Use --cuda-gpu-arch to specify a different GPU " + "arch, use --cuda-path to specify a different CUDA install, or pass " + "--no-cuda-version-check.">; def err_drv_cuda_nvptx_host : Error<"unsupported use of NVPTX for host compilation.">; def err_drv_invalid_thread_model_for_target : Error< "invalid thread model '%0' in '%1' for this target">; Index: clang/lib/Basic/Cuda.cpp =================================================================== --- clang/lib/Basic/Cuda.cpp +++ clang/lib/Basic/Cuda.cpp @@ -180,4 +180,17 @@ llvm_unreachable("invalid enum"); } +CudaArch MinArchForCudaVersion(CudaVersion V) { + switch (V) { + case CudaVersion::UNKNOWN: + case CudaVersion::CUDA_70: + case CudaVersion::CUDA_75: + case CudaVersion::CUDA_80: + return CudaArch::SM_20; + case CudaVersion::CUDA_90: + return CudaArch::SM_30; + } + llvm_unreachable("invalid enum"); +} + } // namespace clang Index: clang/lib/Driver/ToolChains/Cuda.h =================================================================== --- clang/lib/Driver/ToolChains/Cuda.h +++ clang/lib/Driver/ToolChains/Cuda.h @@ -40,7 +40,7 @@ // CUDA architectures for which we have raised an error in // CheckCudaVersionSupportsArch. - mutable llvm::SmallSet ArchsWithVersionTooLowErrors; + mutable llvm::SmallSet ArchsWithBadVersion; public: CudaInstallationDetector(const Driver &D, const llvm::Triple &HostTriple, Index: clang/lib/Driver/ToolChains/Cuda.cpp =================================================================== --- clang/lib/Driver/ToolChains/Cuda.cpp +++ clang/lib/Driver/ToolChains/Cuda.cpp @@ -205,15 +205,25 @@ void CudaInstallationDetector::CheckCudaVersionSupportsArch( CudaArch Arch) const { if (Arch == CudaArch::UNKNOWN || Version == CudaVersion::UNKNOWN || - ArchsWithVersionTooLowErrors.count(Arch) > 0) + ArchsWithBadVersion.count(Arch) > 0) return; auto RequiredVersion = MinVersionForCudaArch(Arch); if (Version < RequiredVersion) { - ArchsWithVersionTooLowErrors.insert(Arch); + ArchsWithBadVersion.insert(Arch); D.Diag(diag::err_drv_cuda_version_too_low) << InstallPath << CudaArchToString(Arch) << CudaVersionToString(Version) << CudaVersionToString(RequiredVersion); + return; + } + + auto MinSupportedArch = MinArchForCudaVersion(Version); + if (Arch < MinSupportedArch) { + ArchsWithBadVersion.insert(Arch); + D.Diag(diag::err_drv_cuda_arch_too_low) + << InstallPath << CudaArchToString(Arch) << CudaVersionToString(Version) + << CudaArchToString(MinSupportedArch); + return; } } Index: clang/test/Driver/Inputs/CUDA_90/usr/local/cuda/version.txt =================================================================== --- /dev/null +++ clang/test/Driver/Inputs/CUDA_90/usr/local/cuda/version.txt @@ -0,0 +1 @@ +CUDA Version 9.0.103 Index: clang/test/Driver/cuda-bad-arch.cu =================================================================== --- clang/test/Driver/cuda-bad-arch.cu +++ clang/test/Driver/cuda-bad-arch.cu @@ -12,6 +12,12 @@ // BAD: error: Unsupported CUDA gpu architecture +// RUN: %clang -### -v --target=x86_64-linux-gnu --cuda-gpu-arch=sm_21 \ +// RUN: --cuda-path=%S/Inputs/CUDA_90/usr/local/cuda %s 2>&1 \ +// RUN: | FileCheck -check-prefix BAD_CUDA9 %s + +// BAD_CUDA9: does not support compiling for GPU archs earlier than sm_30 + // RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_20 -c %s 2>&1 \ // RUN: | FileCheck -check-prefix OK %s // RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_52 -c %s 2>&1 \