Index: include/clang/Driver/Action.h =================================================================== --- include/clang/Driver/Action.h +++ include/clang/Driver/Action.h @@ -146,6 +146,10 @@ CudaDeviceAction(Action *Input, const char *ArchName, bool AtTopLevel); const char *getGpuArchName() const { return GpuArchName; } + + /// Gets the compute_XX that corresponds to getGpuArchName(). + const char *getComputeArchName() const; + bool isAtTopLevel() const { return AtTopLevel; } static bool IsValidGpuArchName(llvm::StringRef ArchName); Index: lib/Driver/Action.cpp =================================================================== --- lib/Driver/Action.cpp +++ lib/Driver/Action.cpp @@ -50,6 +50,21 @@ BindArchAction::BindArchAction(Action *Input, const char *_ArchName) : Action(BindArchClass, Input), ArchName(_ArchName) {} +// Converts CUDA GPU architecture, e.g. "sm_21", to its corresponding virtual +// compute arch, e.g. "compute_20". Returns null if the input arch is null or +// doesn't match an existing arch. +static const char* GpuArchToComputeName(const char *ArchName) { + if (!ArchName) + return nullptr; + llvm::StringRef A(ArchName); + if (A == "sm_20" || A == "sm_21") return "compute_20"; + if (A == "sm_30" || A == "sm_32") return "compute_30"; + if (A == "sm_35") return "compute_35"; + if (A == "sm_50") return "compute_50"; + if (A == "sm_52") return "compute_52"; + return nullptr; +} + void CudaDeviceAction::anchor() {} CudaDeviceAction::CudaDeviceAction(Action *Input, const char *ArchName, @@ -59,9 +74,12 @@ assert(IsValidGpuArchName(GpuArchName)); } +const char *CudaDeviceAction::getComputeArchName() const { + return GpuArchToComputeName(GpuArchName); +} + bool CudaDeviceAction::IsValidGpuArchName(llvm::StringRef ArchName) { - static llvm::Regex RE("^sm_[0-9]+$"); - return RE.match(ArchName); + return GpuArchToComputeName(ArchName.data()) != nullptr; } void CudaHostAction::anchor() {} Index: test/Driver/cuda-bad-arch.cu =================================================================== --- test/Driver/cuda-bad-arch.cu +++ test/Driver/cuda-bad-arch.cu @@ -5,28 +5,16 @@ // RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=compute_20 -c %s 2>&1 \ // RUN: | FileCheck -check-prefix BAD %s -// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=foo_20 -c %s 2>&1 \ -// RUN: | FileCheck -check-prefix BAD %s // RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm20 -c %s 2>&1 \ // RUN: | FileCheck -check-prefix BAD %s -// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_abc -c %s 2>&1 \ -// RUN: | FileCheck -check-prefix BAD %s -// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_20a -c %s 2>&1 \ -// RUN: | FileCheck -check-prefix BAD %s -// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_a20 -c %s 2>&1 \ -// RUN: | FileCheck -check-prefix BAD %s -// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=ssm_20 -c %s 2>&1 \ -// RUN: | FileCheck -check-prefix BAD %s -// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_ -c %s 2>&1 \ +// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_19 -c %s 2>&1 \ // RUN: | FileCheck -check-prefix BAD %s // BAD: error: Unsupported CUDA gpu architecture -// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_2 -c %s 2>&1 \ -// RUN: | FileCheck -check-prefix OK %s // 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_999 -c %s 2>&1 \ +// RUN: %clang -### -target x86_64-linux-gnu --cuda-gpu-arch=sm_52 -c %s 2>&1 \ // RUN: | FileCheck -check-prefix OK %s // RUN: %clang -### -target x86_64-linux-gnu -c %s 2>&1 \ // RUN: | FileCheck -check-prefix OK %s