Skip to content

Commit

Permalink
[GlobalOpt] Check stored once value's type before setting global init…
Browse files Browse the repository at this point in the history
…ializer

In the provided test case, we were trying to set the global's
initializer to `i32* null` when the global's value type was `@0`.

Reviewed By: rnk

Differential Revision: https://reviews.llvm.org/D108232
  • Loading branch information
aeubanks committed Aug 17, 2021
1 parent af78180 commit 16890e0
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
3 changes: 2 additions & 1 deletion llvm/lib/Transforms/IPO/GlobalOpt.cpp
Expand Up @@ -1610,7 +1610,8 @@ processInternalGlobal(GlobalVariable *GV, const GlobalStatus &GS,
// initializer to be the stored value, then delete all stores to the
// global. This allows us to mark it constant.
if (Constant *SOVConstant = dyn_cast<Constant>(GS.StoredOnceValue))
if (isa<UndefValue>(GV->getInitializer())) {
if (SOVConstant->getType() == GV->getValueType() &&
isa<UndefValue>(GV->getInitializer())) {
// Change the initial value here.
GV->setInitializer(SOVConstant);

Expand Down
22 changes: 22 additions & 0 deletions llvm/test/Transforms/GlobalOpt/stored-once-value-type.ll
@@ -0,0 +1,22 @@
; RUN: opt -passes=globalopt < %s -S | FileCheck %s

; Check that we don't try to set a global initializer to a value of a different type.
; In this case, we were trying to set @0's initializer to be i32* null.

%0 = type { i32* }

@0 = internal global %0* null
; CHECK: global %0 undef

define void @a() {
%1 = tail call i8* @_Znwm(i64 8)
%2 = bitcast i8* %1 to %0*
%3 = getelementptr inbounds %0, %0* %2, i64 0, i32 0
store i32* null, i32** %3, align 8
store i8* %1, i8** bitcast (%0** @0 to i8**), align 8
%4 = load i64*, i64** bitcast (%0** @0 to i64**), align 8
%5 = load atomic i64, i64* %4 acquire, align 8
ret void
}

declare i8* @_Znwm(i64)

0 comments on commit 16890e0

Please sign in to comment.