| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 | |
| ; RUN: opt -passes=simplifycfg -S < %s | FileCheck %s | |
| ; cleanuppad/cleanupret | |
| define void @unreachable_cleanuppad_linear(i64 %shapes.1) personality ptr null { | |
| ; CHECK-LABEL: define void @unreachable_cleanuppad_linear( | |
| ; CHECK-SAME: i64 [[SHAPES_1:%.*]]) personality ptr null { | |
| ; CHECK-NEXT: [[START:.*:]] | |
| ; CHECK-NEXT: [[_7:%.*]] = icmp ult i64 0, [[SHAPES_1]] | |
| ; CHECK-NEXT: ret void | |
| ; | |
| start: | |
| %_7 = icmp ult i64 0, %shapes.1 | |
| ret void | |
| funclet: | |
| %cleanuppad = cleanuppad within none [] | |
| br label %funclet_end | |
| funclet_end: | |
| cleanupret from %cleanuppad unwind to caller | |
| } | |
| define void @unreachable_cleanuppad_linear_middle_block(i64 %shapes.1) personality ptr null { | |
| ; CHECK-LABEL: define void @unreachable_cleanuppad_linear_middle_block( | |
| ; CHECK-SAME: i64 [[SHAPES_1:%.*]]) personality ptr null { | |
| ; CHECK-NEXT: [[START:.*:]] | |
| ; CHECK-NEXT: [[_7:%.*]] = icmp ult i64 0, [[SHAPES_1]] | |
| ; CHECK-NEXT: ret void | |
| ; | |
| start: | |
| %_7 = icmp ult i64 0, %shapes.1 | |
| ret void | |
| funclet: | |
| %cleanuppad = cleanuppad within none [] | |
| br label %middle_block | |
| middle_block: | |
| %tmp1 = add i64 %shapes.1, 42 | |
| br label %funclet_end | |
| funclet_end: | |
| cleanupret from %cleanuppad unwind to caller | |
| } | |
| define void @unreachable_cleanuppad_multiple_predecessors(i64 %shapes.1) personality ptr null { | |
| ; CHECK-LABEL: define void @unreachable_cleanuppad_multiple_predecessors( | |
| ; CHECK-SAME: i64 [[SHAPES_1:%.*]]) personality ptr null { | |
| ; CHECK-NEXT: [[START:.*:]] | |
| ; CHECK-NEXT: [[_7:%.*]] = icmp ult i64 0, [[SHAPES_1]] | |
| ; CHECK-NEXT: ret void | |
| ; | |
| start: | |
| %_7 = icmp ult i64 0, %shapes.1 | |
| ret void | |
| funclet: | |
| %cleanuppad = cleanuppad within none [] | |
| switch i64 %shapes.1, label %otherwise [ i64 0, label %one | |
| i64 1, label %two | |
| i64 42, label %three ] | |
| one: | |
| br label %funclet_end | |
| two: | |
| br label %funclet_end | |
| three: | |
| br label %funclet_end | |
| otherwise: | |
| br label %funclet_end | |
| funclet_end: | |
| cleanupret from %cleanuppad unwind to caller | |
| } | |
| ; catchpad/catchret | |
| define void @unreachable_catchpad_linear(i64 %shapes.1) personality ptr null { | |
| ; CHECK-LABEL: define void @unreachable_catchpad_linear( | |
| ; CHECK-SAME: i64 [[SHAPES_1:%.*]]) personality ptr null { | |
| ; CHECK-NEXT: [[START:.*:]] | |
| ; CHECK-NEXT: [[_7:%.*]] = icmp ult i64 0, [[SHAPES_1]] | |
| ; CHECK-NEXT: ret void | |
| ; | |
| start: | |
| %_7 = icmp ult i64 0, %shapes.1 | |
| ret void | |
| dispatch: | |
| %cs = catchswitch within none [label %funclet] unwind to caller | |
| funclet: | |
| %cleanuppad = catchpad within %cs [] | |
| br label %funclet_end | |
| funclet_end: | |
| catchret from %cleanuppad to label %unreachable | |
| unreachable: | |
| unreachable | |
| } | |
| define void @unreachable_catchpad_multiple_predecessors(i64 %shapes.1) personality ptr null { | |
| ; CHECK-LABEL: define void @unreachable_catchpad_multiple_predecessors( | |
| ; CHECK-SAME: i64 [[SHAPES_1:%.*]]) personality ptr null { | |
| ; CHECK-NEXT: [[START:.*:]] | |
| ; CHECK-NEXT: [[_7:%.*]] = icmp ult i64 0, [[SHAPES_1]] | |
| ; CHECK-NEXT: ret void | |
| ; | |
| start: | |
| %_7 = icmp ult i64 0, %shapes.1 | |
| ret void | |
| dispatch: | |
| %cs = catchswitch within none [label %funclet] unwind to caller | |
| funclet: | |
| %cleanuppad = catchpad within %cs [] | |
| switch i64 %shapes.1, label %otherwise [ i64 0, label %one | |
| i64 1, label %two | |
| i64 42, label %three ] | |
| one: | |
| br label %funclet_end | |
| two: | |
| br label %funclet_end | |
| three: | |
| br label %funclet_end | |
| otherwise: | |
| br label %funclet_end | |
| funclet_end: | |
| catchret from %cleanuppad to label %unreachable | |
| unreachable: | |
| unreachable | |
| } | |
| ; Issue reproducer | |
| define void @gh148052(i64 %shapes.1) personality ptr null { | |
| ; CHECK-LABEL: define void @gh148052( | |
| ; CHECK-SAME: i64 [[SHAPES_1:%.*]]) personality ptr null { | |
| ; CHECK-NEXT: [[START:.*:]] | |
| ; CHECK-NEXT: [[_7:%.*]] = icmp ult i64 0, [[SHAPES_1]] | |
| ; CHECK-NEXT: call void @llvm.assume(i1 [[_7]]) | |
| ; CHECK-NEXT: ret void | |
| ; | |
| start: | |
| %_7 = icmp ult i64 0, %shapes.1 | |
| br i1 %_7, label %bb1, label %panic | |
| bb1: | |
| %_11 = icmp ult i64 0, %shapes.1 | |
| br i1 %_11, label %bb3, label %panic1 | |
| panic: | |
| unreachable | |
| bb3: | |
| ret void | |
| panic1: | |
| invoke void @func(i64 0, i64 0, ptr null) | |
| to label %unreachable unwind label %funclet_bb14 | |
| funclet_bb14: | |
| %cleanuppad = cleanuppad within none [] | |
| br label %bb13 | |
| unreachable: | |
| unreachable | |
| bb10: | |
| cleanupret from %cleanuppad5 unwind to caller | |
| funclet_bb10: | |
| %cleanuppad5 = cleanuppad within none [] | |
| br label %bb10 | |
| bb13: | |
| cleanupret from %cleanuppad unwind label %funclet_bb10 | |
| } | |
| %struct.foo = type { ptr, %struct.eggs, ptr } | |
| %struct.eggs = type { ptr, ptr, ptr } | |
| declare x86_thiscallcc ptr @quux(ptr, ptr, i32) | |
| define x86_thiscallcc ptr @baz(ptr %arg, ptr %arg1, ptr %arg2, i1 %arg3, ptr %arg4) personality ptr null { | |
| ; CHECK-LABEL: define x86_thiscallcc ptr @baz( | |
| ; CHECK-SAME: ptr [[ARG:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]], i1 [[ARG3:%.*]], ptr [[ARG4:%.*]]) personality ptr null { | |
| ; CHECK-NEXT: [[BB:.*:]] | |
| ; CHECK-NEXT: [[ALLOCA:%.*]] = alloca [2 x [[STRUCT_FOO:%.*]]], align 4 | |
| ; CHECK-NEXT: [[INVOKE:%.*]] = invoke x86_thiscallcc ptr @quux(ptr null, ptr null, i32 0) | |
| ; CHECK-NEXT: to label %[[BB5:.*]] unwind label %[[BB10:.*]] | |
| ; CHECK: [[BB5]]: | |
| ; CHECK-NEXT: unreachable | |
| ; CHECK: [[BB10]]: | |
| ; CHECK-NEXT: [[CLEANUPPAD12:%.*]] = cleanuppad within none [] | |
| ; CHECK-NEXT: [[GETELEMENTPTR13:%.*]] = getelementptr i8, ptr null, i32 -20 | |
| ; CHECK-NEXT: store i32 0, ptr null, align 4 | |
| ; CHECK-NEXT: ret ptr null | |
| ; | |
| bb: | |
| %alloca = alloca [2 x %struct.foo], align 4 | |
| %invoke = invoke x86_thiscallcc ptr @quux(ptr null, ptr null, i32 0) | |
| to label %bb5 unwind label %bb10 | |
| bb5: ; preds = %bb | |
| %getelementptr = getelementptr i8, ptr %arg, i32 20 | |
| %call = call x86_thiscallcc ptr null(ptr null, ptr null, i32 0) | |
| br label %bb6 | |
| bb6: ; preds = %bb10, %bb5 | |
| %phi = phi ptr [ null, %bb10 ], [ null, %bb5 ] | |
| ret ptr %phi | |
| bb7: ; No predecessors! | |
| %cleanuppad = cleanuppad within none [] | |
| %getelementptr8 = getelementptr i8, ptr %arg2, i32 -20 | |
| %icmp = icmp eq ptr %arg, null | |
| br label %bb9 | |
| bb9: ; preds = %bb7 | |
| cleanupret from %cleanuppad unwind label %bb10 | |
| bb10: ; preds = %bb9, %bb | |
| %phi11 = phi ptr [ %arg, %bb9 ], [ null, %bb ] | |
| %cleanuppad12 = cleanuppad within none [] | |
| %getelementptr13 = getelementptr i8, ptr %phi11, i32 -20 | |
| store i32 0, ptr %phi11, align 4 | |
| br label %bb6 | |
| } | |
| declare void @func(i64, i64, ptr) |