Move branch folding test to a better location.
[oota-llvm.git] / test / CodeGen / X86 / branchfolding-catchpads.ll
1 ; RUN: llc -mtriple=x86_64-pc-windows-msvc < %s | FileCheck %s
2
3 declare i32 @__CxxFrameHandler3(...)
4
5 declare void @throw()
6 declare i16 @f()
7
8 define i16 @test1(i16 %a, i8* %b) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
9 entry:
10   %cmp = icmp eq i16 %a, 10
11   br i1 %cmp, label %if.then, label %if.else
12
13 if.then:
14   %call1 = invoke i16 @f()
15           to label %cleanup unwind label %catch.dispatch
16
17 if.else:
18   %call2 = invoke i16 @f()
19           to label %cleanup unwind label %catch.dispatch
20
21 catch.dispatch:
22   catchpad [i8* null, i32 8, i8* null]
23           to label %catch unwind label %catch.dispatch.2
24
25 catch:
26   invoke void @throw() noreturn
27           to label %unreachable unwind label %catchendblock
28
29 catch.dispatch.2:
30   catchpad [i8* null, i32 64, i8* null]
31           to label %catch.2 unwind label %catchendblock
32
33 catch.2:
34   store i8 1, i8* %b
35   invoke void @throw() noreturn
36           to label %unreachable unwind label %catchendblock
37
38 catchendblock:
39   catchendpad unwind to caller
40
41 cleanup:
42   %retval = phi i16 [ %call1, %if.then ], [ %call2, %if.else ]
43   ret i16 %retval
44
45 unreachable:
46   unreachable
47 }
48
49 ; This test verifies the case where two funclet blocks meet the old criteria
50 ; to be placed at the end.  The order of the blocks is not important for the
51 ; purposes of this test.  The failure mode is an infinite loop during
52 ; compilation.
53 ;
54 ; CHECK-LABEL: .def     test1;
55
56 define i16 @test2(i16 %a, i8* %b) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
57 entry:
58   %cmp = icmp eq i16 %a, 10
59   br i1 %cmp, label %if.then, label %if.else
60
61 if.then:
62   %call1 = invoke i16 @f()
63           to label %cleanup unwind label %catch.dispatch
64
65 if.else:
66   %call2 = invoke i16 @f()
67           to label %cleanup unwind label %catch.dispatch
68
69 catch.dispatch:
70   catchpad [i8* null, i32 8, i8* null]
71           to label %catch unwind label %catch.dispatch.2
72
73 catch:
74   invoke void @throw() noreturn
75           to label %unreachable unwind label %catchendblock
76
77 catch.dispatch.2:
78   %c2 = catchpad [i8* null, i32 32, i8* null]
79           to label %catch.2 unwind label %catch.dispatch.3
80
81 catch.2:
82   store i8 1, i8* %b
83   catchret %c2 to label %cleanup
84
85 catch.dispatch.3:
86   %c3 = catchpad [i8* null, i32 64, i8* null]
87           to label %catch.3 unwind label %catchendblock
88
89 catch.3:
90   store i8 2, i8* %b
91   catchret %c3 to label %cleanup
92
93 catchendblock:
94   catchendpad unwind to caller
95
96 cleanup:
97   %retval = phi i16 [ %call1, %if.then ], [ %call2, %if.else ], [ -1, %catch.2 ], [ -1, %catch.3 ]
98   ret i16 %retval
99
100 unreachable:
101   unreachable
102 }
103
104 ; This test verifies the case where three funclet blocks all meet the old
105 ; criteria to be placed at the end.  The order of the blocks is not important
106 ; for the purposes of this test.  The failure mode is an infinite loop during
107 ; compilation.
108 ;
109 ; CHECK-LABEL: .def     test2;
110