OLD | NEW |
---|---|
(Empty) | |
1 ; RUN: opt %s -simplify-struct-reg-signatures -S | FileCheck %s | |
JF
2015/03/18 20:27:57
Lacking tests:
- ArrayType
- VectorType
- Varar
Mircea Trofin
2015/03/19 05:26:18
Done.
| |
2 | |
3 %struct = type { i32, i32 } | |
4 %rec_struct = type {%rec_struct*} | |
5 %rec_problem_struct = type{void (%rec_problem_struct)*} | |
6 %rec_pair_1 = type {%rec_pair_2*} | |
7 %rec_pair_2 = type {%rec_pair_1*} | |
8 %rec_returning = type { %rec_returning (%rec_returning)* } | |
9 %direct_def = type { void(%struct)*, %struct } | |
10 | |
11 ; new type declarations: | |
12 ; CHECK: %struct = type { i32, i32 } | |
13 ; CHECK-NEXT: %rec_struct = type { %rec_struct* } | |
14 ; CHECK-NEXT: %rec_problem_struct.simplified = type { void (%rec_problem_struct. simplified*)* } | |
15 ; CHECK-NEXT: %rec_pair_1 = type { %rec_pair_2* } | |
16 ; CHECK-NEXT: %rec_pair_2 = type { %rec_pair_1* } | |
17 ; CHECK-NEXT: %rec_returning.simplified = type { void (%rec_returning.simplified *, %rec_returning.simplified*)* } | |
18 ; CHECK-NEXT: %direct_def.simplified = type { void (%struct*)*, %struct } | |
19 | |
20 ; externs | |
21 declare void @extern_func(%struct) | |
22 declare %struct @struct_returning_extern(i32, %struct) | |
23 | |
24 ; verify that parameters are mapped correctly: single param, two, and combo | |
25 ; with non-struct regs | |
26 ; CHECK-NOT: declare void @extern_func(%struct) | |
27 ; CHECK-NOT: declare %struct @struct_returning_extern(i32, %struct) | |
28 ; CHECK-LABEL: declare void @extern_func(%struct* byval) | |
29 ; CHECK-LABEL: declare void @struct_returning_extern(%struct* sret, i32, %struct * byval) | |
30 | |
31 define void @main(%struct* byval %ptr) { | |
32 %val = load %struct* %ptr | |
33 call void @extern_func(%struct %val) | |
34 ret void | |
35 } | |
36 | |
37 define void @two_param_func(%struct %val1, %struct %val2) { | |
38 call void @extern_func(%struct %val1) | |
39 call void @extern_func(%struct %val2) | |
40 ret void | |
41 } | |
42 | |
43 ; CHECK-LABEL: define void @two_param_func(%struct* byval %val1.ptr, %struct* by val %val2.ptr) | |
44 ; CHECK-NOT: define void @two_param_func(%struct %val1, %struct %val2) | |
45 | |
46 define i32 @another_func(i32 %a, %struct %str, i64 %b) { | |
47 call void @two_param_func(%struct %str, %struct %str) | |
48 call void @extern_func(%struct %str) | |
49 ret i32 0 | |
50 } | |
51 | |
52 ; CHECK-LABEL: define i32 @another_func(i32 %a, %struct* byval %str.ptr, i64 %b) | |
53 ; CHECK: call void @two_param_func(%struct* byval %str.sreg.ptr, %struct* byval %str.sreg.ptr1) | |
54 | |
55 define %struct @returns_struct(i32 %an_int, %struct %val) { | |
56 %tmp = call %struct @struct_returning_extern(i32 %an_int, %struct %val) | |
57 ret %struct %tmp | |
58 } | |
59 | |
60 ; verify return value and codegen | |
61 ; CHECK-LABEL: define void @returns_struct(%struct* sret %retVal, i32 %an_int, % struct* byval %val.ptr) | |
62 ; CHECK-NEXT: %val.sreg = load %struct* %val.ptr | |
63 ; CHECK-NEXT: %tmp = alloca %struct | |
64 ; CHECK-NEXT: %val.sreg.ptr = alloca %struct | |
65 ; CHECK-NEXT: store %struct %val.sreg, %struct* %val.sreg.ptr | |
66 ; CHECK-NEXT: call void @struct_returning_extern(%struct* sret %tmp, i32 %an_in t, %struct* byval %val.sreg.ptr) | |
67 ; CHECK-NEXT: %tmp.sreg = load %struct* %tmp | |
68 ; CHECK-NEXT: store %struct %tmp.sreg, %struct* %retVal | |
69 ; CHECK-NEXT: ret void | |
70 | |
71 define i32 @lots_of_call_attrs() { | |
72 %tmp.0 = insertvalue %struct undef, i32 1, 0 | |
73 %tmp.1 = insertvalue %struct %tmp.0, i32 2, 1 | |
74 %ret = tail call zeroext i32 @another_func(i32 1, %struct %tmp.1, i64 2) reado nly | |
75 ret i32 %ret | |
76 } | |
77 | |
78 ; verify attributes are copied | |
79 ; CHECK_LABEL: @lots_of_call_attrs | |
80 ; CHECK: %ret = tail call zeroext i32 @another_func(i32 1, %struct* byval %tmp.1 .ptr, i64 2) #0 | |
81 ; CHECK-NEXT: ret i32 %ret | |
82 | |
83 declare void @rec_struct_ok(%rec_struct*) | |
84 declare void @rec_struct_mod(%rec_struct) | |
85 | |
86 ; compliant recursive structs are kept as-is | |
87 ; CHECK-LABEL: declare void @rec_struct_ok(%rec_struct*) | |
88 ; CHECK-LABEL: declare void @rec_struct_mod(%rec_struct* byval) | |
89 | |
90 define void @rec_call_sreg(%rec_problem_struct %r) { | |
91 %tmp = extractvalue %rec_problem_struct %r, 0 | |
92 call void %tmp(%rec_problem_struct %r) | |
93 ret void | |
94 } | |
95 | |
96 ; non-compliant structs are correctly mapped and calls are changed | |
97 ; CHECK-LABEL: define void @rec_call_sreg(%rec_problem_struct.simplified* byval %r.ptr) | |
98 ; CHECK: call void %tmp(%rec_problem_struct.simplified* byval %r.sreg.ptr) | |
99 | |
100 declare void @pairs(%rec_pair_1) | |
101 | |
102 define %rec_returning @rec_returning_fun(%rec_returning %str) { | |
103 %tmp = extractvalue %rec_returning %str, 0 | |
104 %ret = call %rec_returning %tmp(%rec_returning %str) | |
105 ret %rec_returning %ret | |
106 } | |
107 | |
108 ; pair structs | |
109 ; CHECK-LABEL: declare void @pairs(%rec_pair_1* byval) | |
110 ; CHECK-LABEL: define void @rec_returning_fun(%rec_returning.simplified* sret %r etVal, %rec_returning.simplified* byval %str.ptr) | |
111 ; CHECK-NEXT: %str.sreg = load %rec_returning.simplified* %str.ptr | |
112 ; CHECK-NEXT: %tmp = extractvalue %rec_returning.simplified %str.sreg, 0 | |
113 ; CHECK-NEXT: %ret = alloca %rec_returning.simplified | |
114 ; CHECK-NEXT: %str.sreg.ptr = alloca %rec_returning.simplified | |
115 ; CHECK-NEXT: store %rec_returning.simplified %str.sreg, %rec_returning.simpli fied* %str.sreg.ptr | |
116 ; CHECK-NEXT: call void %tmp(%rec_returning.simplified* sret %ret, %rec_return ing.simplified* byval %str.sreg.ptr) | |
117 ; CHECK-NEXT: %ret.sreg = load %rec_returning.simplified* %ret | |
118 ; CHECK-NEXT: store %rec_returning.simplified %ret.sreg, %rec_returning.simpli fied* %retVal | |
119 ; CHECK-NEXT: ret void | |
120 | |
121 define void @direct_caller(%direct_def %def) { | |
122 %func = extractvalue %direct_def %def, 0 | |
123 %param = extractvalue %direct_def %def, 1 | |
124 call void %func(%struct %param) | |
125 ret void | |
126 } | |
127 | |
128 ; CHECK-LABEL: define void @direct_caller(%direct_def.simplified* byval %def.ptr ) | |
129 ; CHECK-NEXT: %def.sreg = load %direct_def.simplified* %def.ptr | |
130 ; CHECK-NEXT: %func = extractvalue %direct_def.simplified %def.sreg, 0 | |
131 ; CHECK-NEXT: %param = extractvalue %direct_def.simplified %def.sreg, 1 | |
132 ; CHECK-NEXT: %param.ptr = alloca %struct | |
133 ; CHECK-NEXT: store %struct %param, %struct* %param.ptr | |
134 ; CHECK-NEXT: call void %func(%struct* byval %param.ptr) | |
135 ; CHECK-NEXT: ret void | |
136 | |
137 | |
138 ; this is at the end, corresponds to the call marked as readonly | |
139 ; CHECK: attributes #0 = { readonly } | |
OLD | NEW |