1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals 2; RUN: opt -S -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 < %s | FileCheck %s 3 4declare void @Personality() 5declare void @f() 6 7define void @test1() personality ptr @Personality { 8; CHECK-LABEL: @test1( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: call void @f() #[[ATTR0:[0-9]+]] 11; CHECK-NEXT: ret void 12; 13entry: 14 invoke void @f() 15 to label %exit unwind label %unreachable.unwind 16exit: 17 ret void 18unreachable.unwind: 19 cleanuppad within none [] 20 unreachable 21} 22 23define void @test2() personality ptr @Personality { 24; CHECK-LABEL: @test2( 25; CHECK-NEXT: entry: 26; CHECK-NEXT: invoke void @f() 27; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]] 28; CHECK: catch.pad: 29; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label %catch.body] unwind to caller 30; CHECK: catch.body: 31; CHECK-NEXT: [[CATCH:%.*]] = catchpad within [[CS1]] [] 32; CHECK-NEXT: call void @f() 33; CHECK-NEXT: catchret from [[CATCH]] to label [[UNREACHABLE:%.*]] 34; CHECK: exit: 35; CHECK-NEXT: ret void 36; CHECK: unreachable: 37; CHECK-NEXT: unreachable 38; 39entry: 40 invoke void @f() 41 to label %exit unwind label %catch.pad 42catch.pad: 43 %cs1 = catchswitch within none [label %catch.body] unwind label %unreachable.unwind 44catch.body: 45 %catch = catchpad within %cs1 [] 46 call void @f() 47 catchret from %catch to label %unreachable 48exit: 49 ret void 50unreachable.unwind: 51 cleanuppad within none [] 52 unreachable 53unreachable: 54 unreachable 55} 56 57define void @test3() personality ptr @Personality { 58; CHECK-LABEL: @test3( 59; CHECK-NEXT: entry: 60; CHECK-NEXT: invoke void @f() 61; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[CLEANUP_PAD:%.*]] 62; CHECK: cleanup.pad: 63; CHECK-NEXT: [[CLEANUP:%.*]] = cleanuppad within none [] 64; CHECK-NEXT: call void @f() #[[ATTR0]] 65; CHECK-NEXT: unreachable 66; CHECK: exit: 67; CHECK-NEXT: ret void 68; 69entry: 70 invoke void @f() 71 to label %exit unwind label %cleanup.pad 72cleanup.pad: 73 %cleanup = cleanuppad within none [] 74 invoke void @f() 75 to label %cleanup.ret unwind label %unreachable.unwind 76cleanup.ret: 77 ; This cleanupret should be rewritten to unreachable, 78 ; and merged into the pred block. 79 cleanupret from %cleanup unwind label %unreachable.unwind 80exit: 81 ret void 82unreachable.unwind: 83 cleanuppad within none [] 84 unreachable 85} 86 87define void @test5() personality ptr @Personality { 88; CHECK-LABEL: @test5( 89; CHECK-NEXT: entry: 90; CHECK-NEXT: invoke void @f() 91; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]] 92; CHECK: catch.pad: 93; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label %catch.body] unwind to caller 94; CHECK: catch.body: 95; CHECK-NEXT: [[CATCH:%.*]] = catchpad within [[CS1]] [] 96; CHECK-NEXT: catchret from [[CATCH]] to label [[EXIT]] 97; CHECK: exit: 98; CHECK-NEXT: unreachable 99; 100entry: 101 invoke void @f() 102 to label %exit unwind label %catch.pad 103 104catch.pad: 105 %cs1 = catchswitch within none [label %catch.body] unwind to caller 106 107catch.body: 108 %catch = catchpad within %cs1 [] 109 catchret from %catch to label %exit 110 111exit: 112 unreachable 113} 114 115define void @test6() personality ptr @Personality { 116; CHECK-LABEL: @test6( 117; CHECK-NEXT: entry: 118; CHECK-NEXT: invoke void @f() 119; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]] 120; CHECK: catch.pad: 121; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label %catch.body] unwind to caller 122; CHECK: catch.body: 123; CHECK-NEXT: [[CATCH:%.*]] = catchpad within [[CS1]] [ptr null, i32 0, ptr null] 124; CHECK-NEXT: catchret from [[CATCH]] to label [[EXIT]] 125; CHECK: exit: 126; CHECK-NEXT: ret void 127; 128entry: 129 invoke void @f() 130 to label %exit unwind label %catch.pad 131 132catch.pad: 133 %cs1 = catchswitch within none [label %catch.body, label %catch.body] unwind to caller 134 135catch.body: 136 %catch = catchpad within %cs1 [ptr null, i32 0, ptr null] 137 catchret from %catch to label %exit 138 139exit: 140 ret void 141} 142 143define void @test7() personality ptr @Personality { 144; CHECK-LABEL: @test7( 145; CHECK-NEXT: entry: 146; CHECK-NEXT: invoke void @f() 147; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]] 148; CHECK: catch.pad: 149; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label %catch.body] unwind to caller 150; CHECK: catch.body: 151; CHECK-NEXT: [[CATCH:%.*]] = catchpad within [[CS1]] [ptr null, i32 0, ptr null] 152; CHECK-NEXT: catchret from [[CATCH]] to label [[EXIT]] 153; CHECK: exit: 154; CHECK-NEXT: ret void 155; 156entry: 157 invoke void @f() 158 to label %exit unwind label %catch.pad 159 160catch.pad: 161 %cs1 = catchswitch within none [label %catch.body, label %catch.body2] unwind to caller 162 163catch.body: 164 %catch = catchpad within %cs1 [ptr null, i32 0, ptr null] 165 catchret from %catch to label %exit 166 167catch.body2: 168 %catch2 = catchpad within %cs1 [ptr null, i32 0, ptr null] 169 catchret from %catch2 to label %exit 170 171exit: 172 ret void 173} 174 175define void @test8() personality ptr @Personality { 176; CHECK-LABEL: @test8( 177; CHECK-NEXT: entry: 178; CHECK-NEXT: invoke void @f() 179; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]] 180; CHECK: catch.pad: 181; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label %catch.body] unwind to caller 182; CHECK: catch.body: 183; CHECK-NEXT: [[CATCH:%.*]] = catchpad within [[CS1]] [ptr null, i32 0, ptr null] 184; CHECK-NEXT: catchret from [[CATCH]] to label [[EXIT]] 185; CHECK: exit: 186; CHECK-NEXT: ret void 187; 188entry: 189 invoke void @f() 190 to label %exit unwind label %catch.pad 191 192catch.pad: 193 %cs1 = catchswitch within none [label %catch.body, label %catch.body2] unwind to caller 194 195catch.body2: 196 %catch2 = catchpad within %cs1 [ptr null, i32 0, ptr null] 197 catchret from %catch2 to label %exit 198 199catch.body: 200 %catch = catchpad within %cs1 [ptr null, i32 0, ptr null] 201 catchret from %catch to label %exit 202 203exit: 204 ret void 205} 206 207define void @test9() personality ptr @Personality { 208; CHECK-LABEL: @test9( 209; CHECK-NEXT: entry: 210; CHECK-NEXT: invoke void @f() 211; CHECK-NEXT: to label [[EXIT:%.*]] unwind label [[CATCH_PAD:%.*]] 212; CHECK: catch.pad: 213; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label [[CATCH_BODY:%.*]], label %catch.body2] unwind to caller 214; CHECK: catch.body: 215; CHECK-NEXT: [[CATCH:%.*]] = catchpad within [[CS1]] [ptr null, i32 0, ptr null] 216; CHECK-NEXT: catchret from [[CATCH]] to label [[EXIT]] 217; CHECK: catch.body2: 218; CHECK-NEXT: [[CATCH2:%.*]] = catchpad within [[CS1]] [ptr null, i32 64, ptr null] 219; CHECK-NEXT: catchret from [[CATCH2]] to label [[EXIT]] 220; CHECK: exit: 221; CHECK-NEXT: ret void 222; 223entry: 224 invoke void @f() 225 to label %exit unwind label %catch.pad 226 227catch.pad: 228 %cs1 = catchswitch within none [label %catch.body, label %catch.body2] unwind to caller 229 230catch.body: 231 %catch = catchpad within %cs1 [ptr null, i32 0, ptr null] 232 catchret from %catch to label %exit 233 234catch.body2: 235 %catch2 = catchpad within %cs1 [ptr null, i32 64, ptr null] 236 catchret from %catch2 to label %exit 237 238exit: 239 ret void 240} 241;. 242; CHECK: attributes #[[ATTR0]] = { nounwind } 243;. 244