[WinEH] Demote values and phis live across exception handlers up front
[oota-llvm.git] / test / CodeGen / WinEH / cppeh-demote-liveout.ll
1 ; RUN: opt -winehprepare -S < %s | FileCheck %s
2
3 ; Notionally based on this C++ source:
4 ; int liveout_catch(int p) {
5 ;   int val = p + 1;
6 ;   try {
7 ;     might_throw();
8 ;   } catch (int) {
9 ;     val++;
10 ;   }
11 ;   return val;
12 ; }
13
14 declare void @llvm.eh.begincatch(i8*, i8*)
15 declare void @llvm.eh.endcatch()
16 declare void @might_throw()
17 declare i32 @__CxxFrameHandler3(...)
18 declare i32 @llvm.eh.typeid.for(i8*)
19
20 @typeinfo.int = external global i32
21
22 define i32 @liveout_catch(i32 %p) {
23 entry:
24   %val.entry = add i32 %p, 1
25   invoke void @might_throw()
26       to label %ret unwind label %lpad
27
28 lpad:
29   %ehvals = landingpad { i8*, i32 } personality i32 (...)* @__CxxFrameHandler3
30       cleanup
31       catch i32* @typeinfo.int
32   %ehptr = extractvalue { i8*, i32 } %ehvals, 0
33   %sel = extractvalue { i8*, i32 } %ehvals, 1
34   %int_sel = call i32 @llvm.eh.typeid.for(i8* bitcast (i32* @typeinfo.int to i8*))
35   %match = icmp eq i32 %sel, %int_sel
36   br i1 %match, label %catchit, label %resume
37
38 catchit:
39   call void @llvm.eh.begincatch(i8* %ehptr, i8* null)
40   %val.lpad = add i32 %val.entry, 1
41   call void @llvm.eh.endcatch()
42   br label %ret
43
44 ret:
45   %rv = phi i32 [%val.entry, %entry], [%val.lpad, %catchit]
46   ret i32 %rv
47
48 resume:
49   resume {i8*, i32} %ehvals
50 }
51
52 ; CHECK-LABEL: define i32 @liveout_catch(i32 %p)
53 ; CHECK: %val.entry = add i32 %p, 1
54 ; CHECK-NEXT: store i32 %val.entry, i32* %val.entry.reg2mem
55 ; CHECK: invoke void @might_throw()
56 ;
57 ; CHECK: landingpad
58 ; CHECK: indirectbr i8* {{.*}}, [label %ehreturn]
59 ;
60 ; CHECK: ehreturn:
61 ; CHECK: load i32, i32* %val.lpad.reg2mem
62 ; CHECK: br label %ret
63 ;
64 ; CHECK: ret:
65 ; CHECK: %rv = phi i32 [ {{.*}}, %entry ], [ {{.*}}, %ehreturn ]
66 ; CHECK: ret i32
67
68 ; CHECK-LABEL: define internal i8* @liveout_catch.catch(i8*, i8*)
69 ; CHECK: %[[val:[^ ]*]] = load i32, i32*
70 ; CHECK-NEXT: %[[val_lpad:[^ ]*]] = add i32 %[[val]], 1
71 ; CHECK-NEXT: store i32 %[[val_lpad]], i32*
72 ; CHECK: ret i8* blockaddress(@liveout_catch, %ehreturn)