Files
llvm-project/clang/test/CodeGenCUDA/constexpr-variables.cu
Joseph Huber 9f2351c27e [HIP] Do not apply 'externally_initialized' to constant device variables (#182157)
Summary:
From the Language reference:
> By default, global initializers are optimized by assuming that global
variables defined within the module are not modified from their initial
values before the start of the global initializer. This is true even for
variables potentially accessible from outside the module, including
those with external linkage or appearing in @llvm.used or dllexported
variables. This assumption may be suppressed by marking the variable
with externally_initialized.

This is intended because device programs can be modified beyond the
normal lifetime expected by the optimization pipeline. However, for
constant variables we should be able to safely assume that these are
truly constant within the module. In the vast majority of cases these
will not get externally visible symbols, but even `extern const` uses we
should assert that the user should not be writing them if they are
marked const.
2026-02-24 09:11:31 -06:00

44 lines
1.4 KiB
Plaintext

// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -o - -triple nvptx \
// RUN: -fcuda-is-device | FileCheck --check-prefixes=CXX14 %s
// RUN: %clang_cc1 -std=c++17 %s -emit-llvm -o - -triple nvptx \
// RUN: -fcuda-is-device | FileCheck --check-prefixes=CXX17 %s
#include "Inputs/cuda.h"
// COM: @_ZL1a = internal {{.*}}constant i32 7
constexpr int a = 7;
__constant__ const int &use_a = a;
namespace B {
// COM: @_ZN1BL1bE = internal {{.*}}constant i32 9
constexpr int b = 9;
}
__constant__ const int &use_B_b = B::b;
struct Q {
// CXX14: @_ZN1Q2k2E = {{.*}}constant i32 6
// CXX17: @_ZN1Q2k2E = internal {{.*}}constant i32 6
// CXX14: @_ZN1Q2k1E = available_externally {{.*}}constant i32 5
// CXX17: @_ZN1Q2k1E = {{.*}} constant i32 5
static constexpr int k1 = 5;
static constexpr int k2 = 6;
};
constexpr int Q::k2;
__constant__ const int &use_Q_k1 = Q::k1;
__constant__ const int &use_Q_k2 = Q::k2;
template<typename T> struct X {
// CXX14: @_ZN1XIiE1aE = available_externally {{.*}}constant i32 123
// CXX17: @_ZN1XIiE1aE = {{.*}}constant i32 123
static constexpr int a = 123;
};
__constant__ const int &use_X_a = X<int>::a;
template <typename T, T a, T b> struct A {
// CXX14: @_ZN1AIiLi1ELi2EE1xE = available_externally {{.*}}constant i32 2
// CXX17: @_ZN1AIiLi1ELi2EE1xE = {{.*}}constant i32 2
constexpr static T x = a * b;
};
__constant__ const int &y = A<int, 1, 2>::x;