diff --git a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp --- a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp +++ b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp @@ -99,6 +99,7 @@ switch (Term->getOpcode()) { case Instruction::Ret: case Instruction::Resume: + case Instruction::Unreachable: break; default: continue; diff --git a/llvm/test/CodeGen/Thumb2/setjmp_longjmp.ll b/llvm/test/CodeGen/Thumb2/setjmp_longjmp.ll --- a/llvm/test/CodeGen/Thumb2/setjmp_longjmp.ll +++ b/llvm/test/CodeGen/Thumb2/setjmp_longjmp.ll @@ -25,18 +25,18 @@ ; CHECK-NEXT: b LSJLJEH0 ; CHECK-NEXT: movs r0, #1 @ eh_setjmp end ; CHECK-NEXT: LSJLJEH0: -; CHECK-NEXT: cbz r0, LBB0_3 -; CHECK-NEXT: @ %bb.1: @ %if.then -; CHECK-NEXT: movw r0, :lower16:(L_g$non_lazy_ptr-(LPC0_0+4)) -; CHECK-NEXT: movt r0, :upper16:(L_g$non_lazy_ptr-(LPC0_0+4)) +; CHECK-NEXT: movw r1, :lower16:(L_g$non_lazy_ptr-(LPC0_0+4)) +; CHECK-NEXT: movt r1, :upper16:(L_g$non_lazy_ptr-(LPC0_0+4)) ; CHECK-NEXT: LPC0_0: -; CHECK-NEXT: add r0, pc -; CHECK-NEXT: ldr r1, [r0] +; CHECK-NEXT: add r1, pc +; CHECK-NEXT: cbz r0, LBB0_4 +; CHECK-NEXT: @ %bb.1: @ %if.then +; CHECK-NEXT: ldr r2, [r1] ; CHECK-NEXT: movs r0, #1 -; CHECK-NEXT: str r1, [sp] @ 4-byte Spill -; CHECK-NEXT: str r0, [r1] -; CHECK-NEXT: add r0, sp, #4 +; CHECK-NEXT: str r2, [sp] @ 4-byte Spill ; CHECK-NEXT: movs r1, #0 +; CHECK-NEXT: str r0, [r2] +; CHECK-NEXT: add r0, sp, #4 ; CHECK-NEXT: str r7, [sp, #4] ; CHECK-NEXT: str.w sp, [sp, #12] ; CHECK-NEXT: mov r1, pc @ eh_setjmp begin @@ -54,31 +54,26 @@ ; CHECK-NEXT: addne sp, #24 ; CHECK-NEXT: it ne ; CHECK-NEXT: popne.w {r4, r5, r6, r7, r8, r10, r11, pc} -; CHECK-NEXT: LBB0_2: @ %if2.else -; CHECK-NEXT: ldr r1, [sp] @ 4-byte Reload +; CHECK-NEXT: LBB0_2: +; CHECK-NEXT: movw r1, :lower16:(L_g$non_lazy_ptr-(LPC0_1+4)) +; CHECK-NEXT: add r2, sp, #4 +; CHECK-NEXT: movt r1, :upper16:(L_g$non_lazy_ptr-(LPC0_1+4)) ; CHECK-NEXT: movs r0, #2 -; CHECK-NEXT: str r0, [r1] -; CHECK-NEXT: add r1, sp, #4 -; CHECK-NEXT: movs r0, #0 -; CHECK-NEXT: ldr r0, [r1, #8] -; CHECK-NEXT: mov sp, r0 -; CHECK-NEXT: ldr r0, [r1, #4] -; CHECK-NEXT: ldr r7, [r1] -; CHECK-NEXT: bx r0 -; CHECK-NEXT: LBB0_3: @ %if.else -; CHECK-NEXT: movw r0, :lower16:(L_g$non_lazy_ptr-(LPC0_1+4)) -; CHECK-NEXT: movs r1, #0 -; CHECK-NEXT: movt r0, :upper16:(L_g$non_lazy_ptr-(LPC0_1+4)) ; CHECK-NEXT: LPC0_1: -; CHECK-NEXT: add r0, pc -; CHECK-NEXT: ldr r0, [r0] -; CHECK-NEXT: str r1, [r0] -; CHECK-NEXT: add r0, sp, #4 -; CHECK-NEXT: ldr r1, [r0, #8] -; CHECK-NEXT: mov sp, r1 -; CHECK-NEXT: ldr r1, [r0, #4] -; CHECK-NEXT: ldr r7, [r0] -; CHECK-NEXT: bx r1 +; CHECK-NEXT: add r1, pc +; CHECK-NEXT: LBB0_3: @ %common.unreachable +; CHECK-NEXT: ldr r1, [r1] +; CHECK-NEXT: str r0, [r1] +; CHECK-NEXT: movs r0, #0 +; CHECK-NEXT: ldr r0, [r2, #8] +; CHECK-NEXT: mov sp, r0 +; CHECK-NEXT: ldr r0, [r2, #4] +; CHECK-NEXT: ldr r7, [r2] +; CHECK-NEXT: bx r0 +; CHECK-NEXT: LBB0_4: +; CHECK-NEXT: add r2, sp, #4 +; CHECK-NEXT: movs r0, #0 +; CHECK-NEXT: b LBB0_3 entry: %buf = alloca [5 x i8*], align 4 %bufptr = bitcast [5 x i8*]* %buf to i8* diff --git a/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll b/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll --- a/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll +++ b/llvm/test/Transforms/SimplifyCFG/tail-merge-noreturn.ll @@ -10,22 +10,16 @@ define void @merge_simple() { ; CHECK-LABEL: @merge_simple( ; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] -; CHECK: a1: +; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[COMMON_UNREACHABLE:%.*]] +; CHECK: common.unreachable: ; CHECK-NEXT: call void @assert_fail_1(i32 0) ; CHECK-NEXT: unreachable ; CHECK: cont1: ; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]] -; CHECK: a2: -; CHECK-NEXT: call void @assert_fail_1(i32 0) -; CHECK-NEXT: unreachable +; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[COMMON_UNREACHABLE]] ; CHECK: cont2: ; CHECK-NEXT: [[C3:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A3:%.*]] -; CHECK: a3: -; CHECK-NEXT: call void @assert_fail_1(i32 0) -; CHECK-NEXT: unreachable +; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[COMMON_UNREACHABLE]] ; CHECK: cont3: ; CHECK-NEXT: ret void ; @@ -54,22 +48,17 @@ ; CHECK-LABEL: @phi_three_constants( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] -; CHECK: a1: -; CHECK-NEXT: call void @assert_fail_1(i32 0) +; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[COMMON_UNREACHABLE:%.*]] +; CHECK: common.unreachable: +; CHECK-NEXT: [[DOTSINK:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[CONT1]] ], [ 2, [[CONT2:%.*]] ] +; CHECK-NEXT: call void @assert_fail_1(i32 [[DOTSINK]]) ; CHECK-NEXT: unreachable ; CHECK: cont1: ; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]] -; CHECK: a2: -; CHECK-NEXT: call void @assert_fail_1(i32 1) -; CHECK-NEXT: unreachable +; CHECK-NEXT: br i1 [[C2]], label [[CONT2]], label [[COMMON_UNREACHABLE]] ; CHECK: cont2: ; CHECK-NEXT: [[C3:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A3:%.*]] -; CHECK: a3: -; CHECK-NEXT: call void @assert_fail_1(i32 2) -; CHECK-NEXT: unreachable +; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[COMMON_UNREACHABLE]] ; CHECK: cont3: ; CHECK-NEXT: ret void ; @@ -98,16 +87,14 @@ define void @dont_phi_values(i32 %x, i32 %y) { ; CHECK-LABEL: @dont_phi_values( ; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] -; CHECK: a1: -; CHECK-NEXT: call void @assert_fail_1(i32 [[X:%.*]]) +; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[COMMON_UNREACHABLE:%.*]] +; CHECK: common.unreachable: +; CHECK-NEXT: [[Y_SINK:%.*]] = phi i32 [ [[X:%.*]], [[TMP0:%.*]] ], [ [[Y:%.*]], [[CONT1]] ] +; CHECK-NEXT: call void @assert_fail_1(i32 [[Y_SINK]]) ; CHECK-NEXT: unreachable ; CHECK: cont1: ; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]] -; CHECK: a2: -; CHECK-NEXT: call void @assert_fail_1(i32 [[Y:%.*]]) -; CHECK-NEXT: unreachable +; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[COMMON_UNREACHABLE]] ; CHECK: cont2: ; CHECK-NEXT: ret void ; @@ -166,18 +153,17 @@ ; CHECK-NEXT: br i1 [[C:%.*]], label [[S1:%.*]], label [[S2:%.*]] ; CHECK: s1: ; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C1]], label [[A1:%.*]], label [[A2:%.*]] +; CHECK-NEXT: br i1 [[C1]], label [[COMMON_UNREACHABLE:%.*]], label [[A2:%.*]] ; CHECK: s2: ; CHECK-NEXT: [[C2:%.*]] = call i1 @bar() -; CHECK-NEXT: br i1 [[C2]], label [[A1]], label [[A2]] -; CHECK: a1: -; CHECK-NEXT: [[L1:%.*]] = phi i32 [ 0, [[S1]] ], [ 1, [[S2]] ] -; CHECK-NEXT: call void @assert_fail_1(i32 [[L1]]) +; CHECK-NEXT: br i1 [[C2]], label [[COMMON_UNREACHABLE]], label [[A2]] +; CHECK: common.unreachable: +; CHECK-NEXT: [[L2_SINK:%.*]] = phi i32 [ [[L2:%.*]], [[A2]] ], [ 0, [[S1]] ], [ 1, [[S2]] ] +; CHECK-NEXT: call void @assert_fail_1(i32 [[L2_SINK]]) ; CHECK-NEXT: unreachable ; CHECK: a2: -; CHECK-NEXT: [[L2:%.*]] = phi i32 [ 2, [[S1]] ], [ 3, [[S2]] ] -; CHECK-NEXT: call void @assert_fail_1(i32 [[L2]]) -; CHECK-NEXT: unreachable +; CHECK-NEXT: [[L2]] = phi i32 [ 2, [[S1]] ], [ 3, [[S2]] ] +; CHECK-NEXT: br label [[COMMON_UNREACHABLE]] ; entry: br i1 %c, label %s1, label %s2 @@ -201,19 +187,18 @@ ; CHECK-LABEL: @tail_merge_switch( ; CHECK-NEXT: entry: ; CHECK-NEXT: switch i32 [[V:%.*]], label [[RET:%.*]] [ -; CHECK-NEXT: i32 0, label [[A1:%.*]] +; CHECK-NEXT: i32 0, label [[COMMON_UNREACHABLE:%.*]] ; CHECK-NEXT: i32 13, label [[A2:%.*]] ; CHECK-NEXT: i32 42, label [[A3:%.*]] ; CHECK-NEXT: ] -; CHECK: a1: -; CHECK-NEXT: call void @assert_fail_1(i32 0) +; CHECK: common.unreachable: +; CHECK-NEXT: [[DOTSINK:%.*]] = phi i32 [ 2, [[A3]] ], [ 1, [[A2]] ], [ 0, [[ENTRY:%.*]] ] +; CHECK-NEXT: call void @assert_fail_1(i32 [[DOTSINK]]) ; CHECK-NEXT: unreachable ; CHECK: a2: -; CHECK-NEXT: call void @assert_fail_1(i32 1) -; CHECK-NEXT: unreachable +; CHECK-NEXT: br label [[COMMON_UNREACHABLE]] ; CHECK: a3: -; CHECK-NEXT: call void @assert_fail_1(i32 2) -; CHECK-NEXT: unreachable +; CHECK-NEXT: br label [[COMMON_UNREACHABLE]] ; CHECK: ret: ; CHECK-NEXT: ret void ; @@ -239,18 +224,14 @@ define void @need_to_add_bb2_preds(i1 %c1) { ; CHECK-LABEL: @need_to_add_bb2_preds( ; CHECK-NEXT: bb1: -; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB2:%.*]], label [[A1:%.*]] +; CHECK-NEXT: br i1 [[C1:%.*]], label [[BB2:%.*]], label [[COMMON_UNREACHABLE:%.*]] ; CHECK: bb2: ; CHECK-NEXT: [[C2:%.*]] = call i1 @bar() -; CHECK-NEXT: br i1 [[C2]], label [[A2:%.*]], label [[A3:%.*]] -; CHECK: a1: -; CHECK-NEXT: call void @assert_fail_1(i32 0) -; CHECK-NEXT: unreachable -; CHECK: a2: -; CHECK-NEXT: call void @assert_fail_1(i32 1) -; CHECK-NEXT: unreachable -; CHECK: a3: -; CHECK-NEXT: call void @assert_fail_1(i32 2) +; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C2]], i32 1, i32 2 +; CHECK-NEXT: br label [[COMMON_UNREACHABLE]] +; CHECK: common.unreachable: +; CHECK-NEXT: [[DOTSINK:%.*]] = phi i32 [ 0, [[BB1:%.*]] ], [ [[SPEC_SELECT]], [[BB2]] ] +; CHECK-NEXT: call void @assert_fail_1(i32 [[DOTSINK]]) ; CHECK-NEXT: unreachable ; bb1: @@ -274,20 +255,17 @@ ; CHECK-LABEL: @phi_in_bb2( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] -; CHECK: a1: -; CHECK-NEXT: call void @assert_fail_1(i32 0) +; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[COMMON_UNREACHABLE:%.*]] +; CHECK: common.unreachable: +; CHECK-NEXT: [[P2_SINK:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[CONT1]] ], [ 2, [[CONT2:%.*]] ] +; CHECK-NEXT: call void @assert_fail_1(i32 [[P2_SINK]]) ; CHECK-NEXT: unreachable ; CHECK: cont1: ; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A2:%.*]] -; CHECK: a2: -; CHECK-NEXT: [[P2:%.*]] = phi i32 [ 1, [[CONT1]] ], [ 2, [[CONT2]] ] -; CHECK-NEXT: call void @assert_fail_1(i32 [[P2]]) -; CHECK-NEXT: unreachable +; CHECK-NEXT: br i1 [[C2]], label [[CONT2]], label [[COMMON_UNREACHABLE]] ; CHECK: cont2: ; CHECK-NEXT: [[C3:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A2]] +; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[COMMON_UNREACHABLE]] ; CHECK: cont3: ; CHECK-NEXT: ret void ; @@ -336,10 +314,12 @@ ; CHECK: if.then1: ; CHECK-NEXT: call void @escape_i32_ptr(i32* nonnull [[X]]) ; CHECK-NEXT: br label [[IF_END]] -; CHECK: if.end: -; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[TMP0]]) +; CHECK: common.unreachable: ; CHECK-NEXT: call void @abort() ; CHECK-NEXT: unreachable +; CHECK: if.end: +; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[TMP0]]) +; CHECK-NEXT: br label [[COMMON_UNREACHABLE:%.*]] ; CHECK: if.then3: ; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[Y]] to i8* ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull [[TMP1]]) @@ -351,8 +331,7 @@ ; CHECK-NEXT: br label [[IF_END7]] ; CHECK: if.end7: ; CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull [[TMP1]]) -; CHECK-NEXT: call void @abort() -; CHECK-NEXT: unreachable +; CHECK-NEXT: br label [[COMMON_UNREACHABLE]] ; CHECK: if.end9: ; CHECK-NEXT: ret void ; @@ -408,20 +387,16 @@ ; CHECK-LABEL: @dead_phi( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[C1:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[A1:%.*]] -; CHECK: a1: -; CHECK-NEXT: [[DEAD:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 1, [[CONT1]] ] +; CHECK-NEXT: br i1 [[C1]], label [[CONT1:%.*]], label [[COMMON_UNREACHABLE:%.*]] +; CHECK: common.unreachable: ; CHECK-NEXT: call void @assert_fail_1(i32 0) ; CHECK-NEXT: unreachable ; CHECK: cont1: ; CHECK-NEXT: [[C2:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[A1]] +; CHECK-NEXT: br i1 [[C2]], label [[CONT2:%.*]], label [[COMMON_UNREACHABLE]] ; CHECK: cont2: ; CHECK-NEXT: [[C3:%.*]] = call i1 @foo() -; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[A3:%.*]] -; CHECK: a3: -; CHECK-NEXT: call void @assert_fail_1(i32 0) -; CHECK-NEXT: unreachable +; CHECK-NEXT: br i1 [[C3]], label [[CONT3:%.*]], label [[COMMON_UNREACHABLE]] ; CHECK: cont3: ; CHECK-NEXT: ret void ; @@ -450,15 +425,10 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[C:%.*]], metadata [[META5:![0-9]+]], metadata !DIExpression()), !dbg [[DBG7:![0-9]+]] ; CHECK-NEXT: switch i32 [[C]], label [[SW_EPILOG:%.*]] [ -; CHECK-NEXT: i32 13, label [[SW_BB:%.*]] -; CHECK-NEXT: i32 42, label [[SW_BB1:%.*]] +; CHECK-NEXT: i32 13, label [[COMMON_UNREACHABLE:%.*]] +; CHECK-NEXT: i32 42, label [[COMMON_UNREACHABLE]] ; CHECK-NEXT: ] -; CHECK: sw.bb: -; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 55, metadata [[META5]], metadata !DIExpression()), !dbg [[DBG7]] -; CHECK-NEXT: tail call void @abort() -; CHECK-NEXT: unreachable -; CHECK: sw.bb1: -; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 67, metadata [[META5]], metadata !DIExpression()), !dbg [[DBG7]] +; CHECK: common.unreachable: ; CHECK-NEXT: tail call void @abort() ; CHECK-NEXT: unreachable ; CHECK: sw.epilog: @@ -490,19 +460,11 @@ ; CHECK-NEXT: entry: ; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[C:%.*]], metadata [[META5]], metadata !DIExpression()), !dbg [[DBG7]] ; CHECK-NEXT: switch i32 [[C]], label [[SW_EPILOG:%.*]] [ -; CHECK-NEXT: i32 13, label [[SW_BB:%.*]] -; CHECK-NEXT: i32 42, label [[SW_BB1:%.*]] -; CHECK-NEXT: i32 53, label [[SW_BB2:%.*]] +; CHECK-NEXT: i32 13, label [[COMMON_UNREACHABLE:%.*]] +; CHECK-NEXT: i32 42, label [[COMMON_UNREACHABLE]] +; CHECK-NEXT: i32 53, label [[COMMON_UNREACHABLE]] ; CHECK-NEXT: ] -; CHECK: sw.bb: -; CHECK-NEXT: [[C_1:%.*]] = phi i32 [ 55, [[ENTRY:%.*]] ], [ 67, [[SW_BB1]] ] -; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 [[C_1]], metadata [[META5]], metadata !DIExpression()), !dbg [[DBG7]] -; CHECK-NEXT: tail call void @abort() -; CHECK-NEXT: unreachable -; CHECK: sw.bb1: -; CHECK-NEXT: br label [[SW_BB]] -; CHECK: sw.bb2: -; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 84, metadata [[META5]], metadata !DIExpression()), !dbg [[DBG7]] +; CHECK: common.unreachable: ; CHECK-NEXT: tail call void @abort() ; CHECK-NEXT: unreachable ; CHECK: sw.epilog: