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