gollvm: better handling for statically unreachable code

Fix a couple of issues in the control-flow materialization phase in
the bridge that have to do with statically unreachable code (we can
get asserts and IR-verification failures for functions of the form

   func X() {
     if false {
       return
     }
     ... complex control flow ...
   }

Change-Id: Icce7086d72b93683efc69419eafa758b1cec0199
Reviewed-on: https://go-review.googlesource.com/c/gollvm/+/193478
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/bridge/go-llvm.cpp b/bridge/go-llvm.cpp
index 6daf115..7db9f44 100644
--- a/bridge/go-llvm.cpp
+++ b/bridge/go-llvm.cpp
@@ -3278,14 +3278,28 @@
 
   // Visit true block
   llvm::BasicBlock *tsucc = walk(trueStmt, nullptr, tblock);
-  if (tsucc && ! tsucc->getTerminator())
-    llvm::BranchInst::Create(ft, tsucc);
+  if (tsucc && ! tsucc->getTerminator()) {
+    if (tblock)
+      llvm::BranchInst::Create(ft, tsucc);
+    else {
+      LIRBuilder builder(context_, llvm::ConstantFolder());
+      llvm::Instruction *unreachable = builder.CreateUnreachable();
+      tsucc->getInstList().push_back(unreachable);
+    }
+  }
 
   // Walk false block if present
   if (falseStmt) {
     llvm::BasicBlock *fsucc = walk(falseStmt, nullptr, fblock);
-    if (fsucc && ! fsucc->getTerminator())
-      llvm::BranchInst::Create(ft, fsucc);
+    if (fsucc && ! fsucc->getTerminator()) {
+      if (fblock)
+        llvm::BranchInst::Create(ft, fsucc);
+      else {
+        LIRBuilder builder(context_, llvm::ConstantFolder());
+        llvm::Instruction *unreachable = builder.CreateUnreachable();
+        fsucc->getInstList().push_back(unreachable);
+      }
+    }
   }
 
   // Remove fallthrough block if it was never used