@@ -62,14 +62,14 @@ llvm::Value *Codegen::generateIfStmt(const ResolvedIfStmt &stmt) {
6262 trueBB->insertInto (function);
6363 builder.SetInsertPoint (trueBB);
6464 generateBlock (*stmt.trueBlock );
65- builder. CreateBr (exitBB);
65+ generateBrIfNeeded (exitBB);
6666
6767 if (stmt.falseBlock ) {
6868 elseBB->insertInto (function);
6969
7070 builder.SetInsertPoint (elseBB);
7171 generateBlock (*stmt.falseBlock );
72- builder. CreateBr (exitBB);
72+ generateBrIfNeeded (exitBB);
7373 }
7474
7575 exitBB->insertInto (function);
@@ -84,15 +84,15 @@ llvm::Value *Codegen::generateWhileStmt(const ResolvedWhileStmt &stmt) {
8484 auto *body = llvm::BasicBlock::Create (context, " while.body" , function);
8585 auto *exit = llvm::BasicBlock::Create (context, " while.exit" , function);
8686
87- builder. CreateBr (header);
87+ generateBrIfNeeded (header);
8888
8989 builder.SetInsertPoint (header);
9090 llvm::Value *cond = generateExpr (*stmt.condition );
9191 builder.CreateCondBr (doubleToBool (cond), body, exit);
9292
9393 builder.SetInsertPoint (body);
9494 generateBlock (*stmt.body );
95- builder. CreateBr (header);
95+ generateBrIfNeeded (header);
9696
9797 builder.SetInsertPoint (exit);
9898 return nullptr ;
@@ -120,7 +120,8 @@ llvm::Value *Codegen::generateReturnStmt(const ResolvedReturnStmt &stmt) {
120120 storeValue (generateExpr (*stmt.expr ), retVal, stmt.expr ->type );
121121
122122 assert (retBB && " function with return stmt doesn't have a return block" );
123- return builder.CreateBr (retBB);
123+ generateBrIfNeeded (retBB);
124+ return nullptr ;
124125}
125126
126127llvm::Value *Codegen::generateMemberExpr (const ResolvedMemberExpr &memberExpr,
@@ -290,7 +291,7 @@ Codegen::generateBinaryOperator(const ResolvedBinaryOperator &binop) {
290291
291292 builder.SetInsertPoint (rhsBB);
292293 llvm::Value *rhs = doubleToBool (generateExpr (*binop.rhs ));
293- builder. CreateBr (mergeBB);
294+ generateBrIfNeeded (mergeBB);
294295
295296 rhsBB = builder.GetInsertBlock ();
296297 builder.SetInsertPoint (mergeBB);
@@ -362,6 +363,13 @@ llvm::Value *Codegen::boolToDouble(llvm::Value *v) {
362363 return builder.CreateUIToFP (v, builder.getDoubleTy (), " to.double" );
363364}
364365
366+ void Codegen::generateBrIfNeeded (llvm::BasicBlock *targetBB) {
367+ llvm::BasicBlock *currentBB = builder.GetInsertBlock ();
368+
369+ if (currentBB && !currentBB->getTerminator ())
370+ builder.CreateBr (targetBB);
371+ }
372+
365373llvm::Function *Codegen::getCurrentFunction () {
366374 return builder.GetInsertBlock ()->getParent ();
367375};
@@ -410,7 +418,7 @@ void Codegen::generateBlock(const ResolvedBlock &block) {
410418 // The break ensures that no other instruction is generated that will be
411419 // inserted regardless of there is no insertion point and crash (e.g.:
412420 // CreateStore, CreateLoad).
413- if (dynamic_cast < const ResolvedReturnStmt *>(stmt. get () )) {
421+ if (builder. GetInsertBlock ()-> getTerminator ( )) {
414422 builder.ClearInsertionPoint ();
415423 break ;
416424 }
@@ -460,7 +468,7 @@ void Codegen::generateFunctionBody(const ResolvedFunctionDecl &functionDecl) {
460468 generateBlock (*functionDecl.body );
461469
462470 if (retBB->hasNPredecessorsOrMore (1 )) {
463- builder. CreateBr (retBB);
471+ generateBrIfNeeded (retBB);
464472 retBB->insertInto (function);
465473 builder.SetInsertPoint (retBB);
466474 }
0 commit comments