Skip to content

Commit

Permalink
[Codegen] fix bugprone return block emission
Browse files Browse the repository at this point in the history
  • Loading branch information
isuckatcs committed Jul 5, 2024
1 parent 4fff0e9 commit 015f286
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 13 deletions.
7 changes: 1 addition & 6 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,14 +333,8 @@ void Codegen::generateBlock(const ResolvedBlock &block) {
break;
}
}

// FIXME: This should disappear with return optimization.
if (const llvm::BasicBlock *bb = builder.GetInsertBlock();
bb && bb->empty() && !retBlock->hasNPredecessors(0))
builder.CreateUnreachable();
}

// FIXME: Optimize return stmt emission.
void Codegen::generateFunctionBody(const ResolvedFunctionDecl &functionDecl) {
auto *function = module->getFunction(functionDecl.identifier);
auto *bb = llvm::BasicBlock::Create(context, "", function);
Expand Down Expand Up @@ -370,6 +364,7 @@ void Codegen::generateFunctionBody(const ResolvedFunctionDecl &functionDecl) {
generateBlock(*functionDecl.body);

if (retBlock->hasNPredecessorsOrMore(1)) {
builder.CreateBr(retBlock);
retBlock->insertInto(function);
builder.SetInsertPoint(retBlock);
}
Expand Down
4 changes: 2 additions & 2 deletions test/codegen/condition_empty_merge.al
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ fn main(): void {
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: merge: ; preds = <null operand!>, %0
// CHECK-NEXT: unreachable
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: return: ; preds = %then
// CHECK-NEXT: return: ; preds = %merge, %then
// CHECK-NEXT: ret void
// CHECK-NEXT: }
2 changes: 1 addition & 1 deletion test/codegen/multiple_return.al
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ fn main(): void {
// CHECK: define void @__builtin_main() {
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: return: ; preds = %0
// CHECK-NEXT: return: ; preds = <null operand!>, %0
// CHECK-NEXT: ret void
// CHECK-NEXT: }
2 changes: 1 addition & 1 deletion test/codegen/multiple_return_if.al
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn foo(x: number): number {
// CHECK-NEXT: store double 5.200000e+00, double* %retval, align 8
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: return: ; preds = %merge5, %then3, %then
// CHECK-NEXT: return: ; preds = <null operand!>, %merge5, %then3, %then
// CHECK-NEXT: %5 = load double, double* %retval, align 8
// CHECK-NEXT: ret double %5

Expand Down
2 changes: 1 addition & 1 deletion test/codegen/multiple_return_while.al
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ fn foo(x: number): number {
// CHECK-NEXT: store double 5.000000e+00, double* %retval, align 8
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: return: ; preds = %whileExit, %merge, %then
// CHECK-NEXT: return: ; preds = <null operand!>, %whileExit, %merge, %then
// CHECK-NEXT: %8 = load double, double* %retval, align 8
// CHECK-NEXT: ret double %8

Expand Down
99 changes: 99 additions & 0 deletions test/codegen/return.al
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// RUN: compiler %s -llvm-dump 2>&1 | filecheck %s
// RUN: compiler %s -o return && ./return | ( ! grep ^ )
fn main(): void {}

fn noInsertPoint(): void {
return;
}
// CHECK: define void @noInsertPoint() {
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: return: ; preds = <null operand!>, %0
// CHECK-NEXT: ret void
// CHECK-NEXT: }

fn insertPointEmptyBlock(): void {
if 1.0 {
return;
}
}
// CHECK: define void @insertPointEmptyBlock() {
// CHECK-NEXT: br i1 true, label %then, label %merge
// CHECK-NEXT:
// CHECK-NEXT: then: ; preds = %0
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: merge: ; preds = <null operand!>, %0
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: return: ; preds = %merge, %then
// CHECK-NEXT: ret void
// CHECK-NEXT: }

fn insertPointEmptyBlock2(): void {
while 1.0 {
return;
}
}
// CHECK: define void @insertPointEmptyBlock2() {
// CHECK-NEXT: br label %whileCond
// CHECK-NEXT:
// CHECK-NEXT: whileCond: ; preds = <null operand!>, %0
// CHECK-NEXT: br i1 true, label %whileBody, label %whileExit
// CHECK-NEXT:
// CHECK-NEXT: whileBody: ; preds = %whileCond
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: whileExit: ; preds = %whileCond
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: return: ; preds = %whileExit, %whileBody
// CHECK-NEXT: ret void
// CHECK-NEXT: }

fn insertPointNonEmptyBlock(): void {
if 1.0 {
return;
}

let x: number = 1.0;
}
// CHECK: define void @insertPointNonEmptyBlock() {
// CHECK-NEXT: %x = alloca double, align 8
// CHECK-NEXT: br i1 true, label %then, label %merge
// CHECK-NEXT:
// CHECK-NEXT: then: ; preds = %0
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: merge: ; preds = <null operand!>, %0
// CHECK-NEXT: store double 1.000000e+00, double* %x, align 8
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: return: ; preds = %merge, %then
// CHECK-NEXT: ret void
// CHECK-NEXT: }

fn insertPointNonEmptyBlock2(): void {
while 1.0 {
return;
}

let x: number = 1.0;
}
// CHECK: define void @insertPointNonEmptyBlock2() {
// CHECK-NEXT: %x = alloca double, align 8
// CHECK-NEXT: br label %whileCond
// CHECK-NEXT:
// CHECK-NEXT: whileCond: ; preds = <null operand!>, %0
// CHECK-NEXT: br i1 true, label %whileBody, label %whileExit
// CHECK-NEXT:
// CHECK-NEXT: whileBody: ; preds = %whileCond
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: whileExit: ; preds = %whileCond
// CHECK-NEXT: store double 1.000000e+00, double* %x, align 8
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: return: ; preds = %whileExit, %whileBody
// CHECK-NEXT: ret void
// CHECK-NEXT: }
4 changes: 2 additions & 2 deletions test/codegen/while_empty_exit.al
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ fn foo(x: number): void {
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: whileExit: ; preds = %whileCond
// CHECK-NEXT: unreachable
// CHECK-NEXT: br label %return
// CHECK-NEXT:
// CHECK-NEXT: return: ; preds = %whileBody
// CHECK-NEXT: return: ; preds = %whileExit, %whileBody
// CHECK-NEXT: ret void
// CHECK-NEXT: }

Expand Down

0 comments on commit 015f286

Please sign in to comment.