forked from llvm/llvm-project
-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SWDEV-233718 update to final change in trunk
[CUDA][HIP] Fix constexpr variables for C++17 constexpr variables are compile time constants and implicitly const, therefore they are safe to emit on both device and host side. Besides, in many cases they are intended for both device and host, therefore it makes sense to emit them on both device and host sides if necessary. In most cases constexpr variables are used as rvalue and the variables themselves do not need to be emitted. However if their address is taken, then they need to be emitted. For C++14, clang is able to handle that since clang emits them with available_externally linkage together with the initializer. However for C++17, the constexpr static data member of a class or template class become inline variables implicitly. Therefore they become definitions with linkonce_odr or weak_odr linkages. As such, they can not have available_externally linkage. This patch fixes that by adding implicit constant attribute to file scope constexpr variables and constexpr static data members in device compilation. Differential Revision: https://reviews.llvm.org/D79237 Change-Id: I7960fac9511daf4d966264c19fcedac25d84590a
- Loading branch information
Showing
7 changed files
with
121 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -o - -triple nvptx64-nvidia-cuda \ | ||
// RUN: -fcuda-is-device -verify -fsyntax-only | ||
// RUN: %clang_cc1 -std=c++17 %s -emit-llvm -o - -triple nvptx64-nvidia-cuda \ | ||
// RUN: -fcuda-is-device -verify -fsyntax-only | ||
// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -o - \ | ||
// RUN: -triple x86_64-unknown-linux-gnu -verify -fsyntax-only | ||
// RUN: %clang_cc1 -std=c++17 %s -emit-llvm -o - \ | ||
// RUN: -triple x86_64-unknown-linux-gnu -verify -fsyntax-only | ||
#include "Inputs/cuda.h" | ||
|
||
template<typename T> | ||
__host__ __device__ void foo(const T **a) { | ||
// expected-note@-1 {{declared here}} | ||
static const T b = sizeof(a); | ||
static constexpr T c = sizeof(a); | ||
const T d = sizeof(a); | ||
constexpr T e = sizeof(a); | ||
constexpr T f = **a; | ||
// expected-error@-1 {{constexpr variable 'f' must be initialized by a constant expression}} | ||
// expected-note@-2 {{read of non-constexpr variable 'a' is not allowed in a constant expression}} | ||
a[0] = &b; | ||
a[1] = &c; | ||
a[2] = &d; | ||
a[3] = &e; | ||
} | ||
|
||
__device__ void device_fun(const int **a) { | ||
// expected-note@-1 {{declared here}} | ||
constexpr int b = sizeof(a); | ||
static constexpr int c = sizeof(a); | ||
constexpr int d = **a; | ||
// expected-error@-1 {{constexpr variable 'd' must be initialized by a constant expression}} | ||
// expected-note@-2 {{read of non-constexpr variable 'a' is not allowed in a constant expression}} | ||
a[0] = &b; | ||
a[1] = &c; | ||
foo(a); | ||
// expected-note@-1 {{in instantiation of function template specialization 'foo<int>' requested here}} | ||
} | ||
|
||
void host_fun(const int **a) { | ||
// expected-note@-1 {{declared here}} | ||
constexpr int b = sizeof(a); | ||
static constexpr int c = sizeof(a); | ||
constexpr int d = **a; | ||
// expected-error@-1 {{constexpr variable 'd' must be initialized by a constant expression}} | ||
// expected-note@-2 {{read of non-constexpr variable 'a' is not allowed in a constant expression}} | ||
a[0] = &b; | ||
a[1] = &c; | ||
foo(a); | ||
} | ||
|
||
__host__ __device__ void host_device_fun(const int **a) { | ||
// expected-note@-1 {{declared here}} | ||
constexpr int b = sizeof(a); | ||
static constexpr int c = sizeof(a); | ||
constexpr int d = **a; | ||
// expected-error@-1 {{constexpr variable 'd' must be initialized by a constant expression}} | ||
// expected-note@-2 {{read of non-constexpr variable 'a' is not allowed in a constant expression}} | ||
a[0] = &b; | ||
a[1] = &c; | ||
foo(a); | ||
} | ||
|
||
template <class T> | ||
struct A { | ||
explicit A() = default; | ||
}; | ||
template <class T> | ||
constexpr A<T> a{}; | ||
|
||
struct B { | ||
static constexpr bool value = true; | ||
}; | ||
|
||
template<typename T> | ||
struct C { | ||
static constexpr bool value = T::value; | ||
}; | ||
|
||
__constant__ const bool &x = C<B>::value; |