1 // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
2 // RUN:         -triple i686--windows -Oz -emit-llvm %s -o - \
3 // RUN:         | FileCheck %s -check-prefixes CHECK,CHECK-I386,CHECK-INTEL
4 // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
5 // RUN:         -triple thumbv7--windows -Oz -emit-llvm %s -o - \
6 // RUN:         | FileCheck %s --check-prefixes CHECK,CHECK-ARM,CHECK-ARM-X64
7 // RUN: %clang_cc1 -ffreestanding -fms-extensions -fms-compatibility -fms-compatibility-version=17.00 \
8 // RUN:         -triple x86_64--windows -Oz -emit-llvm -target-feature +cx16 %s -o - \
9 // RUN:         | FileCheck %s --check-prefixes CHECK,CHECK-X64,CHECK-ARM-X64,CHECK-INTEL
10 
11 // intrin.h needs size_t, but -ffreestanding prevents us from getting it from
12 // stddef.h.  Work around it with this typedef.
13 typedef __SIZE_TYPE__ size_t;
14 
15 #include <intrin.h>
16 
17 #if defined(__i386__) || defined(__x86_64__)
18 void test__stosb(unsigned char *Dest, unsigned char Data, size_t Count) {
19   return __stosb(Dest, Data, Count);
20 }
21 
22 // CHECK-I386: define{{.*}}void @test__stosb
23 // CHECK-I386:   tail call void @llvm.memset.p0i8.i32(i8* align 1 %Dest, i8 %Data, i32 %Count, i1 true)
24 // CHECK-I386:   ret void
25 // CHECK-I386: }
26 
27 // CHECK-X64: define{{.*}}void @test__stosb
28 // CHECK-X64:   tail call void @llvm.memset.p0i8.i64(i8* align 1 %Dest, i8 %Data, i64 %Count, i1 true)
29 // CHECK-X64:   ret void
30 // CHECK-X64: }
31 
32 void test__ud2(void) {
33   __ud2();
34 }
35 // CHECK-INTEL-LABEL: define{{.*}} void @test__ud2()
36 // CHECK-INTEL: call void @llvm.trap()
37 
38 void test__int2c(void) {
39   __int2c();
40 }
41 // CHECK-INTEL-LABEL: define{{.*}} void @test__int2c()
42 // CHECK-INTEL: call void asm sideeffect "int $$0x2c", ""() #[[NORETURN:[0-9]+]]
43 
44 
45 #endif
46 
47 void *test_ReturnAddress() {
48   return _ReturnAddress();
49 }
50 // CHECK-LABEL: define{{.*}}i8* @test_ReturnAddress()
51 // CHECK: = tail call i8* @llvm.returnaddress(i32 0)
52 // CHECK: ret i8*
53 
54 #if defined(__i386__) || defined(__x86_64__)
55 void *test_AddressOfReturnAddress() {
56   return _AddressOfReturnAddress();
57 }
58 // CHECK-INTEL-LABEL: define dso_local i8* @test_AddressOfReturnAddress()
59 // CHECK-INTEL: = tail call i8* @llvm.addressofreturnaddress()
60 // CHECK-INTEL: ret i8*
61 #endif
62 
63 unsigned char test_BitScanForward(unsigned long *Index, unsigned long Mask) {
64   return _BitScanForward(Index, Mask);
65 }
66 // CHECK: define{{.*}}i8 @test_BitScanForward(i32* {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{
67 // CHECK:   [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i32 %Mask, 0
68 // CHECK:   br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]]
69 // CHECK:   [[END_LABEL]]:
70 // CHECK:   [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ]
71 // CHECK:   ret i8 [[RESULT]]
72 // CHECK:   [[ISNOTZERO_LABEL]]:
73 // CHECK:   [[INDEX:%[0-9]+]] = tail call i32 @llvm.cttz.i32(i32 %Mask, i1 true)
74 // CHECK:   store i32 [[INDEX]], i32* %Index, align 4
75 // CHECK:   br label %[[END_LABEL]]
76 
77 unsigned char test_BitScanReverse(unsigned long *Index, unsigned long Mask) {
78   return _BitScanReverse(Index, Mask);
79 }
80 // CHECK: define{{.*}}i8 @test_BitScanReverse(i32* {{[a-z_ ]*}}%Index, i32 {{[a-z_ ]*}}%Mask){{.*}}{
81 // CHECK:   [[ISNOTZERO:%[0-9]+]] = icmp eq i32 %Mask, 0
82 // CHECK:   br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]]
83 // CHECK:   [[END_LABEL]]:
84 // CHECK:   [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ]
85 // CHECK:   ret i8 [[RESULT]]
86 // CHECK:   [[ISNOTZERO_LABEL]]:
87 // CHECK:   [[REVINDEX:%[0-9]+]] = tail call i32 @llvm.ctlz.i32(i32 %Mask, i1 true)
88 // CHECK:   [[INDEX:%[0-9]+]] = xor i32 [[REVINDEX]], 31
89 // CHECK:   store i32 [[INDEX]], i32* %Index, align 4
90 // CHECK:   br label %[[END_LABEL]]
91 
92 #if defined(__x86_64__) || defined(__arm__)
93 unsigned char test_BitScanForward64(unsigned long *Index, unsigned __int64 Mask) {
94   return _BitScanForward64(Index, Mask);
95 }
96 // CHECK-ARM-X64: define{{.*}}i8 @test_BitScanForward64(i32* {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{
97 // CHECK-ARM-X64:   [[ISNOTZERO:%[a-z0-9._]+]] = icmp eq i64 %Mask, 0
98 // CHECK-ARM-X64:   br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]]
99 // CHECK-ARM-X64:   [[END_LABEL]]:
100 // CHECK-ARM-X64:   [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ]
101 // CHECK-ARM-X64:   ret i8 [[RESULT]]
102 // CHECK-ARM-X64:   [[ISNOTZERO_LABEL]]:
103 // CHECK-ARM-X64:   [[INDEX:%[0-9]+]] = tail call i64 @llvm.cttz.i64(i64 %Mask, i1 true)
104 // CHECK-ARM-X64:   [[TRUNC_INDEX:%[0-9]+]] = trunc i64 [[INDEX]] to i32
105 // CHECK-ARM-X64:   store i32 [[TRUNC_INDEX]], i32* %Index, align 4
106 // CHECK-ARM-X64:   br label %[[END_LABEL]]
107 
108 unsigned char test_BitScanReverse64(unsigned long *Index, unsigned __int64 Mask) {
109   return _BitScanReverse64(Index, Mask);
110 }
111 // CHECK-ARM-X64: define{{.*}}i8 @test_BitScanReverse64(i32* {{[a-z_ ]*}}%Index, i64 {{[a-z_ ]*}}%Mask){{.*}}{
112 // CHECK-ARM-X64:   [[ISNOTZERO:%[0-9]+]] = icmp eq i64 %Mask, 0
113 // CHECK-ARM-X64:   br i1 [[ISNOTZERO]], label %[[END_LABEL:[a-z0-9._]+]], label %[[ISNOTZERO_LABEL:[a-z0-9._]+]]
114 // CHECK-ARM-X64:   [[END_LABEL]]:
115 // CHECK-ARM-X64:   [[RESULT:%[a-z0-9._]+]] = phi i8 [ 0, %[[ISZERO_LABEL:[a-z0-9._]+]] ], [ 1, %[[ISNOTZERO_LABEL]] ]
116 // CHECK-ARM-X64:   ret i8 [[RESULT]]
117 // CHECK-ARM-X64:   [[ISNOTZERO_LABEL]]:
118 // CHECK-ARM-X64:   [[REVINDEX:%[0-9]+]] = tail call i64 @llvm.ctlz.i64(i64 %Mask, i1 true)
119 // CHECK-ARM-X64:   [[TRUNC_REVINDEX:%[0-9]+]] = trunc i64 [[REVINDEX]] to i32
120 // CHECK-ARM-X64:   [[INDEX:%[0-9]+]] = xor i32 [[TRUNC_REVINDEX]], 63
121 // CHECK-ARM-X64:   store i32 [[INDEX]], i32* %Index, align 4
122 // CHECK-ARM-X64:   br label %[[END_LABEL]]
123 #endif
124 
125 void *test_InterlockedExchangePointer(void * volatile *Target, void *Value) {
126   return _InterlockedExchangePointer(Target, Value);
127 }
128 
129 // CHECK: define{{.*}}i8* @test_InterlockedExchangePointer(i8** {{[a-z_ ]*}}%Target, i8* {{[a-z_ ]*}}%Value){{.*}}{
130 // CHECK:   %[[TARGET:[0-9]+]] = bitcast i8** %Target to [[iPTR:i[0-9]+]]*
131 // CHECK:   %[[VALUE:[0-9]+]] = ptrtoint i8* %Value to [[iPTR]]
132 // CHECK:   %[[EXCHANGE:[0-9]+]] = atomicrmw xchg [[iPTR]]* %[[TARGET]], [[iPTR]] %[[VALUE]] seq_cst
133 // CHECK:   %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXCHANGE]] to i8*
134 // CHECK:   ret i8* %[[RESULT]]
135 // CHECK: }
136 
137 void *test_InterlockedCompareExchangePointer(void * volatile *Destination,
138                                              void *Exchange, void *Comparand) {
139   return _InterlockedCompareExchangePointer(Destination, Exchange, Comparand);
140 }
141 
142 // CHECK: define{{.*}}i8* @test_InterlockedCompareExchangePointer(i8** {{[a-z_ ]*}}%Destination, i8* {{[a-z_ ]*}}%Exchange, i8* {{[a-z_ ]*}}%Comparand){{.*}}{
143 // CHECK:   %[[DEST:[0-9]+]] = bitcast i8** %Destination to [[iPTR]]*
144 // CHECK:   %[[EXCHANGE:[0-9]+]] = ptrtoint i8* %Exchange to [[iPTR]]
145 // CHECK:   %[[COMPARAND:[0-9]+]] = ptrtoint i8* %Comparand to [[iPTR]]
146 // CHECK:   %[[XCHG:[0-9]+]] = cmpxchg volatile [[iPTR]]* %[[DEST:[0-9]+]], [[iPTR]] %[[COMPARAND:[0-9]+]], [[iPTR]] %[[EXCHANGE:[0-9]+]] seq_cst seq_cst
147 // CHECK:   %[[EXTRACT:[0-9]+]] = extractvalue { [[iPTR]], i1 } %[[XCHG]], 0
148 // CHECK:   %[[RESULT:[0-9]+]] = inttoptr [[iPTR]] %[[EXTRACT]] to i8*
149 // CHECK:   ret i8* %[[RESULT:[0-9]+]]
150 // CHECK: }
151 
152 char test_InterlockedExchange8(char volatile *value, char mask) {
153   return _InterlockedExchange8(value, mask);
154 }
155 // CHECK: define{{.*}}i8 @test_InterlockedExchange8(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
156 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw xchg i8* %value, i8 %mask seq_cst
157 // CHECK:   ret i8 [[RESULT:%[0-9]+]]
158 // CHECK: }
159 
160 short test_InterlockedExchange16(short volatile *value, short mask) {
161   return _InterlockedExchange16(value, mask);
162 }
163 // CHECK: define{{.*}}i16 @test_InterlockedExchange16(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
164 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw xchg i16* %value, i16 %mask seq_cst
165 // CHECK:   ret i16 [[RESULT:%[0-9]+]]
166 // CHECK: }
167 
168 long test_InterlockedExchange(long volatile *value, long mask) {
169   return _InterlockedExchange(value, mask);
170 }
171 // CHECK: define{{.*}}i32 @test_InterlockedExchange(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
172 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw xchg i32* %value, i32 %mask seq_cst
173 // CHECK:   ret i32 [[RESULT:%[0-9]+]]
174 // CHECK: }
175 
176 char test_InterlockedExchangeAdd8(char volatile *value, char mask) {
177   return _InterlockedExchangeAdd8(value, mask);
178 }
179 // CHECK: define{{.*}}i8 @test_InterlockedExchangeAdd8(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
180 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw add i8* %value, i8 %mask seq_cst
181 // CHECK:   ret i8 [[RESULT:%[0-9]+]]
182 // CHECK: }
183 
184 short test_InterlockedExchangeAdd16(short volatile *value, short mask) {
185   return _InterlockedExchangeAdd16(value, mask);
186 }
187 // CHECK: define{{.*}}i16 @test_InterlockedExchangeAdd16(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
188 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw add i16* %value, i16 %mask seq_cst
189 // CHECK:   ret i16 [[RESULT:%[0-9]+]]
190 // CHECK: }
191 
192 long test_InterlockedExchangeAdd(long volatile *value, long mask) {
193   return _InterlockedExchangeAdd(value, mask);
194 }
195 // CHECK: define{{.*}}i32 @test_InterlockedExchangeAdd(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
196 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw add i32* %value, i32 %mask seq_cst
197 // CHECK:   ret i32 [[RESULT:%[0-9]+]]
198 // CHECK: }
199 
200 char test_InterlockedExchangeSub8(char volatile *value, char mask) {
201   return _InterlockedExchangeSub8(value, mask);
202 }
203 // CHECK: define{{.*}}i8 @test_InterlockedExchangeSub8(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
204 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw sub i8* %value, i8 %mask seq_cst
205 // CHECK:   ret i8 [[RESULT:%[0-9]+]]
206 // CHECK: }
207 
208 short test_InterlockedExchangeSub16(short volatile *value, short mask) {
209   return _InterlockedExchangeSub16(value, mask);
210 }
211 // CHECK: define{{.*}}i16 @test_InterlockedExchangeSub16(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
212 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw sub i16* %value, i16 %mask seq_cst
213 // CHECK:   ret i16 [[RESULT:%[0-9]+]]
214 // CHECK: }
215 
216 long test_InterlockedExchangeSub(long volatile *value, long mask) {
217   return _InterlockedExchangeSub(value, mask);
218 }
219 // CHECK: define{{.*}}i32 @test_InterlockedExchangeSub(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
220 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw sub i32* %value, i32 %mask seq_cst
221 // CHECK:   ret i32 [[RESULT:%[0-9]+]]
222 // CHECK: }
223 
224 char test_InterlockedOr8(char volatile *value, char mask) {
225   return _InterlockedOr8(value, mask);
226 }
227 // CHECK: define{{.*}}i8 @test_InterlockedOr8(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
228 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw or i8* %value, i8 %mask seq_cst
229 // CHECK:   ret i8 [[RESULT:%[0-9]+]]
230 // CHECK: }
231 
232 short test_InterlockedOr16(short volatile *value, short mask) {
233   return _InterlockedOr16(value, mask);
234 }
235 // CHECK: define{{.*}}i16 @test_InterlockedOr16(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
236 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw or i16* %value, i16 %mask seq_cst
237 // CHECK:   ret i16 [[RESULT:%[0-9]+]]
238 // CHECK: }
239 
240 long test_InterlockedOr(long volatile *value, long mask) {
241   return _InterlockedOr(value, mask);
242 }
243 // CHECK: define{{.*}}i32 @test_InterlockedOr(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
244 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw or i32* %value, i32 %mask seq_cst
245 // CHECK:   ret i32 [[RESULT:%[0-9]+]]
246 // CHECK: }
247 
248 char test_InterlockedXor8(char volatile *value, char mask) {
249   return _InterlockedXor8(value, mask);
250 }
251 // CHECK: define{{.*}}i8 @test_InterlockedXor8(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
252 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw xor i8* %value, i8 %mask seq_cst
253 // CHECK:   ret i8 [[RESULT:%[0-9]+]]
254 // CHECK: }
255 
256 short test_InterlockedXor16(short volatile *value, short mask) {
257   return _InterlockedXor16(value, mask);
258 }
259 // CHECK: define{{.*}}i16 @test_InterlockedXor16(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
260 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw xor i16* %value, i16 %mask seq_cst
261 // CHECK:   ret i16 [[RESULT:%[0-9]+]]
262 // CHECK: }
263 
264 long test_InterlockedXor(long volatile *value, long mask) {
265   return _InterlockedXor(value, mask);
266 }
267 // CHECK: define{{.*}}i32 @test_InterlockedXor(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
268 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw xor i32* %value, i32 %mask seq_cst
269 // CHECK:   ret i32 [[RESULT:%[0-9]+]]
270 // CHECK: }
271 
272 char test_InterlockedAnd8(char volatile *value, char mask) {
273   return _InterlockedAnd8(value, mask);
274 }
275 // CHECK: define{{.*}}i8 @test_InterlockedAnd8(i8*{{[a-z_ ]*}}%value, i8{{[a-z_ ]*}}%mask){{.*}}{
276 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw and i8* %value, i8 %mask seq_cst
277 // CHECK:   ret i8 [[RESULT:%[0-9]+]]
278 // CHECK: }
279 
280 short test_InterlockedAnd16(short volatile *value, short mask) {
281   return _InterlockedAnd16(value, mask);
282 }
283 // CHECK: define{{.*}}i16 @test_InterlockedAnd16(i16*{{[a-z_ ]*}}%value, i16{{[a-z_ ]*}}%mask){{.*}}{
284 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw and i16* %value, i16 %mask seq_cst
285 // CHECK:   ret i16 [[RESULT:%[0-9]+]]
286 // CHECK: }
287 
288 long test_InterlockedAnd(long volatile *value, long mask) {
289   return _InterlockedAnd(value, mask);
290 }
291 // CHECK: define{{.*}}i32 @test_InterlockedAnd(i32*{{[a-z_ ]*}}%value, i32{{[a-z_ ]*}}%mask){{.*}}{
292 // CHECK:   [[RESULT:%[0-9]+]] = atomicrmw and i32* %value, i32 %mask seq_cst
293 // CHECK:   ret i32 [[RESULT:%[0-9]+]]
294 // CHECK: }
295 
296 char test_InterlockedCompareExchange8(char volatile *Destination, char Exchange, char Comperand) {
297   return _InterlockedCompareExchange8(Destination, Exchange, Comperand);
298 }
299 // CHECK: define{{.*}}i8 @test_InterlockedCompareExchange8(i8*{{[a-z_ ]*}}%Destination, i8{{[a-z_ ]*}}%Exchange, i8{{[a-z_ ]*}}%Comperand){{.*}}{
300 // CHECK: [[TMP:%[0-9]+]] = cmpxchg volatile i8* %Destination, i8 %Comperand, i8 %Exchange seq_cst seq_cst
301 // CHECK: [[RESULT:%[0-9]+]] = extractvalue { i8, i1 } [[TMP]], 0
302 // CHECK: ret i8 [[RESULT]]
303 // CHECK: }
304 
305 short test_InterlockedCompareExchange16(short volatile *Destination, short Exchange, short Comperand) {
306   return _InterlockedCompareExchange16(Destination, Exchange, Comperand);
307 }
308 // CHECK: define{{.*}}i16 @test_InterlockedCompareExchange16(i16*{{[a-z_ ]*}}%Destination, i16{{[a-z_ ]*}}%Exchange, i16{{[a-z_ ]*}}%Comperand){{.*}}{
309 // CHECK: [[TMP:%[0-9]+]] = cmpxchg volatile i16* %Destination, i16 %Comperand, i16 %Exchange seq_cst seq_cst
310 // CHECK: [[RESULT:%[0-9]+]] = extractvalue { i16, i1 } [[TMP]], 0
311 // CHECK: ret i16 [[RESULT]]
312 // CHECK: }
313 
314 long test_InterlockedCompareExchange(long volatile *Destination, long Exchange, long Comperand) {
315   return _InterlockedCompareExchange(Destination, Exchange, Comperand);
316 }
317 // CHECK: define{{.*}}i32 @test_InterlockedCompareExchange(i32*{{[a-z_ ]*}}%Destination, i32{{[a-z_ ]*}}%Exchange, i32{{[a-z_ ]*}}%Comperand){{.*}}{
318 // CHECK: [[TMP:%[0-9]+]] = cmpxchg volatile i32* %Destination, i32 %Comperand, i32 %Exchange seq_cst seq_cst
319 // CHECK: [[RESULT:%[0-9]+]] = extractvalue { i32, i1 } [[TMP]], 0
320 // CHECK: ret i32 [[RESULT]]
321 // CHECK: }
322 
323 __int64 test_InterlockedCompareExchange64(__int64 volatile *Destination, __int64 Exchange, __int64 Comperand) {
324   return _InterlockedCompareExchange64(Destination, Exchange, Comperand);
325 }
326 // CHECK: define{{.*}}i64 @test_InterlockedCompareExchange64(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%Exchange, i64{{[a-z_ ]*}}%Comperand){{.*}}{
327 // CHECK: [[TMP:%[0-9]+]] = cmpxchg volatile i64* %Destination, i64 %Comperand, i64 %Exchange seq_cst seq_cst
328 // CHECK: [[RESULT:%[0-9]+]] = extractvalue { i64, i1 } [[TMP]], 0
329 // CHECK: ret i64 [[RESULT]]
330 // CHECK: }
331 
332 #if defined(__x86_64__)
333 unsigned char test_InterlockedCompareExchange128(__int64 volatile *Destination, __int64 ExchangeHigh, __int64 ExchangeLow, __int64* ComparandResult) {
334   return _InterlockedCompareExchange128(Destination, ExchangeHigh, ExchangeLow, ComparandResult);
335 }
336 // CHECK-X64: define{{.*}}i8 @test_InterlockedCompareExchange128(i64*{{[a-z_ ]*}}%Destination, i64{{[a-z_ ]*}}%ExchangeHigh, i64{{[a-z_ ]*}}%ExchangeLow, i64*{{[a-z_ ]*}}%ComparandResult){{.*}}{
337 // CHECK-X64: [[DST:%[0-9]+]] = bitcast i64* %Destination to i128*
338 // CHECK-X64: [[EH:%[0-9]+]] = zext i64 %ExchangeHigh to i128
339 // CHECK-X64: [[EL:%[0-9]+]] = zext i64 %ExchangeLow to i128
340 // CHECK-X64: [[CNR:%[0-9]+]] = bitcast i64* %ComparandResult to i128*
341 // CHECK-X64: [[EHS:%[0-9]+]] = shl nuw i128 [[EH]], 64
342 // CHECK-X64: [[EXP:%[0-9]+]] = or i128 [[EHS]], [[EL]]
343 // CHECK-X64: [[ORG:%[0-9]+]] = load i128, i128* [[CNR]], align 16
344 // CHECK-X64: [[RES:%[0-9]+]] = cmpxchg volatile i128* [[DST]], i128 [[ORG]], i128 [[EXP]] seq_cst seq_cst
345 // CHECK-X64: [[OLD:%[0-9]+]] = extractvalue { i128, i1 } [[RES]], 0
346 // CHECK-X64: store i128 [[OLD]], i128* [[CNR]], align 16
347 // CHECK-X64: [[SUC1:%[0-9]+]] = extractvalue { i128, i1 } [[RES]], 1
348 // CHECK-X64: [[SUC8:%[0-9]+]] = zext i1 [[SUC1]] to i8
349 // CHECK-X64: ret i8 [[SUC8]]
350 // CHECK-X64: }
351 #endif
352 
353 short test_InterlockedIncrement16(short volatile *Addend) {
354   return _InterlockedIncrement16(Addend);
355 }
356 // CHECK: define{{.*}}i16 @test_InterlockedIncrement16(i16*{{[a-z_ ]*}}%Addend){{.*}}{
357 // CHECK: [[TMP:%[0-9]+]] = atomicrmw add i16* %Addend, i16 1 seq_cst
358 // CHECK: [[RESULT:%[0-9]+]] = add i16 [[TMP]], 1
359 // CHECK: ret i16 [[RESULT]]
360 // CHECK: }
361 
362 long test_InterlockedIncrement(long volatile *Addend) {
363   return _InterlockedIncrement(Addend);
364 }
365 // CHECK: define{{.*}}i32 @test_InterlockedIncrement(i32*{{[a-z_ ]*}}%Addend){{.*}}{
366 // CHECK: [[TMP:%[0-9]+]] = atomicrmw add i32* %Addend, i32 1 seq_cst
367 // CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], 1
368 // CHECK: ret i32 [[RESULT]]
369 // CHECK: }
370 
371 short test_InterlockedDecrement16(short volatile *Addend) {
372   return _InterlockedDecrement16(Addend);
373 }
374 // CHECK: define{{.*}}i16 @test_InterlockedDecrement16(i16*{{[a-z_ ]*}}%Addend){{.*}}{
375 // CHECK: [[TMP:%[0-9]+]] = atomicrmw sub i16* %Addend, i16 1 seq_cst
376 // CHECK: [[RESULT:%[0-9]+]] = add i16 [[TMP]], -1
377 // CHECK: ret i16 [[RESULT]]
378 // CHECK: }
379 
380 long test_InterlockedDecrement(long volatile *Addend) {
381   return _InterlockedDecrement(Addend);
382 }
383 // CHECK: define{{.*}}i32 @test_InterlockedDecrement(i32*{{[a-z_ ]*}}%Addend){{.*}}{
384 // CHECK: [[TMP:%[0-9]+]] = atomicrmw sub i32* %Addend, i32 1 seq_cst
385 // CHECK: [[RESULT:%[0-9]+]] = add i32 [[TMP]], -1
386 // CHECK: ret i32 [[RESULT]]
387 // CHECK: }
388 
389 #if defined(__x86_64__) || defined(__arm__)
390 __int64 test_InterlockedExchange64(__int64 volatile *value, __int64 mask) {
391   return _InterlockedExchange64(value, mask);
392 }
393 // CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedExchange64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
394 // CHECK-ARM-X64:   [[RESULT:%[0-9]+]] = atomicrmw xchg i64* %value, i64 %mask seq_cst
395 // CHECK-ARM-X64:   ret i64 [[RESULT:%[0-9]+]]
396 // CHECK-ARM-X64: }
397 
398 __int64 test_InterlockedExchangeAdd64(__int64 volatile *value, __int64 mask) {
399   return _InterlockedExchangeAdd64(value, mask);
400 }
401 // CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedExchangeAdd64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
402 // CHECK-ARM-X64:   [[RESULT:%[0-9]+]] = atomicrmw add i64* %value, i64 %mask seq_cst
403 // CHECK-ARM-X64:   ret i64 [[RESULT:%[0-9]+]]
404 // CHECK-ARM-X64: }
405 
406 __int64 test_InterlockedExchangeSub64(__int64 volatile *value, __int64 mask) {
407   return _InterlockedExchangeSub64(value, mask);
408 }
409 // CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedExchangeSub64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
410 // CHECK-ARM-X64:   [[RESULT:%[0-9]+]] = atomicrmw sub i64* %value, i64 %mask seq_cst
411 // CHECK-ARM-X64:   ret i64 [[RESULT:%[0-9]+]]
412 // CHECK-ARM-X64: }
413 
414 __int64 test_InterlockedOr64(__int64 volatile *value, __int64 mask) {
415   return _InterlockedOr64(value, mask);
416 }
417 // CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedOr64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
418 // CHECK-ARM-X64:   [[RESULT:%[0-9]+]] = atomicrmw or i64* %value, i64 %mask seq_cst
419 // CHECK-ARM-X64:   ret i64 [[RESULT:%[0-9]+]]
420 // CHECK-ARM-X64: }
421 
422 __int64 test_InterlockedXor64(__int64 volatile *value, __int64 mask) {
423   return _InterlockedXor64(value, mask);
424 }
425 // CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedXor64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
426 // CHECK-ARM-X64:   [[RESULT:%[0-9]+]] = atomicrmw xor i64* %value, i64 %mask seq_cst
427 // CHECK-ARM-X64:   ret i64 [[RESULT:%[0-9]+]]
428 // CHECK-ARM-X64: }
429 
430 __int64 test_InterlockedAnd64(__int64 volatile *value, __int64 mask) {
431   return _InterlockedAnd64(value, mask);
432 }
433 // CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedAnd64(i64*{{[a-z_ ]*}}%value, i64{{[a-z_ ]*}}%mask){{.*}}{
434 // CHECK-ARM-X64:   [[RESULT:%[0-9]+]] = atomicrmw and i64* %value, i64 %mask seq_cst
435 // CHECK-ARM-X64:   ret i64 [[RESULT:%[0-9]+]]
436 // CHECK-ARM-X64: }
437 
438 __int64 test_InterlockedIncrement64(__int64 volatile *Addend) {
439   return _InterlockedIncrement64(Addend);
440 }
441 // CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedIncrement64(i64*{{[a-z_ ]*}}%Addend){{.*}}{
442 // CHECK-ARM-X64: [[TMP:%[0-9]+]] = atomicrmw add i64* %Addend, i64 1 seq_cst
443 // CHECK-ARM-X64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], 1
444 // CHECK-ARM-X64: ret i64 [[RESULT]]
445 // CHECK-ARM-X64: }
446 
447 __int64 test_InterlockedDecrement64(__int64 volatile *Addend) {
448   return _InterlockedDecrement64(Addend);
449 }
450 // CHECK-ARM-X64: define{{.*}}i64 @test_InterlockedDecrement64(i64*{{[a-z_ ]*}}%Addend){{.*}}{
451 // CHECK-ARM-X64: [[TMP:%[0-9]+]] = atomicrmw sub i64* %Addend, i64 1 seq_cst
452 // CHECK-ARM-X64: [[RESULT:%[0-9]+]] = add i64 [[TMP]], -1
453 // CHECK-ARM-X64: ret i64 [[RESULT]]
454 // CHECK-ARM-X64: }
455 
456 #endif
457 
458 unsigned char test_interlockedbittestandset(volatile long *ptr, long bit) {
459   return _interlockedbittestandset(ptr, bit);
460 }
461 // CHECK-LABEL: define{{.*}} i8 @test_interlockedbittestandset
462 // CHECK: [[MASKBIT:%[0-9]+]] = shl i32 1, %bit
463 // CHECK: [[OLD:%[0-9]+]] = atomicrmw or i32* %ptr, i32 [[MASKBIT]] seq_cst
464 // CHECK: [[SHIFT:%[0-9]+]] = lshr i32 [[OLD]], %bit
465 // CHECK: [[TRUNC:%[0-9]+]] = trunc i32 [[SHIFT]] to i8
466 // CHECK: [[AND:%[0-9]+]] = and i8 [[TRUNC]], 1
467 // CHECK: ret i8 [[AND]]
468 
469 void test__fastfail() {
470   __fastfail(42);
471 }
472 // CHECK-LABEL: define{{.*}} void @test__fastfail()
473 // CHECK-ARM: call void asm sideeffect "udf #251", "{r0}"(i32 42) #[[NORETURN:[0-9]+]]
474 // CHECK-INTEL: call void asm sideeffect "int $$0x29", "{cx}"(i32 42) #[[NORETURN]]
475 
476 // Attributes come last.
477 
478 // CHECK: attributes #[[NORETURN]] = { noreturn{{.*}} }
479 
480