Эх сурвалжийг харах

[AMDGPU] Fix assertion due to initializer list

Sometimes a global var is replaced by a different llvm value. clang use GetAddrOfGlobalVar to get the original llvm global variable.
For most targets, GetAddrOfGlobalVar returns either the llvm global variable or a bitcast of the llvm global variable.
However, for AMDGPU target, GetAddrOfGlobalVar returns the addrspace cast or addrspace cast plus bitcast of the llvm global variable.
To get the llvm global variable, these casts need to be stripped, otherwise there is assertion.

This patch fixes that.

Differential Revision: https://reviews.llvm.org/D69129


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@375362 91177308-0d34-0410-b5e6-96231b3b80d8
Yaxun Liu 5 жил өмнө
parent
commit
c78da41cda

+ 6 - 10
lib/CodeGen/CodeGenModule.cpp

@@ -3546,7 +3546,8 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
               // Make a new global with the correct type, this is now guaranteed
               // Make a new global with the correct type, this is now guaranteed
               // to work.
               // to work.
               auto *NewGV = cast<llvm::GlobalVariable>(
               auto *NewGV = cast<llvm::GlobalVariable>(
-                  GetAddrOfGlobalVar(D, InitType, IsForDefinition));
+                  GetAddrOfGlobalVar(D, InitType, IsForDefinition)
+                      ->stripPointerCasts());
 
 
               // Erase the old global, since it is no longer used.
               // Erase the old global, since it is no longer used.
               GV->eraseFromParent();
               GV->eraseFromParent();
@@ -3928,14 +3929,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
   llvm::Constant *Entry =
   llvm::Constant *Entry =
       GetAddrOfGlobalVar(D, InitType, ForDefinition_t(!IsTentative));
       GetAddrOfGlobalVar(D, InitType, ForDefinition_t(!IsTentative));
 
 
-  // Strip off a bitcast if we got one back.
-  if (auto *CE = dyn_cast<llvm::ConstantExpr>(Entry)) {
-    assert(CE->getOpcode() == llvm::Instruction::BitCast ||
-           CE->getOpcode() == llvm::Instruction::AddrSpaceCast ||
-           // All zero index gep.
-           CE->getOpcode() == llvm::Instruction::GetElementPtr);
-    Entry = CE->getOperand(0);
-  }
+  // Strip off pointer casts if we got them.
+  Entry = Entry->stripPointerCasts();
 
 
   // Entry is now either a Function or GlobalVariable.
   // Entry is now either a Function or GlobalVariable.
   auto *GV = dyn_cast<llvm::GlobalVariable>(Entry);
   auto *GV = dyn_cast<llvm::GlobalVariable>(Entry);
@@ -3958,7 +3953,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
 
 
     // Make a new global with the correct type, this is now guaranteed to work.
     // Make a new global with the correct type, this is now guaranteed to work.
     GV = cast<llvm::GlobalVariable>(
     GV = cast<llvm::GlobalVariable>(
-        GetAddrOfGlobalVar(D, InitType, ForDefinition_t(!IsTentative)));
+        GetAddrOfGlobalVar(D, InitType, ForDefinition_t(!IsTentative))
+            ->stripPointerCasts());
 
 
     // Replace all uses of the old global with the new global
     // Replace all uses of the old global with the new global
     llvm::Constant *NewPtrForOldDecl =
     llvm::Constant *NewPtrForOldDecl =

+ 30 - 15
test/CodeGenCXX/cxx11-extern-constexpr.cpp

@@ -1,10 +1,13 @@
-// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX11
-// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CXX17
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=X86,CXX11X86
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefixes=X86,CXX17X86
+// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -o - -triple amdgcn-amd-amdhsa | FileCheck %s --check-prefixes=AMD,CXX11AMD
+// RUN: %clang_cc1 -std=c++1z %s -emit-llvm -o - -triple amdgcn-amd-amdhsa | FileCheck %s --check-prefixes=AMD,CXX17AMD
 
 
 struct A {
 struct A {
   static const int Foo = 123;
   static const int Foo = 123;
 };
 };
-// CHECK: @_ZN1A3FooE = constant i32 123, align 4
+// X86: @_ZN1A3FooE = constant i32 123, align 4
+// AMD: @_ZN1A3FooE = addrspace(4) constant i32 123, align 4
 const int *p = &A::Foo; // emit available_externally
 const int *p = &A::Foo; // emit available_externally
 const int A::Foo;       // convert to full definition
 const int A::Foo;       // convert to full definition
 
 
@@ -16,7 +19,8 @@ struct CreatePOD {
   // Deferred initialization of the structure here requires changing
   // Deferred initialization of the structure here requires changing
   // the type of the global variable: the initializer list does not include
   // the type of the global variable: the initializer list does not include
   // the tail padding.
   // the tail padding.
-  // CXX11: @_ZN9CreatePOD3podE = available_externally constant { i32, i8 } { i32 42, i8 43 },
+  // CXX11X86: @_ZN9CreatePOD3podE = available_externally constant { i32, i8 } { i32 42, i8 43 },
+  // CXX11AMD: @_ZN9CreatePOD3podE = available_externally addrspace(1) constant { i32, i8 } { i32 42, i8 43 },
   static constexpr PODWithInit pod{};
   static constexpr PODWithInit pod{};
 };
 };
 const int *p_pod = &CreatePOD::pod.g;
 const int *p_pod = &CreatePOD::pod.g;
@@ -30,29 +34,40 @@ struct MutableBar {
 };
 };
 
 
 struct Foo {
 struct Foo {
-  // CXX11: @_ZN3Foo21ConstexprStaticMemberE = available_externally constant i32 42,
-  // CXX17: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant i32 42,
+  // CXX11X86: @_ZN3Foo21ConstexprStaticMemberE = available_externally constant i32 42,
+  // CXX17X86: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr constant i32 42,
+  // CXX11AMD: @_ZN3Foo21ConstexprStaticMemberE = available_externally addrspace(4) constant i32 42,
+  // CXX17AMD: @_ZN3Foo21ConstexprStaticMemberE = linkonce_odr addrspace(4) constant i32 42,
   static constexpr int ConstexprStaticMember = 42;
   static constexpr int ConstexprStaticMember = 42;
-  // CHECK: @_ZN3Foo17ConstStaticMemberE = available_externally constant i32 43,
+  // X86: @_ZN3Foo17ConstStaticMemberE = available_externally constant i32 43,
+  // AMD: @_ZN3Foo17ConstStaticMemberE = available_externally addrspace(4) constant i32 43,
   static const int ConstStaticMember = 43;
   static const int ConstStaticMember = 43;
 
 
-  // CXX11: @_ZN3Foo23ConstStaticStructMemberE = available_externally constant %struct.Bar { i32 44 },
-  // CXX17: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr constant %struct.Bar { i32 44 },
+  // CXX11X86: @_ZN3Foo23ConstStaticStructMemberE = available_externally constant %struct.Bar { i32 44 },
+  // CXX17X86: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr constant %struct.Bar { i32 44 },
+  // CXX11AMD: @_ZN3Foo23ConstStaticStructMemberE = available_externally addrspace(1) constant %struct.Bar { i32 44 },
+  // CXX17AMD: @_ZN3Foo23ConstStaticStructMemberE = linkonce_odr addrspace(1) constant %struct.Bar { i32 44 },
   static constexpr Bar ConstStaticStructMember = {44};
   static constexpr Bar ConstStaticStructMember = {44};
 
 
-  // CXX11: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external global %struct.MutableBar,
-  // CXX17: @_ZN3Foo34ConstexprStaticMutableStructMemberE = linkonce_odr global %struct.MutableBar { i32 45 },
+  // CXX11X86: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external global %struct.MutableBar,
+  // CXX17X86: @_ZN3Foo34ConstexprStaticMutableStructMemberE = linkonce_odr global %struct.MutableBar { i32 45 },
+  // CXX11AMD: @_ZN3Foo34ConstexprStaticMutableStructMemberE = external addrspace(1) global %struct.MutableBar,
+  // CXX17AMD: @_ZN3Foo34ConstexprStaticMutableStructMemberE = linkonce_odr addrspace(1) global %struct.MutableBar { i32 45 },
   static constexpr MutableBar ConstexprStaticMutableStructMember = {45};
   static constexpr MutableBar ConstexprStaticMutableStructMember = {45};
 };
 };
-// CHECK: @_ZL15ConstStaticexpr = internal constant i32 46,
+// X86: @_ZL15ConstStaticexpr = internal constant i32 46,
+// AMD: @_ZL15ConstStaticexpr = internal addrspace(4) constant i32 46,
 static constexpr int ConstStaticexpr = 46;
 static constexpr int ConstStaticexpr = 46;
-// CHECK: @_ZL9ConstExpr = internal constant i32 46, align 4
+// X86: @_ZL9ConstExpr = internal constant i32 46, align 4
+// AMD: @_ZL9ConstExpr = internal addrspace(4) constant i32 46, align 4
 static const int ConstExpr = 46;
 static const int ConstExpr = 46;
 
 
-// CHECK: @_ZL21ConstexprStaticStruct = internal constant %struct.Bar { i32 47 },
+// X86: @_ZL21ConstexprStaticStruct = internal constant %struct.Bar { i32 47 },
+// AMD: @_ZL21ConstexprStaticStruct = internal addrspace(1) constant %struct.Bar { i32 47 },
 static constexpr Bar ConstexprStaticStruct = {47};
 static constexpr Bar ConstexprStaticStruct = {47};
 
 
-// CHECK: @_ZL28ConstexprStaticMutableStruct = internal global %struct.MutableBar { i32 48 },
+// X86: @_ZL28ConstexprStaticMutableStruct = internal global %struct.MutableBar { i32 48 },
+// AMD: @_ZL28ConstexprStaticMutableStruct = internal addrspace(1) global %struct.MutableBar { i32 48 },
 static constexpr MutableBar ConstexprStaticMutableStruct = {48};
 static constexpr MutableBar ConstexprStaticMutableStruct = {48};
 
 
 void use(const int &);
 void use(const int &);