OLD | NEW |
1 ; RUN: opt < %s -expand-varargs -S | FileCheck %s | 1 ; RUN: opt < %s -expand-varargs -S | FileCheck %s |
2 | 2 |
3 target datalayout = "p:32:32:32" | 3 target datalayout = "p:32:32:32" |
4 | 4 |
5 %va_list = type i8* | 5 %va_list = type i8* |
6 | 6 |
7 declare void @llvm.va_start(i8*) | 7 declare void @llvm.va_start(i8*) |
8 declare void @llvm.va_end(i8*) | 8 declare void @llvm.va_end(i8*) |
9 declare void @llvm.va_copy(i8*, i8*) | 9 declare void @llvm.va_copy(i8*, i8*) |
10 | 10 |
(...skipping 26 matching lines...) Expand all Loading... |
37 define void @varargs_func_2(i8* nocapture %o8, i8* nocapture readonly %fmt, ...)
{ | 37 define void @varargs_func_2(i8* nocapture %o8, i8* nocapture readonly %fmt, ...)
{ |
38 ; CHECK-LABEL: @varargs_func_2( | 38 ; CHECK-LABEL: @varargs_func_2( |
39 entry: | 39 entry: |
40 %o16 = bitcast i8* %o8 to i16* | 40 %o16 = bitcast i8* %o8 to i16* |
41 %o32 = bitcast i8* %o8 to i32* | 41 %o32 = bitcast i8* %o8 to i32* |
42 %o64 = bitcast i8* %o8 to i64* | 42 %o64 = bitcast i8* %o8 to i64* |
43 %ofloat = bitcast i8* %o8 to float* | 43 %ofloat = bitcast i8* %o8 to float* |
44 %odouble = bitcast i8* %o8 to double* | 44 %odouble = bitcast i8* %o8 to double* |
45 | 45 |
46 %arglist_alloc = alloca [4 x i32], align 4 | 46 %arglist_alloc = alloca [4 x i32], align 4 |
47 %arglist = getelementptr inbounds [4 x i32]* %arglist_alloc, i32 0, i32 0 | 47 %arglist = getelementptr inbounds [4 x i32], [4 x i32]* %arglist_alloc, i32 0,
i32 0 |
48 %arglist.i8 = bitcast [4 x i32]* %arglist_alloc to i8* | 48 %arglist.i8 = bitcast [4 x i32]* %arglist_alloc to i8* |
49 call void @llvm.va_start(i8* %arglist.i8) | 49 call void @llvm.va_start(i8* %arglist.i8) |
50 br label %start | 50 br label %start |
51 | 51 |
52 start: | 52 start: |
53 %idx = phi i32 [ 0, %entry ], [ %inc, %next ] | 53 %idx = phi i32 [ 0, %entry ], [ %inc, %next ] |
54 %fmt.gep = getelementptr inbounds i8* %fmt, i32 %idx | 54 %fmt.gep = getelementptr inbounds i8, i8* %fmt, i32 %idx |
55 %arg.type = load i8* %fmt.gep | 55 %arg.type = load i8, i8* %fmt.gep |
56 switch i8 %arg.type, label %next [ | 56 switch i8 %arg.type, label %next [ |
57 i8 0, label %done | 57 i8 0, label %done |
58 i8 1, label %type.i8 | 58 i8 1, label %type.i8 |
59 i8 2, label %type.i16 | 59 i8 2, label %type.i16 |
60 i8 3, label %type.i32 | 60 i8 3, label %type.i32 |
61 i8 4, label %type.i64 | 61 i8 4, label %type.i64 |
62 i8 5, label %type.float | 62 i8 5, label %type.float |
63 i8 6, label %type.double | 63 i8 6, label %type.double |
64 ] | 64 ] |
65 | 65 |
66 type.i8: ; CHECK: type.i8: | 66 type.i8: ; CHECK: type.i8: |
67 %i8 = va_arg i32* %arglist, i8 | 67 %i8 = va_arg i32* %arglist, i8 |
68 store i8 %i8, i8* %o8 | 68 store i8 %i8, i8* %o8 |
69 br label %next | 69 br label %next |
70 ; CHECK-NEXT: %arglist1 = bitcast i32* %arglist to i8** | 70 ; CHECK-NEXT: %arglist1 = bitcast i32* %arglist to i8** |
71 ; CHECK-NEXT: %arglist_current = load i8** %arglist1 | 71 ; CHECK-NEXT: %arglist_current = load i8*, i8** %arglist1 |
72 ; CHECK-NEXT: %[[P2I:[0-9]+]] = ptrtoint i8* %arglist_current to i32 | 72 ; CHECK-NEXT: %[[P2I:[0-9]+]] = ptrtoint i8* %arglist_current to i32 |
73 ; %A8 = (uintptr_t)Addr + Alignment - 1 | 73 ; %A8 = (uintptr_t)Addr + Alignment - 1 |
74 ; CHECK-NEXT: %[[A8:[0-9]+]] = add nuw i32 %[[P2I]], sub nuw (i32 ptrtoint (i8*
getelementptr ({ i1, i8 }* null, i64 0, i32 1) to i32), i32 1) | 74 ; CHECK-NEXT: %[[A8:[0-9]+]] = add nuw i32 %[[P2I]], sub nuw (i32 ptrtoint (i8*
getelementptr ({ i1, i8 }, { i1, i8 }* null, i64 0, i32 1) to i32), i32 1) |
75 ; %B8 = %1 & ~(uintptr_t)(Alignment - 1) | 75 ; %B8 = %1 & ~(uintptr_t)(Alignment - 1) |
76 ; CHECK-NEXT: %[[B8:[0-9]+]] = and i32 %[[A8]], xor (i32 sub nuw (i32 ptrtoint (
i8* getelementptr ({ i1, i8 }* null, i64 0, i32 1) to i32), i32 1), i32 -1) | 76 ; CHECK-NEXT: %[[B8:[0-9]+]] = and i32 %[[A8]], xor (i32 sub nuw (i32 ptrtoint (
i8* getelementptr ({ i1, i8 }, { i1, i8 }* null, i64 0, i32 1) to i32), i32 1),
i32 -1) |
77 ; CHECK-NEXT: %[[C8:[0-9]+]] = inttoptr i32 %[[B8]] to i8* | 77 ; CHECK-NEXT: %[[C8:[0-9]+]] = inttoptr i32 %[[B8]] to i8* |
78 ; CHECK-NEXT: %i8 = load i8* %[[C8]] | 78 ; CHECK-NEXT: %i8 = load i8, i8* %[[C8]] |
79 ; CHECK-NEXT: %arglist_next = getelementptr inbounds i8* %[[C8]], i32 1 | 79 ; CHECK-NEXT: %arglist_next = getelementptr inbounds i8, i8* %[[C8]], i32 1 |
80 ; CHECK-NEXT: store i8* %arglist_next, i8** %arglist1 | 80 ; CHECK-NEXT: store i8* %arglist_next, i8** %arglist1 |
81 ; CHECK-NEXT: store i8 %i8, i8* %o8 | 81 ; CHECK-NEXT: store i8 %i8, i8* %o8 |
82 ; CHECK-NEXT: br label %next | 82 ; CHECK-NEXT: br label %next |
83 | 83 |
84 type.i16: ; CHECK: type.i16: | 84 type.i16: ; CHECK: type.i16: |
85 %i16 = va_arg i32* %arglist, i16 | 85 %i16 = va_arg i32* %arglist, i16 |
86 store i16 %i16, i16* %o16 | 86 store i16 %i16, i16* %o16 |
87 br label %next | 87 br label %next |
88 ; CHECK: %[[A16:[0-9]+]] = add nuw i32 %4, sub nuw (i32 ptrtoint (i16* gete
lementptr ({ i1, i16 }* null, i64 0, i32 1) to i32), i32 1) | 88 ; CHECK: %[[A16:[0-9]+]] = add nuw i32 %4, sub nuw (i32 ptrtoint (i16* gete
lementptr ({ i1, i16 }, { i1, i16 }* null, i64 0, i32 1) to i32), i32 1) |
89 ; CHECK-NEXT: %[[B16:[0-9]+]] = and i32 %[[A16]], xor (i32 sub nuw (i32 ptrtoint
(i16* getelementptr ({ i1, i16 }* null, i64 0, i32 1) to i32), i32 1), i32 -1) | 89 ; CHECK-NEXT: %[[B16:[0-9]+]] = and i32 %[[A16]], xor (i32 sub nuw (i32 ptrtoint
(i16* getelementptr ({ i1, i16 }, { i1, i16 }* null, i64 0, i32 1) to i32), i32
1), i32 -1) |
90 ; CHECK-NEXT: %[[C16:[0-9]+]] = inttoptr i32 %[[B16]] to i16* | 90 ; CHECK-NEXT: %[[C16:[0-9]+]] = inttoptr i32 %[[B16]] to i16* |
91 ; CHECK-NEXT: %i16 = load i16* %[[C16]] | 91 ; CHECK-NEXT: %i16 = load i16, i16* %[[C16]] |
92 | 92 |
93 type.i32: ; CHECK: type.i32: | 93 type.i32: ; CHECK: type.i32: |
94 %i32 = va_arg i32* %arglist, i32 | 94 %i32 = va_arg i32* %arglist, i32 |
95 store i32 %i32, i32* %o32 | 95 store i32 %i32, i32* %o32 |
96 br label %next | 96 br label %next |
97 ; CHECK: %[[A32:[0-9]+]] = add nuw i32 %8, sub nuw (i32 ptrtoint (i32* gete
lementptr ({ i1, i32 }* null, i64 0, i32 1) to i32), i32 1) | 97 ; CHECK: %[[A32:[0-9]+]] = add nuw i32 %8, sub nuw (i32 ptrtoint (i32* gete
lementptr ({ i1, i32 }, { i1, i32 }* null, i64 0, i32 1) to i32), i32 1) |
98 ; CHECK-NEXT: %[[B32:[0-9]+]] = and i32 %[[A32]], xor (i32 sub nuw (i32 ptrtoint
(i32* getelementptr ({ i1, i32 }* null, i64 0, i32 1) to i32), i32 1), i32 -1) | 98 ; CHECK-NEXT: %[[B32:[0-9]+]] = and i32 %[[A32]], xor (i32 sub nuw (i32 ptrtoint
(i32* getelementptr ({ i1, i32 }, { i1, i32 }* null, i64 0, i32 1) to i32), i32
1), i32 -1) |
99 ; CHECK-NEXT: %[[C32:[0-9]+]] = inttoptr i32 %[[B32]] to i32* | 99 ; CHECK-NEXT: %[[C32:[0-9]+]] = inttoptr i32 %[[B32]] to i32* |
100 ; CHECK-NEXT: %i32 = load i32* %[[C32]] | 100 ; CHECK-NEXT: %i32 = load i32, i32* %[[C32]] |
101 | 101 |
102 type.i64: ; CHECK: type.i64: | 102 type.i64: ; CHECK: type.i64: |
103 %i64 = va_arg i32* %arglist, i64 | 103 %i64 = va_arg i32* %arglist, i64 |
104 store i64 %i64, i64* %o64 | 104 store i64 %i64, i64* %o64 |
105 br label %next | 105 br label %next |
106 ; CHECK: %[[A64:[0-9]+]] = add nuw i32 %12, sub nuw (i32 ptrtoint (i64* get
elementptr ({ i1, i64 }* null, i64 0, i32 1) to i32), i32 1) | 106 ; CHECK: %[[A64:[0-9]+]] = add nuw i32 %12, sub nuw (i32 ptrtoint (i64* get
elementptr ({ i1, i64 }, { i1, i64 }* null, i64 0, i32 1) to i32), i32 1) |
107 ; CHECK-NEXT: %[[B64:[0-9]+]] = and i32 %[[A64]], xor (i32 sub nuw (i32 ptrtoint
(i64* getelementptr ({ i1, i64 }* null, i64 0, i32 1) to i32), i32 1), i32 -1) | 107 ; CHECK-NEXT: %[[B64:[0-9]+]] = and i32 %[[A64]], xor (i32 sub nuw (i32 ptrtoint
(i64* getelementptr ({ i1, i64 }, { i1, i64 }* null, i64 0, i32 1) to i32), i32
1), i32 -1) |
108 ; CHECK-NEXT: %[[C64:[0-9]+]] = inttoptr i32 %[[B64]] to i64* | 108 ; CHECK-NEXT: %[[C64:[0-9]+]] = inttoptr i32 %[[B64]] to i64* |
109 ; CHECK-NEXT: %i64 = load i64* %[[C64]] | 109 ; CHECK-NEXT: %i64 = load i64, i64* %[[C64]] |
110 | 110 |
111 type.float: ; CHECK: type.float: | 111 type.float: ; CHECK: type.float: |
112 %float = va_arg i32* %arglist, float | 112 %float = va_arg i32* %arglist, float |
113 store float %float, float* %ofloat | 113 store float %float, float* %ofloat |
114 br label %next | 114 br label %next |
115 ; CHECK: %[[AF:[0-9]+]] = add nuw i32 %16, sub nuw (i32 ptrtoint (float* ge
telementptr ({ i1, float }* null, i64 0, i32 1) to i32), i32 1) | 115 ; CHECK: %[[AF:[0-9]+]] = add nuw i32 %16, sub nuw (i32 ptrtoint (float* ge
telementptr ({ i1, float }, { i1, float }* null, i64 0, i32 1) to i32), i32 1) |
116 ; CHECK-NEXT: %[[BF:[0-9]+]] = and i32 %[[AF]], xor (i32 sub nuw (i32 ptrtoint (
float* getelementptr ({ i1, float }* null, i64 0, i32 1) to i32), i32 1), i32 -1
) | 116 ; CHECK-NEXT: %[[BF:[0-9]+]] = and i32 %[[AF]], xor (i32 sub nuw (i32 ptrtoint (
float* getelementptr ({ i1, float }, { i1, float }* null, i64 0, i32 1) to i32),
i32 1), i32 -1) |
117 ; CHECK-NEXT: %[[CF:[0-9]+]] = inttoptr i32 %[[BF]] to float* | 117 ; CHECK-NEXT: %[[CF:[0-9]+]] = inttoptr i32 %[[BF]] to float* |
118 ; CHECK-NEXT: %float = load float* %[[CF]] | 118 ; CHECK-NEXT: %float = load float, float* %[[CF]] |
119 | 119 |
120 type.double: ; CHECK: type.double: | 120 type.double: ; CHECK: type.double: |
121 %double = va_arg i32* %arglist, double | 121 %double = va_arg i32* %arglist, double |
122 store double %double, double* %odouble | 122 store double %double, double* %odouble |
123 br label %next | 123 br label %next |
124 ; CHECK: %[[AD:[0-9]+]] = add nuw i32 %20, sub nuw (i32 ptrtoint (double* g
etelementptr ({ i1, double }* null, i64 0, i32 1) to i32), i32 1) | 124 ; CHECK: %[[AD:[0-9]+]] = add nuw i32 %20, sub nuw (i32 ptrtoint (double* g
etelementptr ({ i1, double }, { i1, double }* null, i64 0, i32 1) to i32), i32 1
) |
125 ; CHECK-NEXT: %[[BD:[0-9]+]] = and i32 %[[AD]], xor (i32 sub nuw (i32 ptrtoint (
double* getelementptr ({ i1, double }* null, i64 0, i32 1) to i32), i32 1), i32
-1) | 125 ; CHECK-NEXT: %[[BD:[0-9]+]] = and i32 %[[AD]], xor (i32 sub nuw (i32 ptrtoint (
double* getelementptr ({ i1, double }, { i1, double }* null, i64 0, i32 1) to i3
2), i32 1), i32 -1) |
126 ; CHECK-NEXT: %[[CD:[0-9]+]] = inttoptr i32 %[[BD]] to double* | 126 ; CHECK-NEXT: %[[CD:[0-9]+]] = inttoptr i32 %[[BD]] to double* |
127 ; CHECK-NEXT: %double = load double* %[[CD]] | 127 ; CHECK-NEXT: %double = load double, double* %[[CD]] |
128 | 128 |
129 next: | 129 next: |
130 %inc = add i32 %idx, 1 | 130 %inc = add i32 %idx, 1 |
131 br label %start | 131 br label %start |
132 | 132 |
133 done: | 133 done: |
134 call void @llvm.va_end(i8* %arglist.i8) | 134 call void @llvm.va_end(i8* %arglist.i8) |
135 ret void | 135 ret void |
136 } | 136 } |
137 | 137 |
138 | 138 |
139 define i32 @varargs_call1() { | 139 define i32 @varargs_call1() { |
140 %result = call i32 (i32, ...)* @varargs_func(i32 111, i64 222, i32 333, double
4.0) | 140 %result = call i32 (i32, ...) @varargs_func(i32 111, i64 222, i32 333, double
4.0) |
141 ret i32 %result | 141 ret i32 %result |
142 } | 142 } |
143 ; CHECK-LABEL: @varargs_call1( | 143 ; CHECK-LABEL: @varargs_call1( |
144 ; CHECK-NEXT: %vararg_buffer = alloca { i64, i32, double } | 144 ; CHECK-NEXT: %vararg_buffer = alloca { i64, i32, double } |
145 ; CHECK-NEXT: %vararg_lifetime_bitcast = bitcast { i64, i32, double }* %vararg_b
uffer to i8* | 145 ; CHECK-NEXT: %vararg_lifetime_bitcast = bitcast { i64, i32, double }* %vararg_b
uffer to i8* |
146 ; CHECK-NEXT: call void @llvm.lifetime.start(i64 24, i8* %vararg_lifetime_bitcas
t) | 146 ; CHECK-NEXT: call void @llvm.lifetime.start(i64 24, i8* %vararg_lifetime_bitcas
t) |
147 ; CHECK-NEXT: %vararg_ptr = getelementptr inbounds { i64, i32, double }* %vararg
_buffer, i32 0, i32 0 | 147 ; CHECK-NEXT: %vararg_ptr = getelementptr inbounds { i64, i32, double }, { i64,
i32, double }* %vararg_buffer, i32 0, i32 0 |
148 ; CHECK-NEXT: store i64 222, i64* %vararg_ptr | 148 ; CHECK-NEXT: store i64 222, i64* %vararg_ptr |
149 ; CHECK-NEXT: %vararg_ptr1 = getelementptr inbounds { i64, i32, double }* %varar
g_buffer, i32 0, i32 1 | 149 ; CHECK-NEXT: %vararg_ptr1 = getelementptr inbounds { i64, i32, double }, { i64,
i32, double }* %vararg_buffer, i32 0, i32 1 |
150 ; CHECK-NEXT: store i32 333, i32* %vararg_ptr1 | 150 ; CHECK-NEXT: store i32 333, i32* %vararg_ptr1 |
151 ; CHECK-NEXT: %vararg_ptr2 = getelementptr inbounds { i64, i32, double }* %varar
g_buffer, i32 0, i32 2 | 151 ; CHECK-NEXT: %vararg_ptr2 = getelementptr inbounds { i64, i32, double }, { i64,
i32, double }* %vararg_buffer, i32 0, i32 2 |
152 ; CHECK-NEXT: store double 4.{{0*}}e+00, double* %vararg_ptr2 | 152 ; CHECK-NEXT: store double 4.{{0*}}e+00, double* %vararg_ptr2 |
153 ; CHECK-NEXT: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (
i32, { i64, i32, double }*)*)(i32 111, { i64, i32, double }* %vararg_buffer) | 153 ; CHECK-NEXT: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (
i32, { i64, i32, double }*)*)(i32 111, { i64, i32, double }* %vararg_buffer) |
154 ; CHECK-NEXT: call void @llvm.lifetime.end(i64 24, i8* %vararg_lifetime_bitcast) | 154 ; CHECK-NEXT: call void @llvm.lifetime.end(i64 24, i8* %vararg_lifetime_bitcast) |
155 ; CHECK-NEXT: ret i32 %result | 155 ; CHECK-NEXT: ret i32 %result |
156 | 156 |
157 | 157 |
158 ; Check that the pass works when there are no variable arguments. | 158 ; Check that the pass works when there are no variable arguments. |
159 define i32 @call_with_zero_varargs() { | 159 define i32 @call_with_zero_varargs() { |
160 %result = call i32 (i32, ...)* @varargs_func(i32 111) | 160 %result = call i32 (i32, ...) @varargs_func(i32 111) |
161 ret i32 %result | 161 ret i32 %result |
162 } | 162 } |
163 ; CHECK-LABEL: @call_with_zero_varargs( | 163 ; CHECK-LABEL: @call_with_zero_varargs( |
164 ; We have a dummy i32 field to deal with buggy programs: | 164 ; We have a dummy i32 field to deal with buggy programs: |
165 ; CHECK-NEXT: %vararg_buffer = alloca { i32 } | 165 ; CHECK-NEXT: %vararg_buffer = alloca { i32 } |
166 ; CHECK-NEXT: %vararg_lifetime_bitcast = bitcast { i32 }* %vararg_buffer to i8* | 166 ; CHECK-NEXT: %vararg_lifetime_bitcast = bitcast { i32 }* %vararg_buffer to i8* |
167 ; CHECK-NEXT: call void @llvm.lifetime.start(i64 4, i8* %vararg_lifetime_bitcast
) | 167 ; CHECK-NEXT: call void @llvm.lifetime.start(i64 4, i8* %vararg_lifetime_bitcast
) |
168 ; CHECK-NEXT: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (
i32, { i32 }*)*)(i32 111, { i32 }* %vararg_buffer) | 168 ; CHECK-NEXT: %result = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (
i32, { i32 }*)*)(i32 111, { i32 }* %vararg_buffer) |
169 ; CHECK-NEXT: call void @llvm.lifetime.end(i64 4, i8* %vararg_lifetime_bitcast) | 169 ; CHECK-NEXT: call void @llvm.lifetime.end(i64 4, i8* %vararg_lifetime_bitcast) |
170 ; CHECK-NEXT: ret i32 %result | 170 ; CHECK-NEXT: ret i32 %result |
(...skipping 13 matching lines...) Expand all Loading... |
184 ; CHECK: call void @llvm.lifetime.start(i64 8, i8* %vararg_lifetime_bitcast) | 184 ; CHECK: call void @llvm.lifetime.start(i64 8, i8* %vararg_lifetime_bitcast) |
185 ; CHECK: %result = invoke i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32
, { i64 }*)*)(i32 111, { i64 }* %vararg_buffer) | 185 ; CHECK: %result = invoke i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32
, { i64 }*)*)(i32 111, { i64 }* %vararg_buffer) |
186 ; CHECK-NEXT: to label %cont unwind label %lpad | 186 ; CHECK-NEXT: to label %cont unwind label %lpad |
187 ; CHECK: cont: | 187 ; CHECK: cont: |
188 ; CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* %vararg_lifetime_bitcast) | 188 ; CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* %vararg_lifetime_bitcast) |
189 ; CHECK: lpad: | 189 ; CHECK: lpad: |
190 ; CHECK: call void @llvm.lifetime.end(i64 8, i8* %vararg_lifetime_bitcast) | 190 ; CHECK: call void @llvm.lifetime.end(i64 8, i8* %vararg_lifetime_bitcast) |
191 | 191 |
192 | 192 |
193 define void @varargs_multiple_calls() { | 193 define void @varargs_multiple_calls() { |
194 %call1 = call i32 (i32, ...)* @varargs_func(i32 11, i64 22, i32 33) | 194 %call1 = call i32 (i32, ...) @varargs_func(i32 11, i64 22, i32 33) |
195 %call2 = call i32 (i32, ...)* @varargs_func(i32 44, i64 55, i32 66) | 195 %call2 = call i32 (i32, ...) @varargs_func(i32 44, i64 55, i32 66) |
196 ret void | 196 ret void |
197 } | 197 } |
198 ; CHECK-LABEL: @varargs_multiple_calls( | 198 ; CHECK-LABEL: @varargs_multiple_calls( |
199 ; The added allocas should appear at the start of the function. | 199 ; The added allocas should appear at the start of the function. |
200 ; CHECK: %vararg_buffer{{.*}} = alloca { i64, i32 } | 200 ; CHECK: %vararg_buffer{{.*}} = alloca { i64, i32 } |
201 ; CHECK: %vararg_buffer{{.*}} = alloca { i64, i32 } | 201 ; CHECK: %vararg_buffer{{.*}} = alloca { i64, i32 } |
202 ; CHECK: %call1 = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32, {
i64, i32 }*)*)(i32 11, { i64, i32 }* %vararg_buffer{{.*}}) | 202 ; CHECK: %call1 = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32, {
i64, i32 }*)*)(i32 11, { i64, i32 }* %vararg_buffer{{.*}}) |
203 ; CHECK: %call2 = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32, {
i64, i32 }*)*)(i32 44, { i64, i32 }* %vararg_buffer{{.*}}) | 203 ; CHECK: %call2 = call i32 bitcast (i32 (i32, i8*)* @varargs_func to i32 (i32, {
i64, i32 }*)*)(i32 44, { i64, i32 }* %vararg_buffer{{.*}}) |
204 | 204 |
205 | 205 |
206 | 206 |
207 define i32 @va_arg_i32(i8* %arglist) { | 207 define i32 @va_arg_i32(i8* %arglist) { |
208 %result = va_arg i8* %arglist, i32 | 208 %result = va_arg i8* %arglist, i32 |
209 ret i32 %result | 209 ret i32 %result |
210 } | 210 } |
211 ; CHECK-LABEL: define i32 @va_arg_i32(i8* %arglist) { | 211 ; CHECK-LABEL: define i32 @va_arg_i32(i8* %arglist) { |
212 ; CHECK-NEXT: %arglist1 = bitcast i8* %arglist to i32** | 212 ; CHECK-NEXT: %arglist1 = bitcast i8* %arglist to i32** |
213 ; CHECK-NEXT: %arglist_current = load i32** %arglist1 | 213 ; CHECK-NEXT: %arglist_current = load i32*, i32** %arglist1 |
214 ; CHECK-NEXT: %1 = ptrtoint i32* %arglist_current to i32 | 214 ; CHECK-NEXT: %1 = ptrtoint i32* %arglist_current to i32 |
215 ; CHECK-NEXT: %2 = add nuw i32 %1, sub nuw (i32 ptrtoint (i32* getelementptr ({
i1, i32 }* null, i64 0, i32 1) to i32), i32 1) | 215 ; CHECK-NEXT: %2 = add nuw i32 %1, sub nuw (i32 ptrtoint (i32* getelementptr ({
i1, i32 }, { i1, i32 }* null, i64 0, i32 1) to i32), i32 1) |
216 ; CHECK-NEXT: %3 = and i32 %2, xor (i32 sub nuw (i32 ptrtoint (i32* getelementpt
r ({ i1, i32 }* null, i64 0, i32 1) to i32), i32 1), i32 -1) | 216 ; CHECK-NEXT: %3 = and i32 %2, xor (i32 sub nuw (i32 ptrtoint (i32* getelementpt
r ({ i1, i32 }, { i1, i32 }* null, i64 0, i32 1) to i32), i32 1), i32 -1) |
217 ; CHECK-NEXT: %4 = inttoptr i32 %3 to i32* | 217 ; CHECK-NEXT: %4 = inttoptr i32 %3 to i32* |
218 ; CHECK-NEXT: %result = load i32* %4 | 218 ; CHECK-NEXT: %result = load i32, i32* %4 |
219 ; CHECK-NEXT: %arglist_next = getelementptr inbounds i32* %4, i32 1 | 219 ; CHECK-NEXT: %arglist_next = getelementptr inbounds i32, i32* %4, i32 1 |
220 ; CHECK-NEXT: store i32* %arglist_next, i32** %arglist1 | 220 ; CHECK-NEXT: store i32* %arglist_next, i32** %arglist1 |
221 ; CHECK-NEXT: ret i32 %result | 221 ; CHECK-NEXT: ret i32 %result |
222 | 222 |
223 | 223 |
224 define i64 @va_arg_i64(i8* %arglist) { | 224 define i64 @va_arg_i64(i8* %arglist) { |
225 %result = va_arg i8* %arglist, i64 | 225 %result = va_arg i8* %arglist, i64 |
226 ret i64 %result | 226 ret i64 %result |
227 } | 227 } |
228 ; CHECK-LABEL: define i64 @va_arg_i64(i8* %arglist) { | 228 ; CHECK-LABEL: define i64 @va_arg_i64(i8* %arglist) { |
229 ; CHECK-NEXT: %arglist1 = bitcast i8* %arglist to i64** | 229 ; CHECK-NEXT: %arglist1 = bitcast i8* %arglist to i64** |
230 ; CHECK-NEXT: %arglist_current = load i64** %arglist1 | 230 ; CHECK-NEXT: %arglist_current = load i64*, i64** %arglist1 |
231 ; CHECK-NEXT: %1 = ptrtoint i64* %arglist_current to i32 | 231 ; CHECK-NEXT: %1 = ptrtoint i64* %arglist_current to i32 |
232 ; CHECK-NEXT: %2 = add nuw i32 %1, sub nuw (i32 ptrtoint (i64* getelementptr ({
i1, i64 }* null, i64 0, i32 1) to i32), i32 1) | 232 ; CHECK-NEXT: %2 = add nuw i32 %1, sub nuw (i32 ptrtoint (i64* getelementptr ({
i1, i64 }, { i1, i64 }* null, i64 0, i32 1) to i32), i32 1) |
233 ; CHECK-NEXT: %3 = and i32 %2, xor (i32 sub nuw (i32 ptrtoint (i64* getelementpt
r ({ i1, i64 }* null, i64 0, i32 1) to i32), i32 1), i32 -1) | 233 ; CHECK-NEXT: %3 = and i32 %2, xor (i32 sub nuw (i32 ptrtoint (i64* getelementpt
r ({ i1, i64 }, { i1, i64 }* null, i64 0, i32 1) to i32), i32 1), i32 -1) |
234 ; CHECK-NEXT: %4 = inttoptr i32 %3 to i64* | 234 ; CHECK-NEXT: %4 = inttoptr i32 %3 to i64* |
235 ; CHECK-NEXT: %result = load i64* %4 | 235 ; CHECK-NEXT: %result = load i64, i64* %4 |
236 ; CHECK-NEXT: %arglist_next = getelementptr inbounds i64* %4, i32 1 | 236 ; CHECK-NEXT: %arglist_next = getelementptr inbounds i64, i64* %4, i32 1 |
237 ; CHECK-NEXT: store i64* %arglist_next, i64** %arglist1 | 237 ; CHECK-NEXT: store i64* %arglist_next, i64** %arglist1 |
238 ; CHECK-NEXT: ret i64 %result | 238 ; CHECK-NEXT: ret i64 %result |
239 | 239 |
240 | 240 |
241 define void @do_va_copy(i8* %dest, i8* %src) { | 241 define void @do_va_copy(i8* %dest, i8* %src) { |
242 call void @llvm.va_copy(i8* %dest, i8* %src) | 242 call void @llvm.va_copy(i8* %dest, i8* %src) |
243 ret void | 243 ret void |
244 } | 244 } |
245 ; CHECK-LABEL: define void @do_va_copy( | 245 ; CHECK-LABEL: define void @do_va_copy( |
246 ; CHECK-NEXT: %vacopy_src = bitcast i8* %src to i8** | 246 ; CHECK-NEXT: %vacopy_src = bitcast i8* %src to i8** |
247 ; CHECK-NEXT: %vacopy_dest = bitcast i8* %dest to i8** | 247 ; CHECK-NEXT: %vacopy_dest = bitcast i8* %dest to i8** |
248 ; CHECK-NEXT: %vacopy_currentptr = load i8** %vacopy_src | 248 ; CHECK-NEXT: %vacopy_currentptr = load i8*, i8** %vacopy_src |
249 ; CHECK-NEXT: store i8* %vacopy_currentptr, i8** %vacopy_dest | 249 ; CHECK-NEXT: store i8* %vacopy_currentptr, i8** %vacopy_dest |
250 ; CHECK-NEXT: ret void | 250 ; CHECK-NEXT: ret void |
OLD | NEW |