Merging r261039:
[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   %cs = catchswitch within none [ label %catch, label %catch.2 ] unwind to caller
23
24 catch:
25   catchpad within %cs [i8* null, i32 8, i8* null]
26   call void @throw() noreturn
27   br label %unreachable
28
29 catch.2:
30   catchpad within %cs [i8* null, i32 64, i8* null]
31   store i8 1, i8* %b
32   call void @throw() noreturn
33   br label %unreachable
34
35 cleanup:
36   %retval = phi i16 [ %call1, %if.then ], [ %call2, %if.else ]
37   ret i16 %retval
38
39 unreachable:
40   unreachable
41 }
42
43 ; This test verifies the case where two funclet blocks meet the old criteria
44 ; to be placed at the end.  The order of the blocks is not important for the
45 ; purposes of this test.  The failure mode is an infinite loop during
46 ; compilation.
47 ;
48 ; CHECK-LABEL: .def     test1;
49
50 define i16 @test2(i16 %a, i8* %b) personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) {
51 entry:
52   %cmp = icmp eq i16 %a, 10
53   br i1 %cmp, label %if.then, label %if.else
54
55 if.then:
56   %call1 = invoke i16 @f()
57           to label %cleanup unwind label %catch.dispatch
58
59 if.else:
60   %call2 = invoke i16 @f()
61           to label %cleanup unwind label %catch.dispatch
62
63 catch.dispatch:
64   %cs = catchswitch within none [ label %catch, label %catch.2, label %catch.3 ] unwind to caller
65
66 catch:
67   catchpad within %cs [i8* null, i32 8, i8* null]
68   call void @throw() noreturn
69   br label %unreachable
70
71 catch.2:
72   %c2 = catchpad within %cs [i8* null, i32 32, i8* null]
73   store i8 1, i8* %b
74   catchret from %c2 to label %cleanup
75
76 catch.3:
77   %c3 = catchpad within %cs [i8* null, i32 64, i8* null]
78   store i8 2, i8* %b
79   catchret from %c3 to label %cleanup
80
81 cleanup:
82   %retval = phi i16 [ %call1, %if.then ], [ %call2, %if.else ], [ -1, %catch.2 ], [ -1, %catch.3 ]
83   ret i16 %retval
84
85 unreachable:
86   unreachable
87 }
88
89 ; This test verifies the case where three funclet blocks all meet the old
90 ; criteria to be placed at the end.  The order of the blocks is not important
91 ; for the purposes of this test.  The failure mode is an infinite loop during
92 ; compilation.
93 ;
94 ; CHECK-LABEL: .def     test2;
95