1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -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(i8*) 7declare void @purefn() nounwind readnone 8declare i32 @read_only() nounwind readonly 9declare i32 @nounwind_fn() nounwind 10declare i32 @fn() 11 12 13define i8* @f1() nounwind uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 14; CHECK-LABEL: @f1( 15; CHECK-NEXT: entry: 16; CHECK-NEXT: unreachable 17; 18entry: 19 %call = invoke noalias i8* undef() 20 to label %invoke.cont unwind label %lpad 21 22invoke.cont: 23 ret i8* %call 24 25lpad: 26 %0 = landingpad { i8*, i32 } 27 filter [0 x i8*] zeroinitializer 28 %1 = extractvalue { i8*, i32 } %0, 0 29 tail call void @__cxa_call_unexpected(i8* %1) noreturn nounwind 30 unreachable 31} 32 33define i8* @f2() nounwind uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 34; CHECK-LABEL: @f2( 35; CHECK-NEXT: entry: 36; CHECK-NEXT: unreachable 37; 38entry: 39 %call = invoke noalias i8* null() 40 to label %invoke.cont unwind label %lpad 41 42invoke.cont: 43 ret i8* %call 44 45lpad: 46 %0 = landingpad { i8*, i32 } 47 filter [0 x i8*] zeroinitializer 48 %1 = extractvalue { i8*, i32 } %0, 0 49 tail call void @__cxa_call_unexpected(i8* %1) noreturn nounwind 50 unreachable 51} 52 53define i8* @f2_no_null_opt() nounwind uwtable ssp #0 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 54; CHECK-LABEL: @f2_no_null_opt( 55; CHECK-NEXT: entry: 56; CHECK-NEXT: [[CALL:%.*]] = invoke noalias i8* null() 57; CHECK-NEXT: to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]] 58; CHECK: invoke.cont: 59; CHECK-NEXT: ret i8* [[CALL]] 60; CHECK: lpad: 61; CHECK-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 } 62; CHECK-NEXT: filter [0 x i8*] zeroinitializer 63; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i8*, i32 } [[TMP0]], 0 64; CHECK-NEXT: tail call void @__cxa_call_unexpected(i8* [[TMP1]]) #[[ATTR5:[0-9]+]] 65; CHECK-NEXT: unreachable 66; 67entry: 68 %call = invoke noalias i8* null() 69 to label %invoke.cont unwind label %lpad 70 71invoke.cont: 72 ret i8* %call 73 74lpad: 75 %0 = landingpad { i8*, i32 } 76 filter [0 x i8*] zeroinitializer 77 %1 = extractvalue { i8*, i32 } %0, 0 78 tail call void @__cxa_call_unexpected(i8* %1) noreturn nounwind 79 unreachable 80} 81 82define i32 @f3() nounwind uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 83; CHECK-LABEL: @f3( 84; CHECK-NEXT: entry: 85; CHECK-NEXT: ret i32 3 86; 87entry: 88 %call = invoke i32 @read_only() 89 to label %invoke.cont unwind label %lpad 90 91invoke.cont: 92 ret i32 3 93 94lpad: 95 %0 = landingpad { i8*, i32 } 96 filter [0 x i8*] zeroinitializer 97 %1 = extractvalue { i8*, i32 } %0, 0 98 tail call void @__cxa_call_unexpected(i8* %1) noreturn nounwind 99 unreachable 100} 101 102define i32 @f4() nounwind uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 103; CHECK-LABEL: @f4( 104; CHECK-NEXT: entry: 105; CHECK-NEXT: [[CALL:%.*]] = call i32 @read_only() 106; CHECK-NEXT: ret i32 [[CALL]] 107; 108entry: 109 %call = invoke i32 @read_only() 110 to label %invoke.cont unwind label %lpad 111 112invoke.cont: 113 ret i32 %call 114 115lpad: 116 %0 = landingpad { i8*, i32 } 117 filter [0 x i8*] zeroinitializer 118 %1 = extractvalue { i8*, i32 } %0, 0 119 tail call void @__cxa_call_unexpected(i8* %1) noreturn nounwind 120 unreachable 121} 122 123define i32 @f5(i1 %cond, i8* %a, i8* %b) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 124; CHECK-LABEL: @f5( 125; CHECK-NEXT: entry: 126; CHECK-NEXT: br i1 [[COND:%.*]], label [[X:%.*]], label [[Y:%.*]] 127; CHECK: x: 128; CHECK-NEXT: [[CALL:%.*]] = invoke i32 @fn() 129; CHECK-NEXT: to label [[CONT:%.*]] unwind label [[LPAD:%.*]] 130; CHECK: y: 131; CHECK-NEXT: [[CALL2:%.*]] = call i32 @nounwind_fn() 132; CHECK-NEXT: br label [[CONT]] 133; CHECK: cont: 134; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[CALL]], [[X]] ], [ [[CALL2]], [[Y]] ] 135; CHECK-NEXT: ret i32 [[PHI]] 136; CHECK: lpad: 137; CHECK-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 } 138; CHECK-NEXT: filter [0 x i8*] zeroinitializer 139; CHECK-NEXT: tail call void @__cxa_call_unexpected(i8* [[A:%.*]]) #[[ATTR5]] 140; CHECK-NEXT: unreachable 141; 142entry: 143 br i1 %cond, label %x, label %y 144 145x: 146 %call = invoke i32 @fn() 147 to label %cont unwind label %lpad 148 149y: 150 %call2 = invoke i32 @nounwind_fn() 151 to label %cont unwind label %lpad 152 153cont: 154 %phi = phi i32 [%call, %x], [%call2, %y] 155 ret i32 %phi 156 157lpad: 158 %phi2 = phi i8* [%a, %x], [%b, %y] 159 %0 = landingpad { i8*, i32 } 160 filter [0 x i8*] zeroinitializer 161 tail call void @__cxa_call_unexpected(i8* %phi2) noreturn nounwind 162 unreachable 163} 164 165define void @f6() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 166; CHECK-LABEL: @f6( 167; CHECK-NEXT: entry: 168; CHECK-NEXT: [[FOO:%.*]] = invoke i32 @fn() 169; CHECK-NEXT: to label [[COMMON_RET:%.*]] unwind label [[LPAD:%.*]] 170; CHECK: common.ret: 171; CHECK-NEXT: ret void 172; CHECK: lpad: 173; CHECK-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 } 174; CHECK-NEXT: cleanup 175; CHECK-NEXT: br label [[COMMON_RET]] 176; 177entry: 178 invoke void @purefn() 179 to label %invoke.cont1 unwind label %lpad 180 181invoke.cont1: 182 %foo = invoke i32 @fn() 183 to label %invoke.cont2 unwind label %lpad 184 185invoke.cont2: 186 ret void 187 188lpad: 189 %tmp = phi i8* [ null, %invoke.cont1 ], [ null, %entry ] 190 landingpad { i8*, i32 } 191 cleanup 192 ret void 193} 194 195attributes #0 = { null_pointer_is_valid } 196