Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / Coroutines / coro-catchswitch-cleanuppad.ll
blob2f6d23da8269294ae09934325c850300f1e7d423
1 ; Tests the PHI nodes in cleanuppads for catchswitch instructions are correctly
2 ; split up.
3 ; RUN: opt < %s -passes='cgscc(coro-split),simplifycfg<switch-range-to-icmp>,early-cse' -S | FileCheck %s
5 declare i32 @__CxxFrameHandler3(...)
6 define ptr @f2(i1 %val) presplitcoroutine personality ptr @__CxxFrameHandler3 {
7 entry:
8   %id = call token @llvm.coro.id(i32 0, ptr null, ptr null, ptr null)
9   %valueA = call i32 @f();
10   %valueB = call i32 @f();
11   %need.alloc = call i1 @llvm.coro.alloc(token %id)
12   br i1 %need.alloc, label %dyn.alloc, label %dowork.0
14 dyn.alloc:
15   %size = call i32 @llvm.coro.size.i32()
16   %alloc = call ptr @malloc(i32 %size)
17   br label %dowork.0
19 dowork.0:
20   %phi = phi ptr [ null, %entry ], [ %alloc, %dyn.alloc ]
21   %hdl = call ptr @llvm.coro.begin(token %id, ptr %phi)
22   invoke void @print(i32 0)
23     to label %checksuspend unwind label %catch.dispatch.1
25 checksuspend:
26   %0 = call i8 @llvm.coro.suspend(token none, i1 false)
27   switch i8 %0, label %suspend [i8 0, label %dowork.1
28                                 i8 1, label %cleanup]
30 dowork.1:
31   invoke void @print(i32 0)
32     to label %checksuspend unwind label %catch.dispatch.1
34 cleanup:
35   %mem = call ptr @llvm.coro.free(token %id, ptr %hdl)
36   call void @free(ptr %mem)
37   br label %suspend
39 suspend:
40   call i1 @llvm.coro.end(ptr %hdl, i1 0, token none)
41   ret ptr %hdl
43 catch.dispatch.1:
44   %cs1 = catchswitch within none [label %handler1] unwind to caller
45 handler1:
46   %h1 = catchpad within %cs1 [ptr null, i32 64, ptr null]
47   invoke void @print(i32 2) [ "funclet"(token %h1) ]
48           to label %catchret1 unwind label %catch.dispatch.2
49 catchret1:
50   catchret from %h1 to label %cleanup
52 catch.dispatch.2:
53   %cs2 = catchswitch within %h1 [label %handler2] unwind label %cleanup2
54 handler2:
55   %h2 = catchpad within %cs2 [ptr null, i32 64, ptr null]
56   invoke void @print(i32 3) [ "funclet"(token %h2) ]
57           to label %cleanup unwind label %cleanup2
58 cleanup2:
59   %cleanupval2 = phi i32 [%valueA, %catch.dispatch.2], [%valueB, %handler2]
60   cleanuppad within %h1 []
61   call void @print(i32 %cleanupval2)
62   br label %cleanup
64 ; Verifiers that a "dispatcher" cleanuppad is created.
66 ; catchswitch and all associated catchpads are required to have the same unwind
67 ; edge, but coro requires that PHI nodes are split up so that reload
68 ; instructions can be generated, therefore we create a new "dispatcher"
69 ; cleanuppad which forwards to individual blocks that contain the reload
70 ; instructions per catchswitch/catchpad and then all branch back to the
71 ; original cleanuppad block.
73 ; CHECK: catch.dispatch.2:
74 ; CHECK:   %cs2 = catchswitch within %h1 [label %handler2] unwind label %cleanup2.corodispatch
76 ; CHECK: handler2:
77 ; CHECK:   invoke void @print(i32 3)
78 ; CHECK:           to label %cleanup unwind label %cleanup2.corodispatch
80 ; CHECK: cleanup2.corodispatch:
81 ; CHECK:   %1 = phi i8 [ 0, %handler2 ], [ 1, %catch.dispatch.2 ]
82 ; CHECK:   %2 = cleanuppad within %h1 []
83 ; CHECK:   %switch = icmp ult i8 %1, 1
84 ; CHECK:   br i1 %switch, label %cleanup2.from.handler2, label %cleanup2.from.catch.dispatch.2
86 ; CHECK: cleanup2.from.handler2:
87 ; CHECK:   %valueB.reload = load i32, ptr %valueB.spill.addr, align 4
88 ; CHECK:   br label %cleanup2
90 ; CHECK: cleanup2.from.catch.dispatch.2:
91 ; CHECK:   %valueA.reload = load i32, ptr %valueA.spill.addr, align 4
92 ; CHECK:   br label %cleanup2
94 ; CHECK: cleanup2:
95 ; CHECK:   %cleanupval2 = phi i32 [ %valueA.reload, %cleanup2.from.catch.dispatch.2 ], [ %valueB.reload, %cleanup2.from.handler2 ]
96 ; CHECK:   call void @print(i32 %cleanupval2)
97 ; CHECK:   br label %cleanup
100 declare ptr @llvm.coro.free(token, ptr)
101 declare i32 @llvm.coro.size.i32()
102 declare i8  @llvm.coro.suspend(token, i1)
103 declare void @llvm.coro.resume(ptr)
104 declare void @llvm.coro.destroy(ptr)
106 declare token @llvm.coro.id(i32, ptr, ptr, ptr)
107 declare i1 @llvm.coro.alloc(token)
108 declare ptr @llvm.coro.begin(token, ptr)
109 declare i1 @llvm.coro.end(ptr, i1, token)
111 declare noalias ptr @malloc(i32)
112 declare void @print(i32)
113 declare void @free(ptr)
115 declare i32 @f()