This is an archive of the discontinued LLVM Phabricator instance.

[clang][CUDA][Windows] Fix compilation error on Windows with `uint32_t __nvvm_get_smem_pointer`
ClosedPublic

Authored by emankov on Apr 1 2022, 5:45 AM.

Details

Summary

The change fixes https://github.com/llvm/llvm-project/issues/54609 (the second reported issue) by eliminating a compilation error occurring only on Windows while trying to compile any CUDA source file by clang (-x cuda).

[Repro]
clang -x cuda <any_cu_source>

[Error]

__clang_cuda_runtime_wrapper.h:473:
__clang_cuda_intrinsics.h(517,19): error GC871EEFB: unknown type name 'uint32_t'; did you mean 'cuuint32_t'?
__device__ inline uint32_t __nvvm_get_smem_pointer(void *__ptr) {
                          ^
C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v11.6/include\cuda.h:57:26: note: 'cuuint32_t' declared here
typedef unsigned __int32 cuuint32_t;

Diff Detail

Event Timeline

emankov created this revision.Apr 1 2022, 5:45 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 1 2022, 5:45 AM
emankov requested review of this revision.Apr 1 2022, 5:45 AM
tra added inline comments.Apr 1 2022, 11:03 AM
clang/lib/Headers/__clang_cuda_intrinsics.h
489

We should include stdint.h unconditionally, and move inclusion to the top of the file.
Special-casing windows does not buy us anything here.

490

Include should be done outside of extern "C"

What about using cuuint32_t instead of uint32_t in __device__ inline uint32_t __nvvm_get_smem_pointer(void *__ptr)? Actually, I like it more. Let's CUDA do all the needed typedefs.

tra added a comment.EditedApr 1 2022, 3:57 PM

What about using cuuint32_t instead of uint32_t in __device__ inline uint32_t __nvvm_get_smem_pointer(void *__ptr)? Actually, I like it more. Let's CUDA do all the needed typedefs.

That should work. cuuint32_t is defined in cuda.h which we always include during CUDA compilation.

I wonder why NVIDIA decided not to include stdint.h on windows:

#ifdef _MSC_VER
typedef unsigned __int32 cuuint32_t;
typedef unsigned __int64 cuuint64_t;
#else
#include <stdint.h>
typedef uint32_t cuuint32_t;
typedef uint64_t cuuint64_t;
#endif

I wonder why NVIDIA decided not to include stdint.h on windows:

#ifdef _MSC_VER
typedef unsigned __int32 cuuint32_t;
typedef unsigned __int64 cuuint64_t;
#else
#include <stdint.h>
typedef uint32_t cuuint32_t;
typedef uint64_t cuuint64_t;
#endif

Because CUDA uses Microsoft specific types unsigned __int32 and unsigned __int64 instead, and it looks that they are all what is needed, so there is no need in including <stdint.h> on Win path.
That is why I prefer using cuuint32_t instead of uint32_t, as it is the type proposed to be used in CUDA-related stuff.

emankov updated this revision to Diff 423236.Apr 16 2022, 7:18 AM
emankov edited the summary of this revision. (Show Details)

Use cuuint32_t instead of uint32_t, as it is the type proposed to be used in CUDA-related stuff. The decision is based on cuda.h header file that is always included when compiling CUDA by clang -x cuda.

cuda.h:

#ifdef _MSC_VER
typedef unsigned __int32 cuuint32_t;
typedef unsigned __int64 cuuint64_t;
#else
#include <stdint.h>
typedef uint32_t cuuint32_t;
typedef uint64_t cuuint64_t;
#endif
``
tra accepted this revision.Apr 18 2022, 11:21 AM
This revision is now accepted and ready to land.Apr 18 2022, 11:21 AM
This revision was landed with ongoing or failed builds.Apr 20 2022, 3:41 PM
This revision was automatically updated to reflect the committed changes.