[Internalize] Preserve variables externally initialized.

- ``externally_initialized`` variables would be initialized or modified
  elsewhere. Particularly, CUDA or HIP may have host code to initialize
  or modify ``externally_initialized`` device variables, which may not
  be explicitly referenced on the device side but may still be used
  through the host side interfaces. Not preserving them triggers the
  elimination of them in the GlobalDCE and breaks the user code.

Reviewed By: yaxunl

Differential Revision: https://reviews.llvm.org/D105135
This commit is contained in:
Michael Liao 2021-06-29 11:03:52 -04:00
parent 3e6d2cbf26
commit 4e5d9c8803
4 changed files with 21 additions and 8 deletions

View File

@ -15,14 +15,14 @@
#include "Inputs/cuda.h"
// Check device variables used by neither host nor device functioins are not kept.
// DEV-NEG-NOT: @v1
// DEV-DAG: @v1
__device__ int v1;
// DEV-NEG-NOT: @v2
// DEV-DAG: @v2
__constant__ int v2;
// Check device variables used by neither host nor device functioins are not kept.
// DEV-NEG-NOT: @_ZL2v3
static __device__ int v3;

View File

@ -15,14 +15,14 @@
// DCE before internalization. This test makes sure unused global variables
// are eliminated.
// Check unused device/constant variables are eliminated.
// NEGCHK-NOT: @v1
// CHECK-DAG: @v1
__device__ int v1;
// NEGCHK-NOT: @v2
// CHECK-DAG: @v2
__constant__ int v2;
// Check unused device/constant variables are eliminated.
// NEGCHK-NOT: @_ZL2v3
constexpr int v3 = 1;

View File

@ -101,6 +101,12 @@ bool InternalizePass::shouldPreserveGV(const GlobalValue &GV) {
if (GV.hasDLLExportStorageClass())
return true;
// As the name suggests, externally initialized variables need preserving as
// they would be initialized elsewhere externally.
if (const auto *G = dyn_cast<GlobalVariable>(&GV))
if (G->isExternallyInitialized())
return true;
// Already local, has nothing to do.
if (GV.hasLocalLinkage())
return false;

View File

@ -0,0 +1,7 @@
; RUN: opt < %s -internalize -S | FileCheck %s
; RUN: opt < %s -passes=internalize -S | FileCheck %s
; CHECK: @G0
; CHECK-NOT: internal
; CHECK-SAME: global i32
@G0 = protected externally_initialized global i32 0, align 4