[GlobalOpt] Remove unreachable blocks before optimizing a function.
authorDavide Italiano <davide@freebsd.org>
Wed, 5 Jul 2017 22:28:28 +0000 (22:28 +0000)
committerDavide Italiano <davide@freebsd.org>
Wed, 5 Jul 2017 22:28:28 +0000 (22:28 +0000)
LLVM's definition of dominance allows instructions that are cyclic
in unreachable blocks, e.g.:

  %pat = select i1 %condition, @global, i16* %pat

because any instruction dominates an instruction in a block that's
not reachable from entry.
So, remove unreachable blocks from the function, because a) there's
no point in analyzing them and b) GlobalOpt should otherwise grow
some more complicated logic to break these cycles.

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

llvm-svn: 307215

llvm/lib/Transforms/IPO/GlobalOpt.cpp
llvm/test/Transforms/GlobalOpt/pr33686.ll [new file with mode: 0644]

index f277a51ae659aec3d84710d31531e41f02e21908..2ce868995bde7617118c50d0e1e29d72512f3196 100644 (file)
@@ -2026,6 +2026,24 @@ OptimizeFunctions(Module &M, TargetLibraryInfo *TLI,
       continue;
     }
 
+    // LLVM's definition of dominance allows instructions that are cyclic
+    // in unreachable blocks, e.g.:
+    // %pat = select i1 %condition, @global, i16* %pat
+    // because any instruction dominates an instruction in a block that's
+    // not reachable from entry.
+    // So, remove unreachable blocks from the function, because a) there's
+    // no point in analyzing them and b) GlobalOpt should otherwise grow
+    // some more complicated logic to break these cycles.
+    // Removing unreachable blocks might invalidate the dominator so we
+    // recalculate it.
+    if (!F->isDeclaration()) {
+      if (removeUnreachableBlocks(*F)) {
+        auto &DT = LookupDomTree(*F);
+        DT.recalculate(*F);
+        Changed = true;
+      }
+    }
+
     Changed |= processGlobal(*F, TLI, LookupDomTree);
 
     if (!F->hasLocalLinkage())
diff --git a/llvm/test/Transforms/GlobalOpt/pr33686.ll b/llvm/test/Transforms/GlobalOpt/pr33686.ll
new file mode 100644 (file)
index 0000000..153a85f
--- /dev/null
@@ -0,0 +1,17 @@
+; RUN: opt -S -globalopt %s | FileCheck %s
+
+; CHECK-LABEL: define void @beth
+; CHECK-NEXT:   entry:
+; CHECK-NEXT:   ret void
+; CHEC-NEXT:  }
+
+@glob = external global i16, align 1
+
+define void @beth() {
+entry:
+  ret void
+
+notreachable:
+  %patatino = select i1 undef, i16* @glob, i16* %patatino
+  br label %notreachable
+}