diff --git a/clang/lib/Driver/ToolChains/AMDGPU.cpp b/clang/lib/Driver/ToolChains/AMDGPU.cpp index 2c85d21ebd738..128fc2bdea054 100644 --- a/clang/lib/Driver/ToolChains/AMDGPU.cpp +++ b/clang/lib/Driver/ToolChains/AMDGPU.cpp @@ -551,6 +551,17 @@ void RocmInstallationDetector::AddHIPIncludeArgs(const ArgList &DriverArgs, CC1Args.push_back(DriverArgs.MakeArgString(P)); } + { + // This header implements diagnostics for problematic uses of + // device-specific macros. Since these diagnostics should be issued even + // when GPU headers are not included, this header is included separately. + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "include"); + CC1Args.push_back("-internal-isystem"); + CC1Args.push_back(DriverArgs.MakeArgString(P)); + CC1Args.append({"-include", "__clang_hip_device_macro_guards.h"}); + } + const auto HandleHipStdPar = [=, &DriverArgs, &CC1Args]() { StringRef Inc = getIncludePath(); auto &FS = D.getVFS(); diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index ff392e7122a44..582c8bd6c8a2d 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -79,6 +79,7 @@ set(hip_files __clang_hip_math.h __clang_hip_stdlib.h __clang_hip_runtime_wrapper.h + __clang_hip_device_macro_guards.h ) set(hlsl_h diff --git a/clang/lib/Headers/__clang_hip_device_macro_guards.h b/clang/lib/Headers/__clang_hip_device_macro_guards.h new file mode 100644 index 0000000000000..42782c9bb08a7 --- /dev/null +++ b/clang/lib/Headers/__clang_hip_device_macro_guards.h @@ -0,0 +1,55 @@ +/*===---- __clang_hip_device_macro_guards.h - guards for HIP device macros -=== + * + * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. + * See https://llvm.org/LICENSE.txt for license information. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + * + *===-----------------------------------------------------------------------=== + */ + +/* + * WARNING: This header is intended to be directly -include'd by + * the compiler and is not supposed to be included by users. + * + */ + +#ifndef __CLANG_HIP_DEVICE_MACRO_GUARDS_H__ +#define __CLANG_HIP_DEVICE_MACRO_GUARDS_H__ + +#if __HIP__ +#if !defined(__HIP_DEVICE_COMPILE__) +// The __AMDGCN_WAVEFRONT_SIZE macros cannot hold meaningful values during host +// compilation as devices are not initialized when the macros are defined and +// there may indeed be devices with differing wavefront sizes in the same +// system. This code issues diagnostics when the macros are used in host code. + +#undef __AMDGCN_WAVEFRONT_SIZE +#undef __AMDGCN_WAVEFRONT_SIZE__ + +// Reference __hip_device_macro_guard in a way that is legal in preprocessor +// directives and does not affect the value so that appropriate diagnostics are +// issued. Function calls, casts, or the comma operator would make the macro +// illegal for use in preprocessor directives. +#define __AMDGCN_WAVEFRONT_SIZE (!__hip_device_macro_guard ? 64 : 64) +#define __AMDGCN_WAVEFRONT_SIZE__ (!__hip_device_macro_guard ? 64 : 64) + +// This function is referenced by the macro in device functions during host +// compilation, it SHOULD NOT cause a diagnostic. +__attribute__((device)) static constexpr int __hip_device_macro_guard(void) { + return -1; +} + +// This function is referenced by the macro in host functions during host +// compilation, it SHOULD cause a diagnostic. +__attribute__(( + host, deprecated("The __AMDGCN_WAVEFRONT_SIZE macros do not correspond " + "to the device(s) when used in host code and may only " + "be used in device code."))) static constexpr int +__hip_device_macro_guard(void) { + return -1; +} +// TODO Change "deprecated" to "unavailable" to cause hard errors instead of +// warnings. +#endif +#endif // __HIP__ +#endif // __CLANG_HIP_DEVICE_MACRO_GUARDS_H__ diff --git a/clang/test/Driver/hip-wavefront-size-host-diagnostics.hip b/clang/test/Driver/hip-wavefront-size-host-diagnostics.hip new file mode 100644 index 0000000000000..e0ee44cdc2986 --- /dev/null +++ b/clang/test/Driver/hip-wavefront-size-host-diagnostics.hip @@ -0,0 +1,52 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang -xhip --offload-arch=gfx1030 --offload-host-only -pedantic -nogpuinc -nogpulib -nobuiltininc -nostdinc -fsyntax-only -Xclang -verify=onhost %s +// RUN: %clang -xhip --offload-arch=gfx1030 --offload-device-only -pedantic -nogpuinc -nogpulib -nobuiltininc -nostdinc -fsyntax-only -Xclang -verify=ondevice %s + +// ondevice-no-diagnostics + +#define WRAPPED __AMDGCN_WAVEFRONT_SIZE__ + +__attribute__((host, device)) void use(int, const char*); + +template __attribute__((host, device)) int templatify(int x) { + return x + N; +} + +// no warning expected +#if defined(__HIP_DEVICE_COMPILE__) && (__AMDGCN_WAVEFRONT_SIZE__ == 64) && (__AMDGCN_WAVEFRONT_SIZE == 64) +int foo(void); +#endif + +// no warning expected +__attribute__((device)) int device_var = __AMDGCN_WAVEFRONT_SIZE__; + +__attribute__((device)) +void device_fun() { + // no warnings expected + use(__AMDGCN_WAVEFRONT_SIZE, "device function"); + use(__AMDGCN_WAVEFRONT_SIZE__, "device function"); + use(WRAPPED, "device function"); + use(templatify<__AMDGCN_WAVEFRONT_SIZE__>(42), "device function"); +} + +// warning expected +int host_var = __AMDGCN_WAVEFRONT_SIZE__; // onhost-warning {{'__hip_device_macro_guard' is deprecated: The __AMDGCN_WAVEFRONT_SIZE macros do not correspond to the device(s) when used in host code and may only be used in device code.}} + +__attribute__((host)) +void host_fun() { + // warnings expected + use(__AMDGCN_WAVEFRONT_SIZE, "host function"); // onhost-warning {{'__hip_device_macro_guard' is deprecated: The __AMDGCN_WAVEFRONT_SIZE macros do not correspond to the device(s) when used in host code and may only be used in device code.}} + use(__AMDGCN_WAVEFRONT_SIZE__, "host function"); // onhost-warning {{'__hip_device_macro_guard' is deprecated: The __AMDGCN_WAVEFRONT_SIZE macros do not correspond to the device(s) when used in host code and may only be used in device code.}} + use(WRAPPED, "host function"); // onhost-warning {{'__hip_device_macro_guard' is deprecated: The __AMDGCN_WAVEFRONT_SIZE macros do not correspond to the device(s) when used in host code and may only be used in device code.}} + use(templatify<__AMDGCN_WAVEFRONT_SIZE__>(42), "host function"); // onhost-warning {{'__hip_device_macro_guard' is deprecated: The __AMDGCN_WAVEFRONT_SIZE macros do not correspond to the device(s) when used in host code and may only be used in device code.}} +} + +__attribute((host, device)) +void host_device_fun() { + // warnings expected + use(__AMDGCN_WAVEFRONT_SIZE__, "host device function"); // onhost-warning {{'__hip_device_macro_guard' is deprecated: The __AMDGCN_WAVEFRONT_SIZE macros do not correspond to the device(s) when used in host code and may only be used in device code.}} + use(WRAPPED, "host device function"); // onhost-warning {{'__hip_device_macro_guard' is deprecated: The __AMDGCN_WAVEFRONT_SIZE macros do not correspond to the device(s) when used in host code and may only be used in device code.}} + use(templatify<__AMDGCN_WAVEFRONT_SIZE__>(42), "host device function"); // onhost-warning {{'__hip_device_macro_guard' is deprecated: The __AMDGCN_WAVEFRONT_SIZE macros do not correspond to the device(s) when used in host code and may only be used in device code.}} +} + +// onhost-note@__clang_hip_device_macro_guards.h:45 0+ {{'__hip_device_macro_guard' has been explicitly marked deprecated here}} diff --git a/clang/test/Preprocessor/predefined-arch-macros.c b/clang/test/Preprocessor/predefined-arch-macros.c index 35801e758cc58..a574f5f8b6a18 100644 --- a/clang/test/Preprocessor/predefined-arch-macros.c +++ b/clang/test/Preprocessor/predefined-arch-macros.c @@ -4399,7 +4399,6 @@ // RUN: %clang -x hip -E -dM %s -o - 2>&1 --offload-host-only -nogpulib \ // RUN: -nogpuinc --offload-arch=gfx803 -target x86_64-unknown-linux \ // RUN: | FileCheck -match-full-lines %s -check-prefixes=CHECK_HIP_HOST -// CHECK_HIP_HOST: #define __AMDGCN_WAVEFRONT_SIZE__ 64 // CHECK_HIP_HOST: #define __AMDGPU__ 1 // CHECK_HIP_HOST: #define __AMD__ 1