xref: /llvm-project/llvm/test/Transforms/SimplifyCFG/tail-merge-resume.ll (revision 07b9d231ff9baa6473b0dd588a3ce5330d3e4871)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=simplifycfg -simplifycfg-require-and-preserve-domtree=1 -sink-common-insts  -S < %s | FileCheck %s
3
4; Test that we tail merge resume blocks and phi operands properly.
5
6declare void @maybe_throws()
7declare void @foo()
8declare void @bar()
9declare void @baz()
10declare void @qux()
11declare void @quux()
12declare void @quuz()
13declare void @common()
14
15define void @merge_simple(i1 %cond) personality ptr @__gxx_personality_v0 {
16; CHECK-LABEL: @merge_simple(
17; CHECK-NEXT:    invoke void @maybe_throws()
18; CHECK-NEXT:            to label [[INVOKE_CONT:%.*]] unwind label [[LPAD:%.*]]
19; CHECK:       invoke.cont:
20; CHECK-NEXT:    invoke void @maybe_throws()
21; CHECK-NEXT:            to label [[INVOKE_CONT2:%.*]] unwind label [[LPAD2:%.*]]
22; CHECK:       invoke.cont2:
23; CHECK-NEXT:    invoke void @maybe_throws()
24; CHECK-NEXT:            to label [[INVOKE_CONT3:%.*]] unwind label [[LPAD3:%.*]]
25; CHECK:       invoke.cont3:
26; CHECK-NEXT:    ret void
27; CHECK:       lpad:
28; CHECK-NEXT:    [[LP:%.*]] = landingpad { ptr, i32 }
29; CHECK-NEXT:            cleanup
30; CHECK-NEXT:    call void @foo()
31; CHECK-NEXT:    br i1 [[COND:%.*]], label [[RESUME0:%.*]], label [[RESUME1:%.*]]
32; CHECK:       lpad2:
33; CHECK-NEXT:    [[LP2:%.*]] = landingpad { ptr, i32 }
34; CHECK-NEXT:            cleanup
35; CHECK-NEXT:    call void @bar()
36; CHECK-NEXT:    br label [[RESUME2:%.*]]
37; CHECK:       lpad3:
38; CHECK-NEXT:    [[LP3:%.*]] = landingpad { ptr, i32 }
39; CHECK-NEXT:            cleanup
40; CHECK-NEXT:    call void @baz()
41; CHECK-NEXT:    br label [[RESUME2]]
42; CHECK:       common.resume:
43; CHECK-NEXT:    [[COMMON_RESUME_OP:%.*]] = phi { ptr, i32 } [ [[LP]], [[RESUME0]] ], [ [[LP]], [[RESUME1]] ], [ [[SEMICOMMON_LP:%.*]], [[RESUME2]] ]
44; CHECK-NEXT:    call void @common()
45; CHECK-NEXT:    resume { ptr, i32 } [[COMMON_RESUME_OP]]
46; CHECK:       resume0:
47; CHECK-NEXT:    call void @qux()
48; CHECK-NEXT:    br label [[COMMON_RESUME:%.*]]
49; CHECK:       resume1:
50; CHECK-NEXT:    call void @quux()
51; CHECK-NEXT:    br label [[COMMON_RESUME]]
52; CHECK:       resume2:
53; CHECK-NEXT:    [[SEMICOMMON_LP]] = phi { ptr, i32 } [ [[LP2]], [[LPAD2]] ], [ [[LP3]], [[LPAD3]] ]
54; CHECK-NEXT:    call void @quuz()
55; CHECK-NEXT:    br label [[COMMON_RESUME]]
56;
57  invoke void @maybe_throws() to label %invoke.cont unwind label %lpad
58
59invoke.cont:
60  invoke void @maybe_throws() to label %invoke.cont2 unwind label %lpad2
61
62invoke.cont2:
63  invoke void @maybe_throws() to label %invoke.cont3 unwind label %lpad3
64
65invoke.cont3:
66  ret void
67
68lpad:
69  %lp = landingpad { ptr, i32 } cleanup
70  call void @foo()
71  br i1 %cond, label %resume0, label %resume1
72
73lpad2:
74  %lp2 = landingpad { ptr, i32 } cleanup
75  call void @bar()
76  br label %resume2
77
78lpad3:
79  %lp3 = landingpad { ptr, i32 } cleanup
80  call void @baz()
81  br label %resume2
82
83resume0:
84  call void @qux()
85  call void @common()
86  resume { ptr, i32 } %lp
87
88resume1:
89  call void @quux()
90  call void @common()
91  resume { ptr, i32 } %lp
92
93resume2:
94  %semicommon.lp = phi { ptr, i32 } [ %lp2, %lpad2 ], [ %lp3, %lpad3 ]
95  call void @quuz()
96  call void @common()
97  resume { ptr, i32 } %semicommon.lp
98}
99
100declare dso_local i32 @__gxx_personality_v0(...)
101