1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt %s -simplifycfg -S | FileCheck %s 3 4declare i32 @f(i32) 5 6define i32 @basic(i32 %x) { 7; CHECK-LABEL: @basic( 8; CHECK-NEXT: entry: 9; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -5 10; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3 11; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[DEFAULT:%.*]] 12; CHECK: default: 13; CHECK-NEXT: [[TMP0:%.*]] = call i32 @f(i32 0) 14; CHECK-NEXT: ret i32 [[TMP0]] 15; CHECK: a: 16; CHECK-NEXT: [[TMP1:%.*]] = call i32 @f(i32 1) 17; CHECK-NEXT: ret i32 [[TMP1]] 18; 19 20entry: 21 switch i32 %x, label %default [ 22 i32 5, label %a 23 i32 6, label %a 24 i32 7, label %a 25 ] 26default: 27 %0 = call i32 @f(i32 0) 28 ret i32 %0 29a: 30 %1 = call i32 @f(i32 1) 31 ret i32 %1 32} 33 34 35define i32 @unreachable(i32 %x) { 36; CHECK-LABEL: @unreachable( 37; CHECK-NEXT: entry: 38; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -5 39; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3 40; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[B:%.*]] 41; CHECK: a: 42; CHECK-NEXT: [[TMP0:%.*]] = call i32 @f(i32 0) 43; CHECK-NEXT: ret i32 [[TMP0]] 44; CHECK: b: 45; CHECK-NEXT: [[TMP1:%.*]] = call i32 @f(i32 1) 46; CHECK-NEXT: ret i32 [[TMP1]] 47; 48 49entry: 50 switch i32 %x, label %unreachable [ 51 i32 5, label %a 52 i32 6, label %a 53 i32 7, label %a 54 i32 10, label %b 55 i32 20, label %b 56 i32 30, label %b 57 i32 40, label %b 58 ] 59unreachable: 60 unreachable 61a: 62 %0 = call i32 @f(i32 0) 63 ret i32 %0 64b: 65 %1 = call i32 @f(i32 1) 66 ret i32 %1 67} 68 69 70define i32 @unreachable2(i32 %x) { 71; CHECK-LABEL: @unreachable2( 72; CHECK-NEXT: entry: 73; CHECK-NEXT: [[X_OFF:%.*]] = add i32 [[X:%.*]], -5 74; CHECK-NEXT: [[SWITCH:%.*]] = icmp ult i32 [[X_OFF]], 3 75; CHECK-NEXT: br i1 [[SWITCH]], label [[A:%.*]], label [[B:%.*]] 76; CHECK: a: 77; CHECK-NEXT: [[TMP0:%.*]] = call i32 @f(i32 0) 78; CHECK-NEXT: ret i32 [[TMP0]] 79; CHECK: b: 80; CHECK-NEXT: [[TMP1:%.*]] = call i32 @f(i32 1) 81; CHECK-NEXT: ret i32 [[TMP1]] 82; 83 84entry: 85 ; Note: folding the most popular case destination into the default 86 ; would prevent switch-to-icmp here. 87 switch i32 %x, label %unreachable [ 88 i32 5, label %a 89 i32 6, label %a 90 i32 7, label %a 91 i32 10, label %b 92 i32 20, label %b 93 ] 94unreachable: 95 unreachable 96a: 97 %0 = call i32 @f(i32 0) 98 ret i32 %0 99b: 100 %1 = call i32 @f(i32 1) 101 ret i32 %1 102} 103 104; This would crash because we did not clean up the 105; default block of the switch before removing the switch. 106 107define void @PR42737(i32* %a, i1 %c) { 108; CHECK-LABEL: @PR42737( 109; CHECK-NEXT: entry: 110; CHECK-NEXT: [[TMP0:%.*]] = xor i1 [[C:%.*]], true 111; CHECK-NEXT: call void @llvm.assume(i1 [[TMP0]]) 112; CHECK-NEXT: unreachable 113; 114entry: 115 br i1 %c, label %switch, label %else 116 117else: 118 store i32 2, i32* %a 119 br label %switch 120 121switch: 122 %cleanup.dest1 = phi i32 [ 0, %else ], [ 3, %entry ] 123 switch i32 %cleanup.dest1, label %unreach1 [ 124 i32 0, label %cleanup1 125 i32 3, label %cleanup2 126 ] 127 128cleanup1: 129 br label %unreach2 130 131cleanup2: 132 br label %unreach2 133 134unreach1: 135 %phi2 = phi i32 [ %cleanup.dest1, %switch ] 136 unreachable 137 138unreach2: 139 unreachable 140} 141