1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -loop-reduce -S | FileCheck %s 3 4target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" 5target triple = "i686-pc-windows-msvc" 6 7declare i32 @_except_handler3(...) 8declare i32 @__CxxFrameHandler3(...) 9 10declare void @external(ptr) 11declare void @reserve() 12 13define void @f() personality ptr @_except_handler3 { 14; CHECK-LABEL: @f( 15; CHECK-NEXT: entry: 16; CHECK-NEXT: br label [[THROW:%.*]] 17; CHECK: throw: 18; CHECK-NEXT: invoke void @reserve() 19; CHECK-NEXT: to label [[THROW]] unwind label [[PAD:%.*]] 20; CHECK: pad: 21; CHECK-NEXT: [[CS:%.*]] = catchswitch within none [label %unreachable] unwind label [[BLAH2:%.*]] 22; CHECK: unreachable: 23; CHECK-NEXT: [[TMP0:%.*]] = catchpad within [[CS]] [] 24; CHECK-NEXT: unreachable 25; CHECK: blah2: 26; CHECK-NEXT: [[CLEANUPPADI4_I_I_I:%.*]] = cleanuppad within none [] 27; CHECK-NEXT: br label [[LOOP_BODY:%.*]] 28; CHECK: loop_body: 29; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[ITER:%.*]] ], [ 0, [[BLAH2]] ] 30; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], -1 31; CHECK-NEXT: [[LSR_IV_NEXT1:%.*]] = inttoptr i32 [[LSR_IV_NEXT]] to ptr 32; CHECK-NEXT: [[TMP100:%.*]] = icmp eq ptr [[LSR_IV_NEXT1]], null 33; CHECK-NEXT: br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]] 34; CHECK: iter: 35; CHECK-NEXT: br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]] 36; CHECK: unwind_out: 37; CHECK-NEXT: cleanupret from [[CLEANUPPADI4_I_I_I]] unwind to caller 38; 39entry: 40 br label %throw 41 42throw: ; preds = %throw, %entry 43 %tmp96 = getelementptr inbounds i8, ptr undef, i32 1 44 invoke void @reserve() 45 to label %throw unwind label %pad 46 47pad: ; preds = %throw 48 %phi2 = phi ptr [ %tmp96, %throw ] 49 %cs = catchswitch within none [label %unreachable] unwind label %blah2 50 51unreachable: 52 catchpad within %cs [] 53 unreachable 54 55blah2: 56 %cleanuppadi4.i.i.i = cleanuppad within none [] 57 br label %loop_body 58 59loop_body: ; preds = %iter, %pad 60 %tmp99 = phi ptr [ %tmp101, %iter ], [ %phi2, %blah2 ] 61 %tmp100 = icmp eq ptr %tmp99, undef 62 br i1 %tmp100, label %unwind_out, label %iter 63 64iter: ; preds = %loop_body 65 %tmp101 = getelementptr inbounds i8, ptr %tmp99, i32 1 66 br i1 true, label %unwind_out, label %loop_body 67 68unwind_out: ; preds = %iter, %loop_body 69 cleanupret from %cleanuppadi4.i.i.i unwind to caller 70} 71 72define void @g() personality ptr @_except_handler3 { 73; CHECK-LABEL: @g( 74; CHECK-NEXT: entry: 75; CHECK-NEXT: br label [[THROW:%.*]] 76; CHECK: throw: 77; CHECK-NEXT: invoke void @reserve() 78; CHECK-NEXT: to label [[THROW]] unwind label [[PAD:%.*]] 79; CHECK: pad: 80; CHECK-NEXT: [[CS:%.*]] = catchswitch within none [label [[UNREACHABLE:%.*]], label %blah] unwind to caller 81; CHECK: unreachable: 82; CHECK-NEXT: [[TMP0:%.*]] = catchpad within [[CS]] [] 83; CHECK-NEXT: unreachable 84; CHECK: blah: 85; CHECK-NEXT: [[CATCHPAD:%.*]] = catchpad within [[CS]] [] 86; CHECK-NEXT: br label [[LOOP_BODY:%.*]] 87; CHECK: unwind_out: 88; CHECK-NEXT: catchret from [[CATCHPAD]] to label [[LEAVE:%.*]] 89; CHECK: leave: 90; CHECK-NEXT: ret void 91; CHECK: loop_body: 92; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[ITER:%.*]] ], [ 0, [[BLAH:%.*]] ] 93; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], -1 94; CHECK-NEXT: [[LSR_IV_NEXT1:%.*]] = inttoptr i32 [[LSR_IV_NEXT]] to ptr 95; CHECK-NEXT: [[TMP100:%.*]] = icmp eq ptr [[LSR_IV_NEXT1]], null 96; CHECK-NEXT: br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]] 97; CHECK: iter: 98; CHECK-NEXT: br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]] 99; 100entry: 101 br label %throw 102 103throw: ; preds = %throw, %entry 104 %tmp96 = getelementptr inbounds i8, ptr undef, i32 1 105 invoke void @reserve() 106 to label %throw unwind label %pad 107 108pad: 109 %phi2 = phi ptr [ %tmp96, %throw ] 110 %cs = catchswitch within none [label %unreachable, label %blah] unwind to caller 111 112unreachable: 113 catchpad within %cs [] 114 unreachable 115 116blah: 117 %catchpad = catchpad within %cs [] 118 br label %loop_body 119 120unwind_out: 121 catchret from %catchpad to label %leave 122 123leave: 124 ret void 125 126loop_body: ; preds = %iter, %pad 127 %tmp99 = phi ptr [ %tmp101, %iter ], [ %phi2, %blah ] 128 %tmp100 = icmp eq ptr %tmp99, undef 129 br i1 %tmp100, label %unwind_out, label %iter 130 131iter: ; preds = %loop_body 132 %tmp101 = getelementptr inbounds i8, ptr %tmp99, i32 1 133 br i1 true, label %unwind_out, label %loop_body 134} 135 136define void @h() personality ptr @_except_handler3 { 137; CHECK-LABEL: @h( 138; CHECK-NEXT: entry: 139; CHECK-NEXT: br label [[THROW:%.*]] 140; CHECK: throw: 141; CHECK-NEXT: invoke void @reserve() 142; CHECK-NEXT: to label [[THROW]] unwind label [[PAD:%.*]] 143; CHECK: pad: 144; CHECK-NEXT: [[CS:%.*]] = catchswitch within none [label [[UNREACHABLE:%.*]], label %blug] unwind to caller 145; CHECK: unreachable: 146; CHECK-NEXT: [[TMP0:%.*]] = catchpad within [[CS]] [] 147; CHECK-NEXT: unreachable 148; CHECK: blug: 149; CHECK-NEXT: [[CATCHPAD:%.*]] = catchpad within [[CS]] [] 150; CHECK-NEXT: br label [[LOOP_BODY:%.*]] 151; CHECK: unwind_out: 152; CHECK-NEXT: catchret from [[CATCHPAD]] to label [[LEAVE:%.*]] 153; CHECK: leave: 154; CHECK-NEXT: ret void 155; CHECK: loop_body: 156; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[ITER:%.*]] ], [ 0, [[BLUG:%.*]] ] 157; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], -1 158; CHECK-NEXT: [[LSR_IV_NEXT1:%.*]] = inttoptr i32 [[LSR_IV_NEXT]] to ptr 159; CHECK-NEXT: [[TMP100:%.*]] = icmp eq ptr [[LSR_IV_NEXT1]], null 160; CHECK-NEXT: br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]] 161; CHECK: iter: 162; CHECK-NEXT: br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]] 163; 164entry: 165 br label %throw 166 167throw: ; preds = %throw, %entry 168 %tmp96 = getelementptr inbounds i8, ptr undef, i32 1 169 invoke void @reserve() 170 to label %throw unwind label %pad 171 172pad: 173 %cs = catchswitch within none [label %unreachable, label %blug] unwind to caller 174 175unreachable: 176 catchpad within %cs [] 177 unreachable 178 179blug: 180 %phi2 = phi ptr [ %tmp96, %pad ] 181 %catchpad = catchpad within %cs [] 182 br label %loop_body 183 184unwind_out: 185 catchret from %catchpad to label %leave 186 187leave: 188 ret void 189 190loop_body: ; preds = %iter, %pad 191 %tmp99 = phi ptr [ %tmp101, %iter ], [ %phi2, %blug ] 192 %tmp100 = icmp eq ptr %tmp99, undef 193 br i1 %tmp100, label %unwind_out, label %iter 194 195iter: ; preds = %loop_body 196 %tmp101 = getelementptr inbounds i8, ptr %tmp99, i32 1 197 br i1 true, label %unwind_out, label %loop_body 198} 199 200define void @i() personality ptr @_except_handler3 { 201; CHECK-LABEL: @i( 202; CHECK-NEXT: entry: 203; CHECK-NEXT: br label [[THROW:%.*]] 204; CHECK: throw: 205; CHECK-NEXT: invoke void @reserve() 206; CHECK-NEXT: to label [[THROW]] unwind label [[CATCHPAD:%.*]] 207; CHECK: catchpad: 208; CHECK-NEXT: [[CS:%.*]] = catchswitch within none [label %cp_body] unwind label [[CLEANUPPAD:%.*]] 209; CHECK: cp_body: 210; CHECK-NEXT: [[TMP0:%.*]] = catchpad within [[CS]] [] 211; CHECK-NEXT: br label [[LOOP_HEAD:%.*]] 212; CHECK: cleanuppad: 213; CHECK-NEXT: [[TMP1:%.*]] = cleanuppad within none [] 214; CHECK-NEXT: br label [[LOOP_HEAD]] 215; CHECK: loop_head: 216; CHECK-NEXT: br label [[LOOP_BODY:%.*]] 217; CHECK: loop_body: 218; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], [[ITER:%.*]] ], [ 0, [[LOOP_HEAD]] ] 219; CHECK-NEXT: [[LSR_IV_NEXT]] = add nuw nsw i32 [[LSR_IV]], -1 220; CHECK-NEXT: [[LSR_IV_NEXT1:%.*]] = inttoptr i32 [[LSR_IV_NEXT]] to ptr 221; CHECK-NEXT: [[TMP100:%.*]] = icmp eq ptr [[LSR_IV_NEXT1]], null 222; CHECK-NEXT: br i1 [[TMP100]], label [[UNWIND_OUT:%.*]], label [[ITER]] 223; CHECK: iter: 224; CHECK-NEXT: br i1 true, label [[UNWIND_OUT]], label [[LOOP_BODY]] 225; CHECK: unwind_out: 226; CHECK-NEXT: unreachable 227; 228entry: 229 br label %throw 230 231throw: ; preds = %throw, %entry 232 %tmp96 = getelementptr inbounds i8, ptr undef, i32 1 233 invoke void @reserve() 234 to label %throw unwind label %catchpad 235 236catchpad: ; preds = %throw 237 %phi2 = phi ptr [ %tmp96, %throw ] 238 %cs = catchswitch within none [label %cp_body] unwind label %cleanuppad 239 240cp_body: 241 catchpad within %cs [] 242 br label %loop_head 243 244cleanuppad: 245 cleanuppad within none [] 246 br label %loop_head 247 248loop_head: 249 br label %loop_body 250 251loop_body: ; preds = %iter, %catchpad 252 %tmp99 = phi ptr [ %tmp101, %iter ], [ %phi2, %loop_head ] 253 %tmp100 = icmp eq ptr %tmp99, undef 254 br i1 %tmp100, label %unwind_out, label %iter 255 256iter: ; preds = %loop_body 257 %tmp101 = getelementptr inbounds i8, ptr %tmp99, i32 1 258 br i1 true, label %unwind_out, label %loop_body 259 260unwind_out: ; preds = %iter, %loop_body 261 unreachable 262} 263 264define void @test1(ptr %b, ptr %c) personality ptr @__CxxFrameHandler3 { 265; CHECK-LABEL: @test1( 266; CHECK-NEXT: entry: 267; CHECK-NEXT: br label [[FOR_COND:%.*]] 268; CHECK: for.cond: 269; CHECK-NEXT: [[D_0:%.*]] = phi ptr [ [[B:%.*]], [[ENTRY:%.*]] ], [ [[INCDEC_PTR:%.*]], [[FOR_INC:%.*]] ] 270; CHECK-NEXT: invoke void @external(ptr [[D_0]]) 271; CHECK-NEXT: to label [[FOR_INC]] unwind label [[CATCH_DISPATCH:%.*]] 272; CHECK: for.inc: 273; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i32, ptr [[D_0]], i32 1 274; CHECK-NEXT: br label [[FOR_COND]] 275; CHECK: catch.dispatch: 276; CHECK-NEXT: [[CS:%.*]] = catchswitch within none [label %catch] unwind label [[CATCH_DISPATCH_2:%.*]] 277; CHECK: catch: 278; CHECK-NEXT: [[TMP0:%.*]] = catchpad within [[CS]] [ptr null, i32 64, ptr null] 279; CHECK-NEXT: catchret from [[TMP0]] to label [[TRY_CONT:%.*]] 280; CHECK: try.cont: 281; CHECK-NEXT: invoke void @external(ptr [[C:%.*]]) 282; CHECK-NEXT: to label [[TRY_CONT_7:%.*]] unwind label [[CATCH_DISPATCH_2]] 283; CHECK: catch.dispatch.2: 284; CHECK-NEXT: [[E_0:%.*]] = phi ptr [ [[C]], [[TRY_CONT]] ], [ [[B]], [[CATCH_DISPATCH]] ] 285; CHECK-NEXT: [[CS2:%.*]] = catchswitch within none [label %catch.4] unwind to caller 286; CHECK: catch.4: 287; CHECK-NEXT: [[TMP1:%.*]] = catchpad within [[CS2]] [ptr null, i32 64, ptr null] 288; CHECK-NEXT: unreachable 289; CHECK: try.cont.7: 290; CHECK-NEXT: ret void 291; 292entry: 293 br label %for.cond 294 295for.cond: ; preds = %for.inc, %entry 296 %d.0 = phi ptr [ %b, %entry ], [ %incdec.ptr, %for.inc ] 297 invoke void @external(ptr %d.0) 298 to label %for.inc unwind label %catch.dispatch 299 300for.inc: ; preds = %for.cond 301 %incdec.ptr = getelementptr inbounds i32, ptr %d.0, i32 1 302 br label %for.cond 303 304catch.dispatch: ; preds = %for.cond 305 %cs = catchswitch within none [label %catch] unwind label %catch.dispatch.2 306 307catch: ; preds = %catch.dispatch 308 %0 = catchpad within %cs [ptr null, i32 64, ptr null] 309 catchret from %0 to label %try.cont 310 311try.cont: ; preds = %catch 312 invoke void @external(ptr %c) 313 to label %try.cont.7 unwind label %catch.dispatch.2 314 315catch.dispatch.2: ; preds = %try.cont, %catchendblock 316 %e.0 = phi ptr [ %c, %try.cont ], [ %b, %catch.dispatch ] 317 %cs2 = catchswitch within none [label %catch.4] unwind to caller 318 319catch.4: ; preds = %catch.dispatch.2 320 catchpad within %cs2 [ptr null, i32 64, ptr null] 321 unreachable 322 323try.cont.7: ; preds = %try.cont 324 ret void 325} 326 327define i32 @test2() personality ptr @_except_handler3 { 328; CHECK-LABEL: @test2( 329; CHECK-NEXT: entry: 330; CHECK-NEXT: br label [[FOR_BODY:%.*]] 331; CHECK: for.body: 332; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ [[INC:%.*]], [[FOR_INC:%.*]] ], [ 0, [[ENTRY:%.*]] ] 333; CHECK-NEXT: invoke void @reserve() 334; CHECK-NEXT: to label [[FOR_INC]] unwind label [[CATCH_DISPATCH:%.*]] 335; CHECK: catch.dispatch: 336; CHECK-NEXT: [[TMP18:%.*]] = catchswitch within none [label %catch.handler] unwind to caller 337; CHECK: catch.handler: 338; CHECK-NEXT: [[PHI_LCSSA:%.*]] = phi i32 [ [[PHI]], [[CATCH_DISPATCH]] ] 339; CHECK-NEXT: [[TMP19:%.*]] = catchpad within [[TMP18]] [ptr null] 340; CHECK-NEXT: catchret from [[TMP19]] to label [[DONE:%.*]] 341; CHECK: done: 342; CHECK-NEXT: ret i32 [[PHI_LCSSA]] 343; CHECK: for.inc: 344; CHECK-NEXT: [[INC]] = add i32 [[PHI]], 1 345; CHECK-NEXT: br label [[FOR_BODY]] 346; 347entry: 348 br label %for.body 349 350for.body: ; preds = %for.inc, %entry 351 %phi = phi i32 [ %inc, %for.inc ], [ 0, %entry ] 352 invoke void @reserve() 353 to label %for.inc unwind label %catch.dispatch 354 355catch.dispatch: ; preds = %for.body 356 %tmp18 = catchswitch within none [label %catch.handler] unwind to caller 357 358catch.handler: ; preds = %catch.dispatch 359 %phi.lcssa = phi i32 [ %phi, %catch.dispatch ] 360 %tmp19 = catchpad within %tmp18 [ptr null] 361 catchret from %tmp19 to label %done 362 363done: 364 ret i32 %phi.lcssa 365 366for.inc: ; preds = %for.body 367 %inc = add i32 %phi, 1 368 br label %for.body 369} 370