1 ; RUN: opt < %s -simplifycfg -S | FileCheck %s 2 3 define void @test1(i1 %C, i1* %BP) { 4 ; CHECK-LABEL: @test1( 5 ; CHECK: entry: 6 ; CHECK-NEXT: ret void 7 entry: 8 br i1 %C, label %T, label %F 9 T: 10 store i1 %C, i1* %BP 11 unreachable 12 F: 13 ret void 14 } 15 16 define void @test2() personality i32 (...)* @__gxx_personality_v0 { 17 ; CHECK-LABEL: @test2( 18 ; CHECK: entry: 19 ; CHECK-NEXT: call void @test2() 20 ; CHECK-NEXT: ret void 21 entry: 22 invoke void @test2( ) 23 to label %N unwind label %U 24 U: 25 %res = landingpad { i8* } 26 cleanup 27 unreachable 28 N: 29 ret void 30 } 31 32 declare i32 @__gxx_personality_v0(...) 33 34 define i32 @test3(i32 %v) { 35 ; CHECK-LABEL: @test3( 36 ; CHECK: entry: 37 ; CHECK-NEXT: [[CMP:%[A-Za-z0-9]+]] = icmp eq i32 %v, 2 38 ; CHECK-NEXT: select i1 [[CMP]], i32 2, i32 1 39 ; CHECK-NEXT: ret 40 entry: 41 switch i32 %v, label %default [ 42 i32 1, label %U 43 i32 2, label %T 44 ] 45 default: 46 ret i32 1 47 U: 48 unreachable 49 T: 50 ret i32 2 51 } 52 53 54 ;; We can either convert the following control-flow to a select or remove the 55 ;; unreachable control flow because of the undef store of null. Make sure we do 56 ;; the latter. 57 58 define void @test5(i1 %cond, i8* %ptr) { 59 60 ; CHECK-LABEL: test5 61 ; CHECK: entry: 62 ; CHECK-NOT: select 63 ; CHECK: store i8 2, i8* %ptr 64 ; CHECK: ret 65 66 entry: 67 br i1 %cond, label %bb1, label %bb3 68 69 bb3: 70 br label %bb2 71 72 bb1: 73 br label %bb2 74 75 bb2: 76 %ptr.2 = phi i8* [ %ptr, %bb3 ], [ null, %bb1 ] 77 store i8 2, i8* %ptr.2, align 8 78 ret void 79 } 80 81 define void @test5_no_null_opt(i1 %cond, i8* %ptr) #0 { 82 83 ; CHECK-LABEL: test5_no_null_opt 84 ; CHECK: entry: 85 ; CHECK: %[[SEL:.*]] = select i1 %cond, i8* null, i8* %ptr 86 ; CHECK: store i8 2, i8* %[[SEL]] 87 88 entry: 89 br i1 %cond, label %bb1, label %bb3 90 91 bb3: 92 br label %bb2 93 94 bb1: 95 br label %bb2 96 97 bb2: 98 %ptr.2 = phi i8* [ %ptr, %bb3 ], [ null, %bb1 ] 99 store i8 2, i8* %ptr.2, align 8 100 ret void 101 } 102 103 ; CHECK-LABEL: test6 104 ; CHECK: entry: 105 ; CHECK-NOT: select 106 ; CHECK: store i8 2, i8* %ptr 107 ; CHECK: ret 108 109 define void @test6(i1 %cond, i8* %ptr) { 110 entry: 111 br i1 %cond, label %bb1, label %bb2 112 113 bb1: 114 br label %bb2 115 116 bb2: 117 %ptr.2 = phi i8* [ %ptr, %entry ], [ null, %bb1 ] 118 store i8 2, i8* %ptr.2, align 8 119 ret void 120 } 121 122 ; CHECK-LABEL: test6_no_null_opt 123 ; CHECK: entry: 124 ; CHECK: %[[SEL:.*]] = select i1 %cond, i8* null, i8* %ptr 125 ; CHECK: store i8 2, i8* %[[SEL]] 126 127 define void @test6_no_null_opt(i1 %cond, i8* %ptr) #0 { 128 entry: 129 br i1 %cond, label %bb1, label %bb2 130 131 bb1: 132 br label %bb2 133 134 bb2: 135 %ptr.2 = phi i8* [ %ptr, %entry ], [ null, %bb1 ] 136 store i8 2, i8* %ptr.2, align 8 137 ret void 138 } 139 140 141 define i32 @test7(i1 %X) { 142 entry: 143 br i1 %X, label %if, label %else 144 145 if: 146 call void undef() 147 br label %else 148 149 else: 150 %phi = phi i32 [ 0, %entry ], [ 1, %if ] 151 ret i32 %phi 152 } 153 ; CHECK-LABEL: define i32 @test7( 154 ; CHECK-NOT: call 155 ; CHECK: ret i32 0 156 157 define void @test8(i1 %X, void ()* %Y) { 158 entry: 159 br i1 %X, label %if, label %else 160 161 if: 162 br label %else 163 164 else: 165 %phi = phi void ()* [ %Y, %entry ], [ null, %if ] 166 call void %phi() 167 ret void 168 } 169 ; CHECK-LABEL: define void @test8( 170 ; CHECK: call void %Y( 171 172 define void @test8_no_null_opt(i1 %X, void ()* %Y) #0 { 173 entry: 174 br i1 %X, label %if, label %else 175 176 if: 177 br label %else 178 179 else: 180 %phi = phi void ()* [ %Y, %entry ], [ null, %if ] 181 call void %phi() 182 ret void 183 } 184 attributes #0 = { "null-pointer-is-valid"="true" } 185 186 ; CHECK-LABEL: define void @test8_no_null_opt( 187 ; CHECK: %[[SEL:.*]] = select i1 %X, void ()* null, void ()* %Y 188 ; CHECK: call void %[[SEL]] 189