diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -393,8 +393,24 @@ if (isa(Ty)) return false; + auto IsStored = [GV](Value *V) { + auto *SI = dyn_cast(V); + if (!SI) + return false; + + auto *GlobalVar = dyn_cast(GV); + Constant *StoredConst = dyn_cast(SI->getOperand(0)); + if (!GlobalVar || !StoredConst) + return true; + + // Don't consider stores that only write the initializer value. + return StoredConst != GlobalVar->getInitializer() && + !(StoredConst->isNullValue() && + GlobalVar->getInitializer()->isNullValue()); + }; + It->second.IsLoaded |= isa(V); - It->second.IsStored |= isa(V); + It->second.IsStored |= IsStored(V); continue; } diff --git a/llvm/test/Transforms/GlobalOpt/sra-many-stores.ll b/llvm/test/Transforms/GlobalOpt/sra-many-stores.ll --- a/llvm/test/Transforms/GlobalOpt/sra-many-stores.ll +++ b/llvm/test/Transforms/GlobalOpt/sra-many-stores.ll @@ -8,6 +8,7 @@ ;. ; CHECK: @[[A:[a-zA-Z0-9_$"\\.-]+]] = global i8 0, align 4 +; CHECK: @[[C:[a-zA-Z0-9_$"\\.-]+]] = global ptr null ;. define internal void @read_struct() { ; CHECK-LABEL: @read_struct( @@ -189,57 +190,23 @@ define void @store_initializer() { ; CHECK-LABEL: @store_initializer( ; CHECK-NEXT: entry: -; CHECK-NEXT: store ptr null, ptr @global.20ptr, align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR:%.*]], ptr @global.20ptr, i64 0, i32 1), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 2), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 3), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 4), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 5), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 6), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 7), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 8), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 9), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 10), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 11), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 12), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 13), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 14), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 15), align 8 -; CHECK-NEXT: store ptr null, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 16), align 8 -; CHECK-NEXT: [[L0:%.*]] = load ptr, ptr @global.20ptr, align 8 -; CHECK-NEXT: store volatile ptr [[L0]], ptr @c, align 8 -; CHECK-NEXT: [[L1:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 1), align 8 -; CHECK-NEXT: store volatile ptr [[L1]], ptr @c, align 8 -; CHECK-NEXT: [[L2:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 2), align 8 -; CHECK-NEXT: store volatile ptr [[L2]], ptr @c, align 8 -; CHECK-NEXT: [[L3:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 3), align 8 -; CHECK-NEXT: store volatile ptr [[L3]], ptr @c, align 8 -; CHECK-NEXT: [[L4:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 4), align 8 -; CHECK-NEXT: store volatile ptr [[L4]], ptr @c, align 8 -; CHECK-NEXT: [[L5:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 5), align 8 -; CHECK-NEXT: store volatile ptr [[L5]], ptr @c, align 8 -; CHECK-NEXT: [[L6:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 6), align 8 -; CHECK-NEXT: store volatile ptr [[L6]], ptr @c, align 8 -; CHECK-NEXT: [[L7:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 7), align 8 -; CHECK-NEXT: store volatile ptr [[L7]], ptr @c, align 8 -; CHECK-NEXT: [[L8:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 8), align 8 -; CHECK-NEXT: store volatile ptr [[L8]], ptr @c, align 8 -; CHECK-NEXT: [[L9:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 9), align 8 -; CHECK-NEXT: store volatile ptr [[L9]], ptr @c, align 8 -; CHECK-NEXT: [[L10:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 10), align 8 -; CHECK-NEXT: store volatile ptr [[L10]], ptr @c, align 8 -; CHECK-NEXT: [[L11:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 11), align 8 -; CHECK-NEXT: store volatile ptr [[L11]], ptr @c, align 8 -; CHECK-NEXT: [[L12:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 12), align 8 -; CHECK-NEXT: store volatile ptr [[L12]], ptr @c, align 8 -; CHECK-NEXT: [[L13:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 13), align 8 -; CHECK-NEXT: store volatile ptr [[L13]], ptr @c, align 8 -; CHECK-NEXT: [[L14:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 14), align 8 -; CHECK-NEXT: store volatile ptr [[L14]], ptr @c, align 8 -; CHECK-NEXT: [[L15:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 15), align 8 -; CHECK-NEXT: store volatile ptr [[L15]], ptr @c, align 8 -; CHECK-NEXT: [[L16:%.*]] = load ptr, ptr getelementptr inbounds ([[STRUCT_20PTR]], ptr @global.20ptr, i64 0, i32 16), align 8 -; CHECK-NEXT: store volatile ptr [[L16]], ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 +; CHECK-NEXT: store volatile ptr null, ptr @c, align 8 ; CHECK-NEXT: ret void ; entry: