1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s 3target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 4 5declare i32 @__gxx_personality_v0(...) 6declare void @__cxa_call_unexpected(ptr) 7declare void @purefn() nounwind readnone willreturn 8declare i32 @readonly() nounwind readonly 9declare i32 @readonly_willreturn() nounwind readonly willreturn 10declare i32 @nounwind_fn() nounwind 11declare i32 @fn() 12 13 14define ptr @f1() nounwind uwtable ssp personality ptr @__gxx_personality_v0 { 15; CHECK-LABEL: @f1( 16; CHECK-NEXT: entry: 17; CHECK-NEXT: unreachable 18; 19entry: 20 %call = invoke noalias ptr undef() 21 to label %invoke.cont unwind label %lpad 22 23invoke.cont: 24 ret ptr %call 25 26lpad: 27 %0 = landingpad { ptr, i32 } 28 filter [0 x ptr] zeroinitializer 29 %1 = extractvalue { ptr, i32 } %0, 0 30 tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind 31 unreachable 32} 33 34define ptr @f2() nounwind uwtable ssp personality ptr @__gxx_personality_v0 { 35; CHECK-LABEL: @f2( 36; CHECK-NEXT: entry: 37; CHECK-NEXT: unreachable 38; 39entry: 40 %call = invoke noalias ptr null() 41 to label %invoke.cont unwind label %lpad 42 43invoke.cont: 44 ret ptr %call 45 46lpad: 47 %0 = landingpad { ptr, i32 } 48 filter [0 x ptr] zeroinitializer 49 %1 = extractvalue { ptr, i32 } %0, 0 50 tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind 51 unreachable 52} 53 54define ptr @f2_no_null_opt() nounwind uwtable ssp #0 personality ptr @__gxx_personality_v0 { 55; CHECK-LABEL: @f2_no_null_opt( 56; CHECK-NEXT: entry: 57; CHECK-NEXT: [[CALL:%.*]] = invoke noalias ptr null() 58; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 59; CHECK: invoke.cont: 60; CHECK-NEXT: ret ptr [[CALL]] 61; CHECK: lpad: 62; CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } 63; CHECK-NEXT: filter [0 x ptr] zeroinitializer 64; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0 65; CHECK-NEXT: tail call void @__cxa_call_unexpected(ptr [[TMP1]]) #[[ATTR7:[0-9]+]] 66; CHECK-NEXT: unreachable 67; 68entry: 69 %call = invoke noalias ptr null() 70 to label %invoke.cont unwind label %lpad 71 72invoke.cont: 73 ret ptr %call 74 75lpad: 76 %0 = landingpad { ptr, i32 } 77 filter [0 x ptr] zeroinitializer 78 %1 = extractvalue { ptr, i32 } %0, 0 79 tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind 80 unreachable 81} 82 83define i32 @invoke_readonly_may_not_return() nounwind personality ptr @__gxx_personality_v0 { 84; CHECK-LABEL: @invoke_readonly_may_not_return( 85; CHECK-NEXT: entry: 86; CHECK-NEXT: [[CALL:%.*]] = call i32 @readonly() 87; CHECK-NEXT: ret i32 3 88; 89entry: 90 %call = invoke i32 @readonly() 91 to label %invoke.cont unwind label %lpad 92 93invoke.cont: 94 ret i32 3 95 96lpad: 97 %0 = landingpad { ptr, i32 } 98 filter [0 x ptr] zeroinitializer 99 %1 = extractvalue { ptr, i32 } %0, 0 100 tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind 101 unreachable 102} 103 104define i32 @invoke_readonly_willreturn() nounwind personality ptr @__gxx_personality_v0 { 105; CHECK-LABEL: @invoke_readonly_willreturn( 106; CHECK-NEXT: entry: 107; CHECK-NEXT: ret i32 3 108; 109entry: 110 %call = invoke i32 @readonly_willreturn() 111 to label %invoke.cont unwind label %lpad 112 113invoke.cont: 114 ret i32 3 115 116lpad: 117 %0 = landingpad { ptr, i32 } 118 filter [0 x ptr] zeroinitializer 119 %1 = extractvalue { ptr, i32 } %0, 0 120 tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind 121 unreachable 122} 123 124define i32 @invoke_readonly_willreturn_with_used_retval() nounwind personality ptr @__gxx_personality_v0 { 125; CHECK-LABEL: @invoke_readonly_willreturn_with_used_retval( 126; CHECK-NEXT: entry: 127; CHECK-NEXT: [[CALL:%.*]] = call i32 @readonly_willreturn() 128; CHECK-NEXT: ret i32 [[CALL]] 129; 130entry: 131 %call = invoke i32 @readonly_willreturn() 132 to label %invoke.cont unwind label %lpad 133 134invoke.cont: 135 ret i32 %call 136 137lpad: 138 %0 = landingpad { ptr, i32 } 139 filter [0 x ptr] zeroinitializer 140 %1 = extractvalue { ptr, i32 } %0, 0 141 tail call void @__cxa_call_unexpected(ptr %1) noreturn nounwind 142 unreachable 143} 144 145define i32 @f5(i1 %cond, ptr %a, ptr %b) personality ptr @__gxx_personality_v0 { 146; CHECK-LABEL: @f5( 147; CHECK-NEXT: entry: 148; CHECK-NEXT: br i1 [[COND:%.*]], label [[X:%.*]], label [[Y:%.*]] 149; CHECK: x: 150; CHECK-NEXT: [[CALL:%.*]] = invoke i32 @fn() 151; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[LPAD:%.*]] 152; CHECK: y: 153; CHECK-NEXT: [[CALL2:%.*]] = call i32 @nounwind_fn() 154; CHECK-NEXT: br label [[CONT]] 155; CHECK: cont: 156; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[CALL]], [[X]] ], [ [[CALL2]], [[Y]] ] 157; CHECK-NEXT: ret i32 [[PHI]] 158; CHECK: lpad: 159; CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } 160; CHECK-NEXT: filter [0 x ptr] zeroinitializer 161; CHECK-NEXT: tail call void @__cxa_call_unexpected(ptr [[A:%.*]]) #[[ATTR7]] 162; CHECK-NEXT: unreachable 163; 164entry: 165 br i1 %cond, label %x, label %y 166 167x: 168 %call = invoke i32 @fn() 169 to label %cont unwind label %lpad 170 171y: 172 %call2 = invoke i32 @nounwind_fn() 173 to label %cont unwind label %lpad 174 175cont: 176 %phi = phi i32 [%call, %x], [%call2, %y] 177 ret i32 %phi 178 179lpad: 180 %phi2 = phi ptr [%a, %x], [%b, %y] 181 %0 = landingpad { ptr, i32 } 182 filter [0 x ptr] zeroinitializer 183 tail call void @__cxa_call_unexpected(ptr %phi2) noreturn nounwind 184 unreachable 185} 186 187define void @f6() personality ptr @__gxx_personality_v0 { 188; CHECK-LABEL: @f6( 189; CHECK-NEXT: entry: 190; CHECK-NEXT: [[FOO:%.*]] = invoke i32 @fn() 191; CHECK-NEXT: to label [[COMMON_RET:%.*]] unwind label [[LPAD:%.*]] 192; CHECK: common.ret: 193; CHECK-NEXT: ret void 194; CHECK: lpad: 195; CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 } 196; CHECK-NEXT: cleanup 197; CHECK-NEXT: br label [[COMMON_RET]] 198; 199entry: 200 invoke void @purefn() 201 to label %invoke.cont1 unwind label %lpad 202 203invoke.cont1: 204 %foo = invoke i32 @fn() 205 to label %invoke.cont2 unwind label %lpad 206 207invoke.cont2: 208 ret void 209 210lpad: 211 %tmp = phi ptr [ null, %invoke.cont1 ], [ null, %entry ] 212 landingpad { ptr, i32 } 213 cleanup 214 ret void 215} 216 217define void @invoke_of_noreturn() personality ptr @__gxx_personality_v0 { 218; CHECK-LABEL: @invoke_of_noreturn( 219; CHECK-NEXT: entry: 220; CHECK-NEXT: invoke void @simple_throw() 221; CHECK-NEXT: to label [[INVOKE_CONT_UNREACHABLE:%.*]] unwind label [[LPAD:%.*]] 222; CHECK: invoke.cont.unreachable: 223; CHECK-NEXT: unreachable 224; CHECK: lpad: 225; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 } 226; CHECK-NEXT: cleanup 227; CHECK-NEXT: call void @sideeffect(i32 1) 228; CHECK-NEXT: resume { ptr, i32 } [[EH]] 229; 230entry: 231 invoke void @simple_throw() to label %invoke.cont unwind label %lpad 232 233invoke.cont: 234 call void @sideeffect(i32 0) 235 ret void 236 237lpad: 238 %eh = landingpad { ptr, i32 } cleanup 239 call void @sideeffect(i32 1) 240 resume { ptr, i32 } %eh 241} 242 243define void @invoke_of_noreturn_with_shared_normal_destination(i1 %c) personality ptr @__gxx_personality_v0 { 244; CHECK-LABEL: @invoke_of_noreturn_with_shared_normal_destination( 245; CHECK-NEXT: entry: 246; CHECK-NEXT: br i1 [[C:%.*]], label [[INVOKE:%.*]], label [[INVOKE_CONT:%.*]] 247; CHECK: invoke: 248; CHECK-NEXT: invoke void @simple_throw() 249; CHECK-NEXT: to label [[INVOKE_CONT_UNREACHABLE:%.*]] unwind label [[LPAD:%.*]] 250; CHECK: invoke.cont.unreachable: 251; CHECK-NEXT: unreachable 252; CHECK: invoke.cont: 253; CHECK-NEXT: call void @sideeffect(i32 -1) 254; CHECK-NEXT: ret void 255; CHECK: lpad: 256; CHECK-NEXT: [[EH:%.*]] = landingpad { ptr, i32 } 257; CHECK-NEXT: cleanup 258; CHECK-NEXT: call void @sideeffect(i32 1) 259; CHECK-NEXT: resume { ptr, i32 } [[EH]] 260; 261entry: 262 br i1 %c, label %invoke, label %invoke.cont 263 264invoke: 265 invoke void @simple_throw() to label %invoke.cont unwind label %lpad 266 267invoke.cont: 268 %r = phi i32 [ 0, %invoke ], [ -1, %entry ] 269 call void @sideeffect(i32 %r) 270 ret void 271 272lpad: 273 %eh = landingpad { ptr, i32 } cleanup 274 call void @sideeffect(i32 1) 275 resume { ptr, i32 } %eh 276} 277 278define void @invoke_of_nounwind() personality ptr @__gxx_personality_v0 { 279; CHECK-LABEL: @invoke_of_nounwind( 280; CHECK-NEXT: entry: 281; CHECK-NEXT: call void @simple_return() 282; CHECK-NEXT: call void @sideeffect(i32 0) 283; CHECK-NEXT: ret void 284; 285entry: 286 invoke void @simple_return() to label %invoke.cont unwind label %lpad 287 288invoke.cont: 289 call void @sideeffect(i32 0) 290 ret void 291 292lpad: 293 %eh = landingpad { ptr, i32 } cleanup 294 call void @sideeffect(i32 1) 295 resume { ptr, i32 } %eh 296} 297 298declare void @simple_throw() noreturn 299declare void @simple_return() nounwind 300declare void @sideeffect(i32 ) 301 302attributes #0 = { null_pointer_is_valid } 303