diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -2031,7 +2031,8 @@ assert(PrevInstr && "no previous instruction for a fall through"); if (MIB->isUnconditionalBranch(Instr) && !MIB->isUnconditionalBranch(*PrevInstr) && - !MIB->getConditionalTailCall(*PrevInstr)) { + !MIB->getConditionalTailCall(*PrevInstr) && + !MIB->isReturn(*PrevInstr)) { // Temporarily restore inserter basic block. InsertBB = PrevBB; } else { diff --git a/bolt/test/AArch64/jmp-after-ret.s b/bolt/test/AArch64/jmp-after-ret.s new file mode 100644 --- /dev/null +++ b/bolt/test/AArch64/jmp-after-ret.s @@ -0,0 +1,24 @@ +## This test checks that the unreachable unconditional branch is removed +## if it is located after return instruction. + +# REQUIRES: system-linux + +# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown \ +# RUN: %s -o %t.o +# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt | FileCheck %s + +# CHECK: UCE removed 1 blocks + + .text + .align 4 + .global main + .type main, %function +main: + b.eq 1f + ret + b main +1: + mov x1, #1 + ret + .size main, .-main diff --git a/bolt/test/X86/jmp-after-ret.s b/bolt/test/X86/jmp-after-ret.s new file mode 100644 --- /dev/null +++ b/bolt/test/X86/jmp-after-ret.s @@ -0,0 +1,24 @@ +## This test checks that the unreachable unconditional branch is removed +## if it is located after return instruction. + +# REQUIRES: system-linux + +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown \ +# RUN: %s -o %t.o +# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt | FileCheck %s + +# CHECK: UCE removed 1 blocks + + .text + .globl main + .type main, %function + .size main, .Lend-main +main: + je 1f + retq + jmp main +1: + movl $0x2, %ebx + retq +.Lend: