1; Verifies that we can insert the spill for a PHI preceding the catchswitch 2; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg,early-cse' -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 7; CHECK-LABEL: define void @f( 8define void @f(i1 %cond) presplitcoroutine personality i32 0 { 9entry: 10 %id = call token @llvm.coro.id(i32 8, ptr null, ptr null, ptr null) 11 %size = call i32 @llvm.coro.size.i32() 12 %alloc = call ptr @malloc(i32 %size) 13 %hdl = call ptr @llvm.coro.begin(token %id, ptr %alloc) 14 br i1 %cond, label %if.else, label %if.then 15 16if.then: 17 invoke void @may_throw1() 18 to label %coro.ret unwind label %catch.dispatch 19 20if.else: 21 invoke void @may_throw2() 22 to label %coro.ret unwind label %catch.dispatch 23 24catch.dispatch: ; preds = %if.else, %if.then 25 %val = phi i32 [ 1, %if.then ], [ 2, %if.else ] 26 %switch = catchswitch within none [label %catch] unwind label %cleanuppad 27 28; Verifies that we split out the PHI into a separate block 29; added a cleanuppad spill cleanupret unwinding into the catchswitch. 30 31; CHECK: catch.dispatch: 32; CHECK: %val = phi i32 [ 2, %if.else ], [ 1, %if.then ] 33; CHECK: %[[Pad:.+]] = cleanuppad within none [] 34; CHECK: %val.spill.addr = getelementptr inbounds %f.Frame, ptr %hdl, i32 0, i32 2 35; CHECK: store i32 %val, ptr %val.spill.addr 36; CHECK: cleanupret from %[[Pad]] unwind label %[[Switch:.+]] 37 38; CHECK: [[Switch]]: 39; CHECK: %switch = catchswitch within none [label %catch] unwind to caller 40 41catch: ; preds = %catch.dispatch 42 %pad = catchpad within %switch [ptr null, i32 64, ptr null] 43 catchret from %pad to label %suspend 44 45suspend: 46 %sp = call i8 @llvm.coro.suspend(token none, i1 false) 47 switch i8 %sp, label %coro.ret [ 48 i8 0, label %resume 49 i8 1, label %coro.ret 50 ] 51 52resume: ; preds = %await2.suspend 53 call void @print(i32 %val) 54 br label %coro.ret 55 56coro.ret: 57 call i1 @llvm.coro.end(ptr %hdl, i1 0, token none) 58 ret void 59 60cleanuppad: 61 %cpad = cleanuppad within none [] 62 cleanupret from %cpad unwind to caller 63} 64 65; Function Attrs: argmemonly nounwind readonly 66declare token @llvm.coro.id(i32, ptr readnone, ptr nocapture readonly, ptr) #1 67 68; Function Attrs: nounwind 69declare i1 @llvm.coro.alloc(token) #2 70 71; Function Attrs: nobuiltin 72declare i32 @llvm.coro.size.i32() #4 73declare ptr @llvm.coro.begin(token, ptr writeonly) #2 74declare token @llvm.coro.save(ptr) 75declare i8 @llvm.coro.suspend(token, i1) 76 77declare void @may_throw1() 78declare void @may_throw2() 79declare void @print(i32) 80declare noalias ptr @malloc(i32) 81declare void @free(ptr) 82 83declare i1 @llvm.coro.end(ptr, i1, token) #2 84 85; Function Attrs: nobuiltin nounwind 86 87; Function Attrs: argmemonly nounwind readonly 88declare ptr @llvm.coro.free(token, ptr nocapture readonly) #1 89