[PATCH] D13343: GlobalOpt does not treat externally_initialized globals correctly

Oliver Stannard via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 05:51:40 PDT 2015


olista01 created this revision.
olista01 added a subscriber: llvm-commits.
olista01 set the repository for this revision to rL LLVM.

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.

Repository:
  rL LLVM

http://reviews.llvm.org/D13343

Files:
  lib/Transforms/IPO/GlobalOpt.cpp
  lib/Transforms/Utils/GlobalStatus.cpp
  test/Transforms/GlobalOpt/externally-initialized.ll

Index: test/Transforms/GlobalOpt/externally-initialized.ll
===================================================================
--- /dev/null
+++ test/Transforms/GlobalOpt/externally-initialized.ll
@@ -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
+}
Index: lib/Transforms/Utils/GlobalStatus.cpp
===================================================================
--- lib/Transforms/Utils/GlobalStatus.cpp
+++ lib/Transforms/Utils/GlobalStatus.cpp
@@ -49,6 +49,10 @@
 
 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)) {
Index: lib/Transforms/IPO/GlobalOpt.cpp
===================================================================
--- lib/Transforms/IPO/GlobalOpt.cpp
+++ lib/Transforms/IPO/GlobalOpt.cpp
@@ -1804,7 +1804,7 @@
       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


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D13343.36232.patch
Type: text/x-patch
Size: 2597 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151001/2dd3f5b0/attachment.bin>


More information about the llvm-commits mailing list