[llvm] r250035 - GlobalOpt does not treat externally_initialized globals correctly
Oliver Stannard via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 12 06:20:52 PDT 2015
Author: olista01
Date: Mon Oct 12 08:20:52 2015
New Revision: 250035
URL: http://llvm.org/viewvc/llvm-project?rev=250035&view=rev
Log:
GlobalOpt does not treat externally_initialized globals correctly
GlobalOpt currently merges stores into the initialisers of internal,
externally_initialized globals, but should not do so as the value of the global
may change between the initialiser and any code in the module being run.
Added:
llvm/trunk/test/Transforms/GlobalOpt/externally-initialized.ll
Modified:
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
llvm/trunk/lib/Transforms/Utils/GlobalStatus.cpp
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=250035&r1=250034&r2=250035&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Mon Oct 12 08:20:52 2015
@@ -1804,7 +1804,7 @@ bool GlobalOpt::ProcessInternalGlobal(Gl
GVI = FirstNewGV; // Don't skip the newly produced globals!
return true;
}
- } else if (GS.StoredType == GlobalStatus::StoredOnce) {
+ } else if (GS.StoredType == GlobalStatus::StoredOnce && GS.StoredOnceValue) {
// If the initial value for the global was an undef value, and if only
// one other value was stored into it, we can just change the
// initializer to be the stored value, then delete all stores to the
Modified: llvm/trunk/lib/Transforms/Utils/GlobalStatus.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/GlobalStatus.cpp?rev=250035&r1=250034&r2=250035&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/GlobalStatus.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/GlobalStatus.cpp Mon Oct 12 08:20:52 2015
@@ -49,6 +49,10 @@ bool llvm::isSafeToDestroyConstant(const
static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS,
SmallPtrSetImpl<const PHINode *> &PhiUsers) {
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
+ if (GV->isExternallyInitialized())
+ GS.StoredType = GlobalStatus::StoredOnce;
+
for (const Use &U : V->uses()) {
const User *UR = U.getUser();
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(UR)) {
Added: llvm/trunk/test/Transforms/GlobalOpt/externally-initialized.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/externally-initialized.ll?rev=250035&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/externally-initialized.ll (added)
+++ llvm/trunk/test/Transforms/GlobalOpt/externally-initialized.ll Mon Oct 12 08:20:52 2015
@@ -0,0 +1,37 @@
+; RUN: opt < %s -S -globalopt | FileCheck %s
+
+; This global is externally_initialized, which may modify the value between
+; it's static initializer and any code in this module being run, so the only
+; write to it cannot be merged into the static initialiser.
+; CHECK: @a = internal unnamed_addr externally_initialized global i32 undef
+ at a = internal externally_initialized global i32 undef
+
+; This global is stored to by the external initialization, so cannot be
+; constant-propagated and removed, despite the fact that there are no writes
+; to it.
+; CHECK: @b = internal unnamed_addr externally_initialized global i32 undef
+ at b = internal externally_initialized global i32 undef
+
+
+define void @foo() {
+; CHECK-LABEL: foo
+entry:
+; CHECK: store i32 42, i32* @a
+ store i32 42, i32* @a
+ ret void
+}
+define i32 @bar() {
+; CHECK-LABEL: bar
+entry:
+; CHECK: %val = load i32, i32* @a
+ %val = load i32, i32* @a
+ ret i32 %val
+}
+
+define i32 @baz() {
+; CHECK-LABEL: baz
+entry:
+; CHECK: %val = load i32, i32* @b
+ %val = load i32, i32* @b
+ ret i32 %val
+}
More information about the llvm-commits
mailing list