OLD | NEW |
---|---|
1 ; RUN: opt -expand-byval %s -S | FileCheck %s | 1 ; RUN: opt -expand-byval %s -S | FileCheck %s |
2 | 2 |
3 target datalayout = "p:32:32:32" | 3 target datalayout = "p:32:32:32" |
4 | 4 |
5 %MyStruct = type { i32, i8, i32 } | 5 %MyStruct = type { i32, i8, i32 } |
6 %AlignedStruct = type { double, double } | 6 %AlignedStruct = type { double, double } |
7 | 7 |
8 | 8 |
9 ; Removal of "byval" attribute for passing structs arguments by value | 9 ; Removal of "byval" attribute for passing structs arguments by value |
10 | 10 |
11 declare void @ext_func(%MyStruct*) | 11 declare void @ext_func(%MyStruct*) |
12 | 12 |
13 define void @byval_receiver(%MyStruct* byval align 32 %ptr) { | 13 define void @byval_receiver(%MyStruct* byval align 32 %ptr) { |
14 call void @ext_func(%MyStruct* %ptr) | 14 call void @ext_func(%MyStruct* %ptr) |
15 ret void | 15 ret void |
16 } | 16 } |
17 ; Strip the "byval" and "align" attributes. | 17 ; Strip the "byval" and "align" attributes. |
18 ; CHECK: define void @byval_receiver(%MyStruct* %ptr) { | 18 ; CHECK: define void @byval_receiver(%MyStruct* noalias %ptr) { |
19 ; CHECK-NEXT: call void @ext_func(%MyStruct* %ptr) | 19 ; CHECK-NEXT: call void @ext_func(%MyStruct* %ptr) |
20 | 20 |
21 | 21 |
22 declare void @ext_byval_func(%MyStruct* byval) | 22 declare void @ext_byval_func(%MyStruct* byval) |
23 ; CHECK: declare void @ext_byval_func(%MyStruct*) | 23 ; CHECK: declare void @ext_byval_func(%MyStruct* noalias) |
24 | 24 |
25 define void @byval_caller(%MyStruct* %ptr) { | 25 define void @byval_caller(%MyStruct* %ptr) { |
26 call void @ext_byval_func(%MyStruct* byval %ptr) | 26 call void @ext_byval_func(%MyStruct* byval %ptr) |
27 ret void | 27 ret void |
28 } | 28 } |
29 ; CHECK: define void @byval_caller(%MyStruct* %ptr) { | 29 ; CHECK: define void @byval_caller(%MyStruct* %ptr) { |
30 ; CHECK-NEXT: %ptr.byval_copy = alloca %MyStruct, align 4 | 30 ; CHECK-NEXT: %ptr.byval_copy = alloca %MyStruct, align 4 |
31 ; CHECK: call void @llvm.lifetime.start(i64 12, i8* %{{.*}}) | 31 ; CHECK: call void @llvm.lifetime.start(i64 12, i8* %{{.*}}) |
32 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 12, i32 0, i1 false) | 32 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* %{{.*}}, i64 12, i32 0, i1 false) |
33 ; CHECK-NEXT: call void @ext_byval_func(%MyStruct* %ptr.byval_copy) | 33 ; CHECK-NEXT: call void @ext_byval_func(%MyStruct* noalias %ptr.byval_copy) |
jvoung (off chromium)
2013/04/26 19:36:25
Oh, also doesn't *need* to be in the call here?
Mark Seaborn
2013/04/26 19:59:09
Yes, but as we were discussing it doesn't seem to
| |
34 | 34 |
35 | 35 |
36 define void @byval_tail_caller(%MyStruct* %ptr) { | 36 define void @byval_tail_caller(%MyStruct* %ptr) { |
37 tail call void @ext_byval_func(%MyStruct* byval %ptr) | 37 tail call void @ext_byval_func(%MyStruct* byval %ptr) |
38 ret void | 38 ret void |
39 } | 39 } |
40 ; CHECK: define void @byval_tail_caller(%MyStruct* %ptr) { | 40 ; CHECK: define void @byval_tail_caller(%MyStruct* %ptr) { |
41 ; CHECK: {{^}} call void @ext_byval_func(%MyStruct* %ptr.byval_copy) | 41 ; CHECK: {{^}} call void @ext_byval_func(%MyStruct* noalias %ptr.byval_copy) |
42 | 42 |
43 | 43 |
44 define void @byval_invoke(%MyStruct* %ptr) { | 44 define void @byval_invoke(%MyStruct* %ptr) { |
45 invoke void @ext_byval_func(%MyStruct* byval align 32 %ptr) | 45 invoke void @ext_byval_func(%MyStruct* byval align 32 %ptr) |
46 to label %cont unwind label %lpad | 46 to label %cont unwind label %lpad |
47 cont: | 47 cont: |
48 ret void | 48 ret void |
49 lpad: | 49 lpad: |
50 %lp = landingpad { i8*, i32 } personality i8* null cleanup | 50 %lp = landingpad { i8*, i32 } personality i8* null cleanup |
51 ret void | 51 ret void |
52 } | 52 } |
53 ; CHECK: define void @byval_invoke(%MyStruct* %ptr) { | 53 ; CHECK: define void @byval_invoke(%MyStruct* %ptr) { |
54 ; CHECK: %ptr.byval_copy = alloca %MyStruct, align 32 | 54 ; CHECK: %ptr.byval_copy = alloca %MyStruct, align 32 |
55 ; CHECK: call void @llvm.lifetime.start(i64 12, i8* %{{.*}}) | 55 ; CHECK: call void @llvm.lifetime.start(i64 12, i8* %{{.*}}) |
56 ; CHECK: invoke void @ext_byval_func(%MyStruct* %ptr.byval_copy) | 56 ; CHECK: invoke void @ext_byval_func(%MyStruct* noalias %ptr.byval_copy) |
57 ; CHECK: cont: | 57 ; CHECK: cont: |
58 ; CHECK: call void @llvm.lifetime.end(i64 12, i8* %{{.*}}) | 58 ; CHECK: call void @llvm.lifetime.end(i64 12, i8* %{{.*}}) |
59 ; CHECK: lpad: | 59 ; CHECK: lpad: |
60 ; CHECK: call void @llvm.lifetime.end(i64 12, i8* %{{.*}}) | 60 ; CHECK: call void @llvm.lifetime.end(i64 12, i8* %{{.*}}) |
61 | 61 |
62 | 62 |
63 ; Check handling of alignment | 63 ; Check handling of alignment |
64 | 64 |
65 ; Check that "align" is stripped for declarations too. | 65 ; Check that "align" is stripped for declarations too. |
66 declare void @ext_byval_func_align(%MyStruct* byval align 32) | 66 declare void @ext_byval_func_align(%MyStruct* byval align 32) |
67 ; CHECK: declare void @ext_byval_func_align(%MyStruct*) | 67 ; CHECK: declare void @ext_byval_func_align(%MyStruct* noalias) |
68 | 68 |
69 define void @byval_caller_align_via_attr(%MyStruct* %ptr) { | 69 define void @byval_caller_align_via_attr(%MyStruct* %ptr) { |
70 call void @ext_byval_func(%MyStruct* byval align 32 %ptr) | 70 call void @ext_byval_func(%MyStruct* byval align 32 %ptr) |
71 ret void | 71 ret void |
72 } | 72 } |
73 ; CHECK: define void @byval_caller_align_via_attr(%MyStruct* %ptr) { | 73 ; CHECK: define void @byval_caller_align_via_attr(%MyStruct* %ptr) { |
74 ; CHECK-NEXT: %ptr.byval_copy = alloca %MyStruct, align 32 | 74 ; CHECK-NEXT: %ptr.byval_copy = alloca %MyStruct, align 32 |
75 ; The memcpy may assume that %ptr is 32-byte-aligned. | 75 ; The memcpy may assume that %ptr is 32-byte-aligned. |
76 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %3, i64 12, i32 32, i1 false) | 76 ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %2, i8* %3, i64 12, i32 32, i1 false) |
77 | 77 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 define void @inreg_attr(%MyStruct* inreg %ptr) { | 114 define void @inreg_attr(%MyStruct* inreg %ptr) { |
115 ret void | 115 ret void |
116 } | 116 } |
117 ; CHECK: define void @inreg_attr(%MyStruct* inreg %ptr) { | 117 ; CHECK: define void @inreg_attr(%MyStruct* inreg %ptr) { |
118 | 118 |
119 declare void @func_attrs() #0 | 119 declare void @func_attrs() #0 |
120 ; CHECK: declare void @func_attrs() #0 | 120 ; CHECK: declare void @func_attrs() #0 |
121 | 121 |
122 attributes #0 = { noreturn nounwind } | 122 attributes #0 = { noreturn nounwind } |
123 ; CHECK: attributes #0 = { noreturn nounwind } | 123 ; CHECK: attributes #0 = { noreturn nounwind } |
OLD | NEW |