diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.cpp @@ -294,6 +294,31 @@ } } + // If we're allowed to modify and the block ends in a unconditional branch + // which could simply fallthrough, remove the branch. (Note: This case only + // matters when we can't understand the whole sequence, otherwise it's also + // handled by BranchFolding.cpp.) + if (AllowModify && isUncondBranchOpcode(LastOpc) && + MBB.isLayoutSuccessor(getBranchDestBlock(*LastInst))) { + LastInst->eraseFromParent(); + LastInst = SecondLastInst; + LastOpc = LastInst->getOpcode(); + if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { + assert(!isUncondBranchOpcode(LastOpc) && + "unreachable unconditional branches removed above"); + + if (isCondBranchOpcode(LastOpc)) { + // Block ends with fall-through condbranch. + parseCondBranch(LastInst, TBB, Cond); + return false; + } + return true; // Can't handle indirect branch. + } else { + SecondLastInst = &*I; + SecondLastOpc = SecondLastInst->getOpcode(); + } + } + // If there are three terminators, we don't know what sort of block this is. if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I)) return true; diff --git a/llvm/test/CodeGen/AArch64/implicit-null-check.ll b/llvm/test/CodeGen/AArch64/implicit-null-check.ll --- a/llvm/test/CodeGen/AArch64/implicit-null-check.ll +++ b/llvm/test/CodeGen/AArch64/implicit-null-check.ll @@ -11,8 +11,7 @@ ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: .Ltmp0: ; CHECK-NEXT: ldr w0, [x0] // on-fault: .LBB0_2 -; CHECK-NEXT: b .LBB0_1 -; CHECK-NEXT: .LBB0_1: // %not_null +; CHECK-NEXT: // %bb.1: // %not_null ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB0_2: // %is_null ; CHECK-NEXT: mov w0, #42 @@ -35,8 +34,7 @@ ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: .Ltmp1: ; CHECK-NEXT: ldr w0, [x0] // on-fault: .LBB1_2 -; CHECK-NEXT: b .LBB1_1 -; CHECK-NEXT: .LBB1_1: // %not_null +; CHECK-NEXT: // %bb.1: // %not_null ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB1_2: // %is_null ; CHECK-NEXT: mov w0, #42 @@ -58,8 +56,7 @@ ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: .Ltmp2: ; CHECK-NEXT: ldr w0, [x0] // on-fault: .LBB2_2 -; CHECK-NEXT: b .LBB2_1 -; CHECK-NEXT: .LBB2_1: // %not_null +; CHECK-NEXT: // %bb.1: // %not_null ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB2_2: // %is_null ; CHECK-NEXT: mov w0, #42 @@ -130,8 +127,7 @@ ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: .Ltmp3: ; CHECK-NEXT: ldrb w0, [x0] // on-fault: .LBB5_2 -; CHECK-NEXT: b .LBB5_1 -; CHECK-NEXT: .LBB5_1: // %not_null +; CHECK-NEXT: // %bb.1: // %not_null ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB5_2: // %is_null ; CHECK-NEXT: mov w0, #42 @@ -182,8 +178,7 @@ ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: .Ltmp4: ; CHECK-NEXT: ldr w0, [x0, #128] // on-fault: .LBB7_2 -; CHECK-NEXT: b .LBB7_1 -; CHECK-NEXT: .LBB7_1: // %not_null +; CHECK-NEXT: // %bb.1: // %not_null ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB7_2: // %is_null ; CHECK-NEXT: mov w0, #42 @@ -206,8 +201,7 @@ ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: .Ltmp5: ; CHECK-NEXT: ldr w8, [x0] // on-fault: .LBB8_2 -; CHECK-NEXT: b .LBB8_1 -; CHECK-NEXT: .LBB8_1: // %not_null +; CHECK-NEXT: // %bb.1: // %not_null ; CHECK-NEXT: add w0, w8, w1 ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB8_2: // %is_null @@ -233,8 +227,7 @@ ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: .Ltmp6: ; CHECK-NEXT: ldr w8, [x0] // on-fault: .LBB9_2 -; CHECK-NEXT: b .LBB9_1 -; CHECK-NEXT: .LBB9_1: // %not_null +; CHECK-NEXT: // %bb.1: // %not_null ; CHECK-NEXT: udiv w9, w1, w2 ; CHECK-NEXT: add w0, w8, w9 ; CHECK-NEXT: ret @@ -289,8 +282,7 @@ ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: .Ltmp7: ; CHECK-NEXT: ldr w8, [x0] // on-fault: .LBB11_2 -; CHECK-NEXT: b .LBB11_1 -; CHECK-NEXT: .LBB11_1: // %not_null +; CHECK-NEXT: // %bb.1: // %not_null ; CHECK-NEXT: add w9, w0, w1 ; CHECK-NEXT: add w8, w9, w8 ; CHECK-NEXT: add w0, w8, #4 // =4 @@ -417,8 +409,7 @@ ; CHECK: // %bb.0: // %entry ; CHECK-NEXT: .Ltmp8: ; CHECK-NEXT: ldur w0, [x0, #-128] // on-fault: .LBB16_2 -; CHECK-NEXT: b .LBB16_1 -; CHECK-NEXT: .LBB16_1: // %not_null +; CHECK-NEXT: // %bb.1: // %not_null ; CHECK-NEXT: ret ; CHECK-NEXT: .LBB16_2: // %is_null ; CHECK-NEXT: mov w0, #42