xref: /llvm-project/llvm/test/CodeGen/X86/atomic-rm-bit-test.ll (revision e6bf48d11047e970cb24554a01b65b566d6b5d22)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=i686-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=X86
3; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=X64
4
5define zeroext i8 @atomic_shl1_or_8_gpr_val(ptr %v, i8 zeroext %c) nounwind {
6; X86-LABEL: atomic_shl1_or_8_gpr_val:
7; X86:       # %bb.0: # %entry
8; X86-NEXT:    pushl %esi
9; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
10; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
11; X86-NEXT:    movl $1, %edx
12; X86-NEXT:    shll %cl, %edx
13; X86-NEXT:    movzbl (%esi), %eax
14; X86-NEXT:    .p2align 4
15; X86-NEXT:  .LBB0_1: # %atomicrmw.start
16; X86-NEXT:    # =>This Inner Loop Header: Depth=1
17; X86-NEXT:    movl %eax, %ecx
18; X86-NEXT:    orb %dl, %cl
19; X86-NEXT:    lock cmpxchgb %cl, (%esi)
20; X86-NEXT:    jne .LBB0_1
21; X86-NEXT:  # %bb.2: # %atomicrmw.end
22; X86-NEXT:    andb %al, %dl
23; X86-NEXT:    movl %edx, %eax
24; X86-NEXT:    popl %esi
25; X86-NEXT:    retl
26;
27; X64-LABEL: atomic_shl1_or_8_gpr_val:
28; X64:       # %bb.0: # %entry
29; X64-NEXT:    movl %esi, %ecx
30; X64-NEXT:    movl $1, %edx
31; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
32; X64-NEXT:    shll %cl, %edx
33; X64-NEXT:    movzbl (%rdi), %eax
34; X64-NEXT:    .p2align 4
35; X64-NEXT:  .LBB0_1: # %atomicrmw.start
36; X64-NEXT:    # =>This Inner Loop Header: Depth=1
37; X64-NEXT:    movl %eax, %ecx
38; X64-NEXT:    orb %dl, %cl
39; X64-NEXT:    lock cmpxchgb %cl, (%rdi)
40; X64-NEXT:    jne .LBB0_1
41; X64-NEXT:  # %bb.2: # %atomicrmw.end
42; X64-NEXT:    andb %al, %dl
43; X64-NEXT:    movl %edx, %eax
44; X64-NEXT:    retq
45entry:
46  %conv = zext i8 %c to i32
47  %shl = shl nuw i32 1, %conv
48  %conv1 = trunc i32 %shl to i8
49  %0 = atomicrmw or ptr %v, i8 %conv1 monotonic, align 1
50  %conv5 = and i8 %conv1, %0
51  ret i8 %conv5
52}
53
54define zeroext i8 @atomic_shl1_mask0_or_8_gpr_val(ptr %v, i8 zeroext %c) nounwind {
55; X86-LABEL: atomic_shl1_mask0_or_8_gpr_val:
56; X86:       # %bb.0: # %entry
57; X86-NEXT:    pushl %ebx
58; X86-NEXT:    pushl %esi
59; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
60; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
61; X86-NEXT:    movl %edx, %ecx
62; X86-NEXT:    andb $7, %cl
63; X86-NEXT:    movb $1, %ah
64; X86-NEXT:    shlb %cl, %ah
65; X86-NEXT:    movb (%esi), %al
66; X86-NEXT:    .p2align 4
67; X86-NEXT:  .LBB1_1: # %atomicrmw.start
68; X86-NEXT:    # =>This Inner Loop Header: Depth=1
69; X86-NEXT:    movl %eax, %ecx
70; X86-NEXT:    orb %ah, %cl
71; X86-NEXT:    lock cmpxchgb %cl, (%esi)
72; X86-NEXT:    jne .LBB1_1
73; X86-NEXT:  # %bb.2: # %atomicrmw.end
74; X86-NEXT:    movl $1, %ebx
75; X86-NEXT:    movl %edx, %ecx
76; X86-NEXT:    shll %cl, %ebx
77; X86-NEXT:    andb %bl, %al
78; X86-NEXT:    popl %esi
79; X86-NEXT:    popl %ebx
80; X86-NEXT:    retl
81;
82; X64-LABEL: atomic_shl1_mask0_or_8_gpr_val:
83; X64:       # %bb.0: # %entry
84; X64-NEXT:    movl %esi, %ecx
85; X64-NEXT:    andb $7, %cl
86; X64-NEXT:    movb $1, %dl
87; X64-NEXT:    shlb %cl, %dl
88; X64-NEXT:    movzbl (%rdi), %eax
89; X64-NEXT:    .p2align 4
90; X64-NEXT:  .LBB1_1: # %atomicrmw.start
91; X64-NEXT:    # =>This Inner Loop Header: Depth=1
92; X64-NEXT:    movl %eax, %ecx
93; X64-NEXT:    orb %dl, %cl
94; X64-NEXT:    lock cmpxchgb %cl, (%rdi)
95; X64-NEXT:    jne .LBB1_1
96; X64-NEXT:  # %bb.2: # %atomicrmw.end
97; X64-NEXT:    movl $1, %edx
98; X64-NEXT:    movl %esi, %ecx
99; X64-NEXT:    shll %cl, %edx
100; X64-NEXT:    andb %dl, %al
101; X64-NEXT:    retq
102entry:
103  %0 = and i8 %c, 7
104  %shl = shl nuw i8 1, %0
105  %1 = atomicrmw or ptr %v, i8 %shl monotonic, align 1
106  %conv3 = zext i8 %c to i32
107  %shl4 = shl nuw i32 1, %conv3
108  %2 = trunc i32 %shl4 to i8
109  %conv5 = and i8 %1, %2
110  ret i8 %conv5
111}
112
113define zeroext i8 @atomic_shl1_mask01_or_8_gpr_val(ptr %v, i8 zeroext %c) nounwind {
114; X86-LABEL: atomic_shl1_mask01_or_8_gpr_val:
115; X86:       # %bb.0: # %entry
116; X86-NEXT:    pushl %esi
117; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
118; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
119; X86-NEXT:    andb $7, %cl
120; X86-NEXT:    movb $1, %dl
121; X86-NEXT:    shlb %cl, %dl
122; X86-NEXT:    movzbl (%esi), %eax
123; X86-NEXT:    .p2align 4
124; X86-NEXT:  .LBB2_1: # %atomicrmw.start
125; X86-NEXT:    # =>This Inner Loop Header: Depth=1
126; X86-NEXT:    movl %eax, %ecx
127; X86-NEXT:    orb %dl, %cl
128; X86-NEXT:    lock cmpxchgb %cl, (%esi)
129; X86-NEXT:    jne .LBB2_1
130; X86-NEXT:  # %bb.2: # %atomicrmw.end
131; X86-NEXT:    andb %al, %dl
132; X86-NEXT:    movl %edx, %eax
133; X86-NEXT:    popl %esi
134; X86-NEXT:    retl
135;
136; X64-LABEL: atomic_shl1_mask01_or_8_gpr_val:
137; X64:       # %bb.0: # %entry
138; X64-NEXT:    movl %esi, %ecx
139; X64-NEXT:    andb $7, %cl
140; X64-NEXT:    movb $1, %dl
141; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
142; X64-NEXT:    shlb %cl, %dl
143; X64-NEXT:    movzbl (%rdi), %eax
144; X64-NEXT:    .p2align 4
145; X64-NEXT:  .LBB2_1: # %atomicrmw.start
146; X64-NEXT:    # =>This Inner Loop Header: Depth=1
147; X64-NEXT:    movl %eax, %ecx
148; X64-NEXT:    orb %dl, %cl
149; X64-NEXT:    lock cmpxchgb %cl, (%rdi)
150; X64-NEXT:    jne .LBB2_1
151; X64-NEXT:  # %bb.2: # %atomicrmw.end
152; X64-NEXT:    andb %al, %dl
153; X64-NEXT:    movl %edx, %eax
154; X64-NEXT:    retq
155entry:
156  %0 = and i8 %c, 7
157  %shl = shl nuw i8 1, %0
158  %1 = atomicrmw or ptr %v, i8 %shl monotonic, align 1
159  %conv7 = and i8 %shl, %1
160  ret i8 %conv7
161}
162
163define zeroext i8 @atomic_shl1_xor_8_gpr_valz(ptr %v, i8 zeroext %c) nounwind {
164; X86-LABEL: atomic_shl1_xor_8_gpr_valz:
165; X86:       # %bb.0: # %entry
166; X86-NEXT:    pushl %esi
167; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
168; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
169; X86-NEXT:    movl $1, %edx
170; X86-NEXT:    shll %cl, %edx
171; X86-NEXT:    movzbl (%esi), %eax
172; X86-NEXT:    .p2align 4
173; X86-NEXT:  .LBB3_1: # %atomicrmw.start
174; X86-NEXT:    # =>This Inner Loop Header: Depth=1
175; X86-NEXT:    movl %eax, %ecx
176; X86-NEXT:    xorb %dl, %cl
177; X86-NEXT:    lock cmpxchgb %cl, (%esi)
178; X86-NEXT:    jne .LBB3_1
179; X86-NEXT:  # %bb.2: # %atomicrmw.end
180; X86-NEXT:    movzbl %al, %eax
181; X86-NEXT:    testl %eax, %edx
182; X86-NEXT:    sete %al
183; X86-NEXT:    popl %esi
184; X86-NEXT:    retl
185;
186; X64-LABEL: atomic_shl1_xor_8_gpr_valz:
187; X64:       # %bb.0: # %entry
188; X64-NEXT:    movl %esi, %ecx
189; X64-NEXT:    movl $1, %edx
190; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
191; X64-NEXT:    shll %cl, %edx
192; X64-NEXT:    movzbl (%rdi), %eax
193; X64-NEXT:    .p2align 4
194; X64-NEXT:  .LBB3_1: # %atomicrmw.start
195; X64-NEXT:    # =>This Inner Loop Header: Depth=1
196; X64-NEXT:    movl %eax, %ecx
197; X64-NEXT:    xorb %dl, %cl
198; X64-NEXT:    lock cmpxchgb %cl, (%rdi)
199; X64-NEXT:    jne .LBB3_1
200; X64-NEXT:  # %bb.2: # %atomicrmw.end
201; X64-NEXT:    movzbl %al, %eax
202; X64-NEXT:    testl %eax, %edx
203; X64-NEXT:    sete %al
204; X64-NEXT:    retq
205entry:
206  %conv = zext i8 %c to i32
207  %shl = shl nuw i32 1, %conv
208  %conv1 = trunc i32 %shl to i8
209  %0 = atomicrmw xor ptr %v, i8 %conv1 monotonic, align 1
210  %conv2 = zext i8 %0 to i32
211  %and = and i32 %shl, %conv2
212  %tobool.not = icmp eq i32 %and, 0
213  %conv5 = zext i1 %tobool.not to i8
214  ret i8 %conv5
215}
216
217define zeroext i8 @atomic_shl1_mask0_xor_8_gpr_valz(ptr %v, i8 zeroext %c) nounwind {
218; X86-LABEL: atomic_shl1_mask0_xor_8_gpr_valz:
219; X86:       # %bb.0: # %entry
220; X86-NEXT:    pushl %esi
221; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
222; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
223; X86-NEXT:    movl %edx, %ecx
224; X86-NEXT:    andb $7, %cl
225; X86-NEXT:    movb $1, %ah
226; X86-NEXT:    shlb %cl, %ah
227; X86-NEXT:    movb (%esi), %al
228; X86-NEXT:    .p2align 4
229; X86-NEXT:  .LBB4_1: # %atomicrmw.start
230; X86-NEXT:    # =>This Inner Loop Header: Depth=1
231; X86-NEXT:    movl %eax, %ecx
232; X86-NEXT:    xorb %ah, %cl
233; X86-NEXT:    lock cmpxchgb %cl, (%esi)
234; X86-NEXT:    jne .LBB4_1
235; X86-NEXT:  # %bb.2: # %atomicrmw.end
236; X86-NEXT:    movzbl %al, %eax
237; X86-NEXT:    movzbl %dl, %ecx
238; X86-NEXT:    btl %ecx, %eax
239; X86-NEXT:    setae %al
240; X86-NEXT:    popl %esi
241; X86-NEXT:    retl
242;
243; X64-LABEL: atomic_shl1_mask0_xor_8_gpr_valz:
244; X64:       # %bb.0: # %entry
245; X64-NEXT:    movl %esi, %ecx
246; X64-NEXT:    andb $7, %cl
247; X64-NEXT:    movb $1, %dl
248; X64-NEXT:    shlb %cl, %dl
249; X64-NEXT:    movzbl (%rdi), %eax
250; X64-NEXT:    .p2align 4
251; X64-NEXT:  .LBB4_1: # %atomicrmw.start
252; X64-NEXT:    # =>This Inner Loop Header: Depth=1
253; X64-NEXT:    movl %eax, %ecx
254; X64-NEXT:    xorb %dl, %cl
255; X64-NEXT:    lock cmpxchgb %cl, (%rdi)
256; X64-NEXT:    jne .LBB4_1
257; X64-NEXT:  # %bb.2: # %atomicrmw.end
258; X64-NEXT:    movzbl %al, %eax
259; X64-NEXT:    movzbl %sil, %ecx
260; X64-NEXT:    btl %ecx, %eax
261; X64-NEXT:    setae %al
262; X64-NEXT:    retq
263entry:
264  %0 = and i8 %c, 7
265  %shl = shl nuw i8 1, %0
266  %1 = atomicrmw xor ptr %v, i8 %shl monotonic, align 1
267  %conv2 = zext i8 %1 to i32
268  %conv3 = zext i8 %c to i32
269  %shl4 = shl nuw i32 1, %conv3
270  %and = and i32 %shl4, %conv2
271  %tobool.not = icmp eq i32 %and, 0
272  %conv5 = zext i1 %tobool.not to i8
273  ret i8 %conv5
274}
275
276define zeroext i8 @atomic_shl1_mask01_xor_8_gpr_valz(ptr %v, i8 zeroext %c) nounwind {
277; X86-LABEL: atomic_shl1_mask01_xor_8_gpr_valz:
278; X86:       # %bb.0: # %entry
279; X86-NEXT:    pushl %ebx
280; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
281; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
282; X86-NEXT:    andb $7, %cl
283; X86-NEXT:    movl $1, %ebx
284; X86-NEXT:    shll %cl, %ebx
285; X86-NEXT:    movzbl (%edx), %eax
286; X86-NEXT:    .p2align 4
287; X86-NEXT:  .LBB5_1: # %atomicrmw.start
288; X86-NEXT:    # =>This Inner Loop Header: Depth=1
289; X86-NEXT:    movl %eax, %ecx
290; X86-NEXT:    xorb %bl, %cl
291; X86-NEXT:    lock cmpxchgb %cl, (%edx)
292; X86-NEXT:    jne .LBB5_1
293; X86-NEXT:  # %bb.2: # %atomicrmw.end
294; X86-NEXT:    movzbl %al, %eax
295; X86-NEXT:    testl %eax, %ebx
296; X86-NEXT:    sete %al
297; X86-NEXT:    popl %ebx
298; X86-NEXT:    retl
299;
300; X64-LABEL: atomic_shl1_mask01_xor_8_gpr_valz:
301; X64:       # %bb.0: # %entry
302; X64-NEXT:    movl %esi, %ecx
303; X64-NEXT:    andb $7, %cl
304; X64-NEXT:    movl $1, %edx
305; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
306; X64-NEXT:    shll %cl, %edx
307; X64-NEXT:    movzbl (%rdi), %eax
308; X64-NEXT:    .p2align 4
309; X64-NEXT:  .LBB5_1: # %atomicrmw.start
310; X64-NEXT:    # =>This Inner Loop Header: Depth=1
311; X64-NEXT:    movl %eax, %ecx
312; X64-NEXT:    xorb %dl, %cl
313; X64-NEXT:    lock cmpxchgb %cl, (%rdi)
314; X64-NEXT:    jne .LBB5_1
315; X64-NEXT:  # %bb.2: # %atomicrmw.end
316; X64-NEXT:    movzbl %al, %eax
317; X64-NEXT:    testl %eax, %edx
318; X64-NEXT:    sete %al
319; X64-NEXT:    retq
320entry:
321  %0 = and i8 %c, 7
322  %sh_prom = zext i8 %0 to i32
323  %shl = shl nuw nsw i32 1, %sh_prom
324  %conv1 = trunc i32 %shl to i8
325  %1 = atomicrmw xor ptr %v, i8 %conv1 monotonic, align 1
326  %conv2 = zext i8 %1 to i32
327  %and = and i32 %shl, %conv2
328  %tobool.not = icmp eq i32 %and, 0
329  %conv7 = zext i1 %tobool.not to i8
330  ret i8 %conv7
331}
332
333define zeroext i8 @atomic_shl1_and_8_gpr_brnz(ptr %v, i8 zeroext %c) nounwind {
334; X86-LABEL: atomic_shl1_and_8_gpr_brnz:
335; X86:       # %bb.0: # %entry
336; X86-NEXT:    pushl %ebx
337; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
338; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
339; X86-NEXT:    movl $1, %ebx
340; X86-NEXT:    shll %cl, %ebx
341; X86-NEXT:    movb %bl, %ah
342; X86-NEXT:    notb %ah
343; X86-NEXT:    movb (%edx), %al
344; X86-NEXT:    .p2align 4
345; X86-NEXT:  .LBB6_1: # %atomicrmw.start
346; X86-NEXT:    # =>This Inner Loop Header: Depth=1
347; X86-NEXT:    movb %al, %ch
348; X86-NEXT:    andb %ah, %ch
349; X86-NEXT:    lock cmpxchgb %ch, (%edx)
350; X86-NEXT:    jne .LBB6_1
351; X86-NEXT:  # %bb.2: # %atomicrmw.end
352; X86-NEXT:    movzbl %al, %eax
353; X86-NEXT:    testl %eax, %ebx
354; X86-NEXT:    je .LBB6_3
355; X86-NEXT:  # %bb.4: # %if.then
356; X86-NEXT:    movzbl %cl, %eax
357; X86-NEXT:    movzbl (%edx,%eax), %eax
358; X86-NEXT:    popl %ebx
359; X86-NEXT:    retl
360; X86-NEXT:  .LBB6_3:
361; X86-NEXT:    movb $123, %al
362; X86-NEXT:    popl %ebx
363; X86-NEXT:    retl
364;
365; X64-LABEL: atomic_shl1_and_8_gpr_brnz:
366; X64:       # %bb.0: # %entry
367; X64-NEXT:    movl %esi, %ecx
368; X64-NEXT:    movl $1, %edx
369; X64-NEXT:    shll %cl, %edx
370; X64-NEXT:    movl %edx, %esi
371; X64-NEXT:    notb %sil
372; X64-NEXT:    movzbl (%rdi), %eax
373; X64-NEXT:    .p2align 4
374; X64-NEXT:  .LBB6_1: # %atomicrmw.start
375; X64-NEXT:    # =>This Inner Loop Header: Depth=1
376; X64-NEXT:    movl %eax, %r8d
377; X64-NEXT:    andb %sil, %r8b
378; X64-NEXT:    lock cmpxchgb %r8b, (%rdi)
379; X64-NEXT:    jne .LBB6_1
380; X64-NEXT:  # %bb.2: # %atomicrmw.end
381; X64-NEXT:    movzbl %al, %eax
382; X64-NEXT:    testl %eax, %edx
383; X64-NEXT:    je .LBB6_3
384; X64-NEXT:  # %bb.4: # %if.then
385; X64-NEXT:    movzbl %cl, %eax
386; X64-NEXT:    movzbl (%rdi,%rax), %eax
387; X64-NEXT:    retq
388; X64-NEXT:  .LBB6_3:
389; X64-NEXT:    movb $123, %al
390; X64-NEXT:    retq
391entry:
392  %conv = zext i8 %c to i32
393  %shl = shl nuw i32 1, %conv
394  %0 = trunc i32 %shl to i8
395  %conv1 = xor i8 %0, -1
396  %1 = atomicrmw and ptr %v, i8 %conv1 monotonic, align 1
397  %conv2 = zext i8 %1 to i32
398  %and = and i32 %shl, %conv2
399  %tobool.not = icmp eq i32 %and, 0
400  br i1 %tobool.not, label %return, label %if.then
401
402if.then:                                          ; preds = %entry
403  %idxprom = zext i8 %c to i64
404  %arrayidx = getelementptr inbounds i8, ptr %v, i64 %idxprom
405  %2 = load i8, ptr %arrayidx, align 1
406  br label %return
407
408return:                                           ; preds = %entry, %if.then
409  %retval.0 = phi i8 [ %2, %if.then ], [ 123, %entry ]
410  ret i8 %retval.0
411}
412
413define zeroext i8 @atomic_shl1_mask0_and_8_gpr_brnz(ptr %v, i8 zeroext %c) nounwind {
414; X86-LABEL: atomic_shl1_mask0_and_8_gpr_brnz:
415; X86:       # %bb.0: # %entry
416; X86-NEXT:    pushl %esi
417; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
418; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
419; X86-NEXT:    movb $-2, %ah
420; X86-NEXT:    rolb %cl, %ah
421; X86-NEXT:    movb (%edx), %al
422; X86-NEXT:    .p2align 4
423; X86-NEXT:  .LBB7_1: # %atomicrmw.start
424; X86-NEXT:    # =>This Inner Loop Header: Depth=1
425; X86-NEXT:    movb %al, %ch
426; X86-NEXT:    andb %ah, %ch
427; X86-NEXT:    lock cmpxchgb %ch, (%edx)
428; X86-NEXT:    jne .LBB7_1
429; X86-NEXT:  # %bb.2: # %atomicrmw.end
430; X86-NEXT:    movzbl %al, %esi
431; X86-NEXT:    movzbl %cl, %eax
432; X86-NEXT:    btl %eax, %esi
433; X86-NEXT:    jae .LBB7_3
434; X86-NEXT:  # %bb.4: # %if.then
435; X86-NEXT:    movzbl (%edx,%eax), %eax
436; X86-NEXT:    popl %esi
437; X86-NEXT:    retl
438; X86-NEXT:  .LBB7_3:
439; X86-NEXT:    movb $123, %al
440; X86-NEXT:    popl %esi
441; X86-NEXT:    retl
442;
443; X64-LABEL: atomic_shl1_mask0_and_8_gpr_brnz:
444; X64:       # %bb.0: # %entry
445; X64-NEXT:    movl %esi, %ecx
446; X64-NEXT:    movb $-2, %dl
447; X64-NEXT:    rolb %cl, %dl
448; X64-NEXT:    movzbl (%rdi), %eax
449; X64-NEXT:    .p2align 4
450; X64-NEXT:  .LBB7_1: # %atomicrmw.start
451; X64-NEXT:    # =>This Inner Loop Header: Depth=1
452; X64-NEXT:    movl %eax, %esi
453; X64-NEXT:    andb %dl, %sil
454; X64-NEXT:    lock cmpxchgb %sil, (%rdi)
455; X64-NEXT:    jne .LBB7_1
456; X64-NEXT:  # %bb.2: # %atomicrmw.end
457; X64-NEXT:    movzbl %al, %edx
458; X64-NEXT:    movzbl %cl, %eax
459; X64-NEXT:    btl %eax, %edx
460; X64-NEXT:    jae .LBB7_3
461; X64-NEXT:  # %bb.4: # %if.then
462; X64-NEXT:    movzbl (%rdi,%rax), %eax
463; X64-NEXT:    retq
464; X64-NEXT:  .LBB7_3:
465; X64-NEXT:    movb $123, %al
466; X64-NEXT:    retq
467entry:
468  %0 = and i8 %c, 7
469  %shl = shl nuw i8 1, %0
470  %not = xor i8 %shl, -1
471  %1 = atomicrmw and ptr %v, i8 %not monotonic, align 1
472  %conv2 = zext i8 %1 to i32
473  %conv3 = zext i8 %c to i32
474  %shl4 = shl nuw i32 1, %conv3
475  %and = and i32 %shl4, %conv2
476  %tobool.not = icmp eq i32 %and, 0
477  br i1 %tobool.not, label %return, label %if.then
478
479if.then:                                          ; preds = %entry
480  %conv = zext i8 %c to i64
481  %arrayidx = getelementptr inbounds i8, ptr %v, i64 %conv
482  %2 = load i8, ptr %arrayidx, align 1
483  br label %return
484
485return:                                           ; preds = %entry, %if.then
486  %retval.0 = phi i8 [ %2, %if.then ], [ 123, %entry ]
487  ret i8 %retval.0
488}
489
490define zeroext i8 @atomic_shl1_mask01_and_8_gpr_brnz(ptr %v, i8 zeroext %c) nounwind {
491; X86-LABEL: atomic_shl1_mask01_and_8_gpr_brnz:
492; X86:       # %bb.0: # %entry
493; X86-NEXT:    pushl %ebx
494; X86-NEXT:    movb {{[0-9]+}}(%esp), %ah
495; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
496; X86-NEXT:    movb %ah, %cl
497; X86-NEXT:    andb $7, %cl
498; X86-NEXT:    movl $1, %ebx
499; X86-NEXT:    shll %cl, %ebx
500; X86-NEXT:    movl %ebx, %ecx
501; X86-NEXT:    notb %cl
502; X86-NEXT:    movb (%edx), %al
503; X86-NEXT:    .p2align 4
504; X86-NEXT:  .LBB8_1: # %atomicrmw.start
505; X86-NEXT:    # =>This Inner Loop Header: Depth=1
506; X86-NEXT:    movb %al, %ch
507; X86-NEXT:    andb %cl, %ch
508; X86-NEXT:    lock cmpxchgb %ch, (%edx)
509; X86-NEXT:    jne .LBB8_1
510; X86-NEXT:  # %bb.2: # %atomicrmw.end
511; X86-NEXT:    movzbl %al, %ecx
512; X86-NEXT:    testl %ecx, %ebx
513; X86-NEXT:    je .LBB8_3
514; X86-NEXT:  # %bb.4: # %if.then
515; X86-NEXT:    movzbl %ah, %eax
516; X86-NEXT:    movzbl (%edx,%eax), %eax
517; X86-NEXT:    popl %ebx
518; X86-NEXT:    retl
519; X86-NEXT:  .LBB8_3:
520; X86-NEXT:    movb $123, %al
521; X86-NEXT:    popl %ebx
522; X86-NEXT:    retl
523;
524; X64-LABEL: atomic_shl1_mask01_and_8_gpr_brnz:
525; X64:       # %bb.0: # %entry
526; X64-NEXT:    movl %esi, %ecx
527; X64-NEXT:    andb $7, %cl
528; X64-NEXT:    movl $1, %edx
529; X64-NEXT:    shll %cl, %edx
530; X64-NEXT:    movl %edx, %ecx
531; X64-NEXT:    notb %cl
532; X64-NEXT:    movzbl (%rdi), %eax
533; X64-NEXT:    .p2align 4
534; X64-NEXT:  .LBB8_1: # %atomicrmw.start
535; X64-NEXT:    # =>This Inner Loop Header: Depth=1
536; X64-NEXT:    movl %eax, %r8d
537; X64-NEXT:    andb %cl, %r8b
538; X64-NEXT:    lock cmpxchgb %r8b, (%rdi)
539; X64-NEXT:    jne .LBB8_1
540; X64-NEXT:  # %bb.2: # %atomicrmw.end
541; X64-NEXT:    movzbl %al, %eax
542; X64-NEXT:    testl %eax, %edx
543; X64-NEXT:    je .LBB8_3
544; X64-NEXT:  # %bb.4: # %if.then
545; X64-NEXT:    movzbl %sil, %eax
546; X64-NEXT:    movzbl (%rdi,%rax), %eax
547; X64-NEXT:    retq
548; X64-NEXT:  .LBB8_3:
549; X64-NEXT:    movb $123, %al
550; X64-NEXT:    retq
551entry:
552  %0 = and i8 %c, 7
553  %sh_prom = zext i8 %0 to i32
554  %shl = shl nuw nsw i32 1, %sh_prom
555  %1 = trunc i32 %shl to i8
556  %conv1 = xor i8 %1, -1
557  %2 = atomicrmw and ptr %v, i8 %conv1 monotonic, align 1
558  %conv2 = zext i8 %2 to i32
559  %and = and i32 %shl, %conv2
560  %tobool.not = icmp eq i32 %and, 0
561  br i1 %tobool.not, label %return, label %if.then
562
563if.then:                                          ; preds = %entry
564  %conv = zext i8 %c to i64
565  %arrayidx = getelementptr inbounds i8, ptr %v, i64 %conv
566  %3 = load i8, ptr %arrayidx, align 1
567  br label %return
568
569return:                                           ; preds = %entry, %if.then
570  %retval.0 = phi i8 [ %3, %if.then ], [ 123, %entry ]
571  ret i8 %retval.0
572}
573
574define zeroext i8 @atomic_shl1_and_8_gpr_val(ptr %v) nounwind {
575; X86-LABEL: atomic_shl1_and_8_gpr_val:
576; X86:       # %bb.0: # %entry
577; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
578; X86-NEXT:    movzbl (%ecx), %eax
579; X86-NEXT:    .p2align 4
580; X86-NEXT:  .LBB9_1: # %atomicrmw.start
581; X86-NEXT:    # =>This Inner Loop Header: Depth=1
582; X86-NEXT:    movl %eax, %edx
583; X86-NEXT:    andb $-17, %dl
584; X86-NEXT:    lock cmpxchgb %dl, (%ecx)
585; X86-NEXT:    jne .LBB9_1
586; X86-NEXT:  # %bb.2: # %atomicrmw.end
587; X86-NEXT:    andb $16, %al
588; X86-NEXT:    retl
589;
590; X64-LABEL: atomic_shl1_and_8_gpr_val:
591; X64:       # %bb.0: # %entry
592; X64-NEXT:    movzbl (%rdi), %eax
593; X64-NEXT:    .p2align 4
594; X64-NEXT:  .LBB9_1: # %atomicrmw.start
595; X64-NEXT:    # =>This Inner Loop Header: Depth=1
596; X64-NEXT:    movl %eax, %ecx
597; X64-NEXT:    andb $-17, %cl
598; X64-NEXT:    lock cmpxchgb %cl, (%rdi)
599; X64-NEXT:    jne .LBB9_1
600; X64-NEXT:  # %bb.2: # %atomicrmw.end
601; X64-NEXT:    andb $16, %al
602; X64-NEXT:    retq
603entry:
604  %0 = atomicrmw and ptr %v, i8 -17 monotonic, align 1
605  %1 = and i8 %0, 16
606  ret i8 %1
607}
608
609define zeroext i8 @atomic_shl1_or_8_gpr_valnz(ptr %v) nounwind {
610; X86-LABEL: atomic_shl1_or_8_gpr_valnz:
611; X86:       # %bb.0: # %entry
612; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
613; X86-NEXT:    movzbl (%ecx), %eax
614; X86-NEXT:    .p2align 4
615; X86-NEXT:  .LBB10_1: # %atomicrmw.start
616; X86-NEXT:    # =>This Inner Loop Header: Depth=1
617; X86-NEXT:    movl %eax, %edx
618; X86-NEXT:    orb $16, %dl
619; X86-NEXT:    lock cmpxchgb %dl, (%ecx)
620; X86-NEXT:    jne .LBB10_1
621; X86-NEXT:  # %bb.2: # %atomicrmw.end
622; X86-NEXT:    shrb $4, %al
623; X86-NEXT:    andb $1, %al
624; X86-NEXT:    retl
625;
626; X64-LABEL: atomic_shl1_or_8_gpr_valnz:
627; X64:       # %bb.0: # %entry
628; X64-NEXT:    movzbl (%rdi), %eax
629; X64-NEXT:    .p2align 4
630; X64-NEXT:  .LBB10_1: # %atomicrmw.start
631; X64-NEXT:    # =>This Inner Loop Header: Depth=1
632; X64-NEXT:    movl %eax, %ecx
633; X64-NEXT:    orb $16, %cl
634; X64-NEXT:    lock cmpxchgb %cl, (%rdi)
635; X64-NEXT:    jne .LBB10_1
636; X64-NEXT:  # %bb.2: # %atomicrmw.end
637; X64-NEXT:    shrb $4, %al
638; X64-NEXT:    andb $1, %al
639; X64-NEXT:    retq
640entry:
641  %0 = atomicrmw or ptr %v, i8 16 monotonic, align 1
642  %1 = lshr i8 %0, 4
643  %.lobit = and i8 %1, 1
644  ret i8 %.lobit
645}
646
647define zeroext i8 @atomic_shl1_xor_8_gpr_brz(ptr %v) nounwind {
648; X86-LABEL: atomic_shl1_xor_8_gpr_brz:
649; X86:       # %bb.0: # %entry
650; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
651; X86-NEXT:    movzbl (%edx), %eax
652; X86-NEXT:    .p2align 4
653; X86-NEXT:  .LBB11_1: # %atomicrmw.start
654; X86-NEXT:    # =>This Inner Loop Header: Depth=1
655; X86-NEXT:    movl %eax, %ecx
656; X86-NEXT:    xorb $16, %cl
657; X86-NEXT:    lock cmpxchgb %cl, (%edx)
658; X86-NEXT:    jne .LBB11_1
659; X86-NEXT:  # %bb.2: # %atomicrmw.end
660; X86-NEXT:    movb $123, %cl
661; X86-NEXT:    testb $16, %al
662; X86-NEXT:    jne .LBB11_4
663; X86-NEXT:  # %bb.3: # %if.then
664; X86-NEXT:    movzbl 4(%edx), %ecx
665; X86-NEXT:  .LBB11_4: # %return
666; X86-NEXT:    movl %ecx, %eax
667; X86-NEXT:    retl
668;
669; X64-LABEL: atomic_shl1_xor_8_gpr_brz:
670; X64:       # %bb.0: # %entry
671; X64-NEXT:    movzbl (%rdi), %eax
672; X64-NEXT:    .p2align 4
673; X64-NEXT:  .LBB11_1: # %atomicrmw.start
674; X64-NEXT:    # =>This Inner Loop Header: Depth=1
675; X64-NEXT:    movl %eax, %ecx
676; X64-NEXT:    xorb $16, %cl
677; X64-NEXT:    lock cmpxchgb %cl, (%rdi)
678; X64-NEXT:    jne .LBB11_1
679; X64-NEXT:  # %bb.2: # %atomicrmw.end
680; X64-NEXT:    movb $123, %cl
681; X64-NEXT:    testb $16, %al
682; X64-NEXT:    jne .LBB11_4
683; X64-NEXT:  # %bb.3: # %if.then
684; X64-NEXT:    movzbl 4(%rdi), %ecx
685; X64-NEXT:  .LBB11_4: # %return
686; X64-NEXT:    movl %ecx, %eax
687; X64-NEXT:    retq
688entry:
689  %0 = atomicrmw xor ptr %v, i8 16 monotonic, align 1
690  %1 = and i8 %0, 16
691  %tobool.not = icmp eq i8 %1, 0
692  br i1 %tobool.not, label %if.then, label %return
693
694if.then:                                          ; preds = %entry
695  %arrayidx = getelementptr inbounds i8, ptr %v, i64 4
696  %2 = load i8, ptr %arrayidx, align 1
697  br label %return
698
699return:                                           ; preds = %entry, %if.then
700  %retval.0 = phi i8 [ %2, %if.then ], [ 123, %entry ]
701  ret i8 %retval.0
702}
703
704define zeroext i16 @atomic_shl1_xor_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
705; X86-LABEL: atomic_shl1_xor_16_gpr_val:
706; X86:       # %bb.0: # %entry
707; X86-NEXT:    pushl %esi
708; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
709; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
710; X86-NEXT:    movl $1, %edx
711; X86-NEXT:    shll %cl, %edx
712; X86-NEXT:    movzwl (%esi), %eax
713; X86-NEXT:    .p2align 4
714; X86-NEXT:  .LBB12_1: # %atomicrmw.start
715; X86-NEXT:    # =>This Inner Loop Header: Depth=1
716; X86-NEXT:    movl %eax, %ecx
717; X86-NEXT:    xorl %edx, %ecx
718; X86-NEXT:    # kill: def $ax killed $ax killed $eax
719; X86-NEXT:    lock cmpxchgw %cx, (%esi)
720; X86-NEXT:    # kill: def $ax killed $ax def $eax
721; X86-NEXT:    jne .LBB12_1
722; X86-NEXT:  # %bb.2: # %atomicrmw.end
723; X86-NEXT:    andl %edx, %eax
724; X86-NEXT:    # kill: def $ax killed $ax killed $eax
725; X86-NEXT:    popl %esi
726; X86-NEXT:    retl
727;
728; X64-LABEL: atomic_shl1_xor_16_gpr_val:
729; X64:       # %bb.0: # %entry
730; X64-NEXT:    movl %esi, %ecx
731; X64-NEXT:    movl $1, %edx
732; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
733; X64-NEXT:    shll %cl, %edx
734; X64-NEXT:    movzwl (%rdi), %eax
735; X64-NEXT:    .p2align 4
736; X64-NEXT:  .LBB12_1: # %atomicrmw.start
737; X64-NEXT:    # =>This Inner Loop Header: Depth=1
738; X64-NEXT:    movl %eax, %ecx
739; X64-NEXT:    xorl %edx, %ecx
740; X64-NEXT:    # kill: def $ax killed $ax killed $eax
741; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
742; X64-NEXT:    # kill: def $ax killed $ax def $eax
743; X64-NEXT:    jne .LBB12_1
744; X64-NEXT:  # %bb.2: # %atomicrmw.end
745; X64-NEXT:    andl %edx, %eax
746; X64-NEXT:    # kill: def $ax killed $ax killed $eax
747; X64-NEXT:    retq
748entry:
749  %conv = zext i16 %c to i32
750  %shl = shl nuw i32 1, %conv
751  %conv1 = trunc i32 %shl to i16
752  %0 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
753  %conv5 = and i16 %0, %conv1
754  ret i16 %conv5
755}
756
757define zeroext i16 @atomic_shl1_small_mask_xor_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
758; X86-LABEL: atomic_shl1_small_mask_xor_16_gpr_val:
759; X86:       # %bb.0: # %entry
760; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
761; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
762; X86-NEXT:    andl $7, %ecx
763; X86-NEXT:    xorl %eax, %eax
764; X86-NEXT:    lock btcw %cx, (%edx)
765; X86-NEXT:    setb %al
766; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
767; X86-NEXT:    shll %cl, %eax
768; X86-NEXT:    # kill: def $ax killed $ax killed $eax
769; X86-NEXT:    retl
770;
771; X64-LABEL: atomic_shl1_small_mask_xor_16_gpr_val:
772; X64:       # %bb.0: # %entry
773; X64-NEXT:    movl %esi, %ecx
774; X64-NEXT:    andl $7, %ecx
775; X64-NEXT:    xorl %eax, %eax
776; X64-NEXT:    lock btcw %cx, (%rdi)
777; X64-NEXT:    setb %al
778; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
779; X64-NEXT:    shll %cl, %eax
780; X64-NEXT:    # kill: def $ax killed $ax killed $eax
781; X64-NEXT:    retq
782entry:
783  %0 = and i16 %c, 7
784  %shl = shl nuw nsw i16 1, %0
785  %1 = atomicrmw xor ptr %v, i16 %shl monotonic, align 2
786  %and = and i16 %shl, %1
787  ret i16 %and
788}
789
790define zeroext i16 @atomic_shl1_mask0_xor_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
791; X86-LABEL: atomic_shl1_mask0_xor_16_gpr_val:
792; X86:       # %bb.0: # %entry
793; X86-NEXT:    pushl %edi
794; X86-NEXT:    pushl %esi
795; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
796; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
797; X86-NEXT:    movl %edx, %ecx
798; X86-NEXT:    andb $15, %cl
799; X86-NEXT:    movl $1, %edi
800; X86-NEXT:    shll %cl, %edi
801; X86-NEXT:    movzwl (%esi), %eax
802; X86-NEXT:    .p2align 4
803; X86-NEXT:  .LBB14_1: # %atomicrmw.start
804; X86-NEXT:    # =>This Inner Loop Header: Depth=1
805; X86-NEXT:    movl %eax, %ecx
806; X86-NEXT:    xorl %edi, %ecx
807; X86-NEXT:    # kill: def $ax killed $ax killed $eax
808; X86-NEXT:    lock cmpxchgw %cx, (%esi)
809; X86-NEXT:    # kill: def $ax killed $ax def $eax
810; X86-NEXT:    jne .LBB14_1
811; X86-NEXT:  # %bb.2: # %atomicrmw.end
812; X86-NEXT:    movl $1, %esi
813; X86-NEXT:    movl %edx, %ecx
814; X86-NEXT:    shll %cl, %esi
815; X86-NEXT:    andl %esi, %eax
816; X86-NEXT:    # kill: def $ax killed $ax killed $eax
817; X86-NEXT:    popl %esi
818; X86-NEXT:    popl %edi
819; X86-NEXT:    retl
820;
821; X64-LABEL: atomic_shl1_mask0_xor_16_gpr_val:
822; X64:       # %bb.0: # %entry
823; X64-NEXT:    movl %esi, %ecx
824; X64-NEXT:    andb $15, %cl
825; X64-NEXT:    movl $1, %edx
826; X64-NEXT:    shll %cl, %edx
827; X64-NEXT:    movzwl (%rdi), %eax
828; X64-NEXT:    .p2align 4
829; X64-NEXT:  .LBB14_1: # %atomicrmw.start
830; X64-NEXT:    # =>This Inner Loop Header: Depth=1
831; X64-NEXT:    movl %eax, %ecx
832; X64-NEXT:    xorl %edx, %ecx
833; X64-NEXT:    # kill: def $ax killed $ax killed $eax
834; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
835; X64-NEXT:    # kill: def $ax killed $ax def $eax
836; X64-NEXT:    jne .LBB14_1
837; X64-NEXT:  # %bb.2: # %atomicrmw.end
838; X64-NEXT:    movl $1, %edx
839; X64-NEXT:    movl %esi, %ecx
840; X64-NEXT:    shll %cl, %edx
841; X64-NEXT:    andl %edx, %eax
842; X64-NEXT:    # kill: def $ax killed $ax killed $eax
843; X64-NEXT:    retq
844entry:
845  %0 = and i16 %c, 15
846  %shl = shl nuw i16 1, %0
847  %1 = atomicrmw xor ptr %v, i16 %shl monotonic, align 2
848  %conv3 = zext i16 %c to i32
849  %shl4 = shl nuw i32 1, %conv3
850  %2 = trunc i32 %shl4 to i16
851  %conv5 = and i16 %1, %2
852  ret i16 %conv5
853}
854
855define zeroext i16 @atomic_shl1_mask1_xor_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
856; X86-LABEL: atomic_shl1_mask1_xor_16_gpr_val:
857; X86:       # %bb.0: # %entry
858; X86-NEXT:    pushl %edi
859; X86-NEXT:    pushl %esi
860; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
861; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
862; X86-NEXT:    movl $1, %esi
863; X86-NEXT:    shll %cl, %esi
864; X86-NEXT:    movzwl (%edx), %eax
865; X86-NEXT:    .p2align 4
866; X86-NEXT:  .LBB15_1: # %atomicrmw.start
867; X86-NEXT:    # =>This Inner Loop Header: Depth=1
868; X86-NEXT:    movl %eax, %edi
869; X86-NEXT:    xorl %esi, %edi
870; X86-NEXT:    # kill: def $ax killed $ax killed $eax
871; X86-NEXT:    lock cmpxchgw %di, (%edx)
872; X86-NEXT:    # kill: def $ax killed $ax def $eax
873; X86-NEXT:    jne .LBB15_1
874; X86-NEXT:  # %bb.2: # %atomicrmw.end
875; X86-NEXT:    andb $15, %cl
876; X86-NEXT:    movl $1, %edx
877; X86-NEXT:    # kill: def $cl killed $cl killed $cx
878; X86-NEXT:    shll %cl, %edx
879; X86-NEXT:    andl %edx, %eax
880; X86-NEXT:    # kill: def $ax killed $ax killed $eax
881; X86-NEXT:    popl %esi
882; X86-NEXT:    popl %edi
883; X86-NEXT:    retl
884;
885; X64-LABEL: atomic_shl1_mask1_xor_16_gpr_val:
886; X64:       # %bb.0: # %entry
887; X64-NEXT:    movl %esi, %ecx
888; X64-NEXT:    movl $1, %edx
889; X64-NEXT:    shll %cl, %edx
890; X64-NEXT:    movzwl (%rdi), %eax
891; X64-NEXT:    .p2align 4
892; X64-NEXT:  .LBB15_1: # %atomicrmw.start
893; X64-NEXT:    # =>This Inner Loop Header: Depth=1
894; X64-NEXT:    movl %eax, %esi
895; X64-NEXT:    xorl %edx, %esi
896; X64-NEXT:    # kill: def $ax killed $ax killed $eax
897; X64-NEXT:    lock cmpxchgw %si, (%rdi)
898; X64-NEXT:    # kill: def $ax killed $ax def $eax
899; X64-NEXT:    jne .LBB15_1
900; X64-NEXT:  # %bb.2: # %atomicrmw.end
901; X64-NEXT:    andb $15, %cl
902; X64-NEXT:    movl $1, %edx
903; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
904; X64-NEXT:    shll %cl, %edx
905; X64-NEXT:    andl %edx, %eax
906; X64-NEXT:    # kill: def $ax killed $ax killed $eax
907; X64-NEXT:    retq
908entry:
909  %conv = zext i16 %c to i32
910  %shl = shl nuw i32 1, %conv
911  %conv1 = trunc i32 %shl to i16
912  %0 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
913  %1 = and i16 %c, 15
914  %shl4 = shl nuw i16 1, %1
915  %and = and i16 %0, %shl4
916  ret i16 %and
917}
918
919define zeroext i16 @atomic_shl1_mask01_xor_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
920; X86-LABEL: atomic_shl1_mask01_xor_16_gpr_val:
921; X86:       # %bb.0: # %entry
922; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
923; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
924; X86-NEXT:    andl $15, %ecx
925; X86-NEXT:    xorl %eax, %eax
926; X86-NEXT:    lock btcw %cx, (%edx)
927; X86-NEXT:    setb %al
928; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
929; X86-NEXT:    shll %cl, %eax
930; X86-NEXT:    # kill: def $ax killed $ax killed $eax
931; X86-NEXT:    retl
932;
933; X64-LABEL: atomic_shl1_mask01_xor_16_gpr_val:
934; X64:       # %bb.0: # %entry
935; X64-NEXT:    movl %esi, %ecx
936; X64-NEXT:    andl $15, %ecx
937; X64-NEXT:    xorl %eax, %eax
938; X64-NEXT:    lock btcw %cx, (%rdi)
939; X64-NEXT:    setb %al
940; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
941; X64-NEXT:    shll %cl, %eax
942; X64-NEXT:    # kill: def $ax killed $ax killed $eax
943; X64-NEXT:    retq
944entry:
945  %0 = and i16 %c, 15
946  %shl = shl nuw i16 1, %0
947  %1 = atomicrmw xor ptr %v, i16 %shl monotonic, align 2
948  %conv7 = and i16 %1, %shl
949  ret i16 %conv7
950}
951
952define zeroext i16 @atomic_blsi_xor_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
953; X86-LABEL: atomic_blsi_xor_16_gpr_val:
954; X86:       # %bb.0: # %entry
955; X86-NEXT:    pushl %esi
956; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
957; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
958; X86-NEXT:    movl %eax, %ecx
959; X86-NEXT:    negl %ecx
960; X86-NEXT:    andl %eax, %ecx
961; X86-NEXT:    movzwl (%edx), %eax
962; X86-NEXT:    .p2align 4
963; X86-NEXT:  .LBB17_1: # %atomicrmw.start
964; X86-NEXT:    # =>This Inner Loop Header: Depth=1
965; X86-NEXT:    movl %eax, %esi
966; X86-NEXT:    xorl %ecx, %esi
967; X86-NEXT:    # kill: def $ax killed $ax killed $eax
968; X86-NEXT:    lock cmpxchgw %si, (%edx)
969; X86-NEXT:    # kill: def $ax killed $ax def $eax
970; X86-NEXT:    jne .LBB17_1
971; X86-NEXT:  # %bb.2: # %atomicrmw.end
972; X86-NEXT:    andl %ecx, %eax
973; X86-NEXT:    # kill: def $ax killed $ax killed $eax
974; X86-NEXT:    popl %esi
975; X86-NEXT:    retl
976;
977; X64-LABEL: atomic_blsi_xor_16_gpr_val:
978; X64:       # %bb.0: # %entry
979; X64-NEXT:    movl %esi, %ecx
980; X64-NEXT:    negl %ecx
981; X64-NEXT:    andl %esi, %ecx
982; X64-NEXT:    movzwl (%rdi), %eax
983; X64-NEXT:    .p2align 4
984; X64-NEXT:  .LBB17_1: # %atomicrmw.start
985; X64-NEXT:    # =>This Inner Loop Header: Depth=1
986; X64-NEXT:    movl %eax, %edx
987; X64-NEXT:    xorl %ecx, %edx
988; X64-NEXT:    # kill: def $ax killed $ax killed $eax
989; X64-NEXT:    lock cmpxchgw %dx, (%rdi)
990; X64-NEXT:    # kill: def $ax killed $ax def $eax
991; X64-NEXT:    jne .LBB17_1
992; X64-NEXT:  # %bb.2: # %atomicrmw.end
993; X64-NEXT:    andl %ecx, %eax
994; X64-NEXT:    # kill: def $ax killed $ax killed $eax
995; X64-NEXT:    retq
996entry:
997  %sub = sub i16 0, %c
998  %and = and i16 %sub, %c
999  %0 = atomicrmw xor ptr %v, i16 %and monotonic, align 2
1000  %conv9 = and i16 %0, %and
1001  ret i16 %conv9
1002}
1003
1004define zeroext i16 @atomic_shl1_xor_16_gpr_valz(ptr %v, i16 zeroext %c) nounwind {
1005; X86-LABEL: atomic_shl1_xor_16_gpr_valz:
1006; X86:       # %bb.0: # %entry
1007; X86-NEXT:    pushl %esi
1008; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1009; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1010; X86-NEXT:    movl $1, %edx
1011; X86-NEXT:    shll %cl, %edx
1012; X86-NEXT:    movzwl (%esi), %eax
1013; X86-NEXT:    .p2align 4
1014; X86-NEXT:  .LBB18_1: # %atomicrmw.start
1015; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1016; X86-NEXT:    movl %eax, %ecx
1017; X86-NEXT:    xorl %edx, %ecx
1018; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1019; X86-NEXT:    lock cmpxchgw %cx, (%esi)
1020; X86-NEXT:    # kill: def $ax killed $ax def $eax
1021; X86-NEXT:    jne .LBB18_1
1022; X86-NEXT:  # %bb.2: # %atomicrmw.end
1023; X86-NEXT:    movzwl %ax, %ecx
1024; X86-NEXT:    xorl %eax, %eax
1025; X86-NEXT:    testl %ecx, %edx
1026; X86-NEXT:    sete %al
1027; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1028; X86-NEXT:    popl %esi
1029; X86-NEXT:    retl
1030;
1031; X64-LABEL: atomic_shl1_xor_16_gpr_valz:
1032; X64:       # %bb.0: # %entry
1033; X64-NEXT:    movl %esi, %ecx
1034; X64-NEXT:    movl $1, %edx
1035; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1036; X64-NEXT:    shll %cl, %edx
1037; X64-NEXT:    movzwl (%rdi), %eax
1038; X64-NEXT:    .p2align 4
1039; X64-NEXT:  .LBB18_1: # %atomicrmw.start
1040; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1041; X64-NEXT:    movl %eax, %ecx
1042; X64-NEXT:    xorl %edx, %ecx
1043; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1044; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
1045; X64-NEXT:    # kill: def $ax killed $ax def $eax
1046; X64-NEXT:    jne .LBB18_1
1047; X64-NEXT:  # %bb.2: # %atomicrmw.end
1048; X64-NEXT:    movzwl %ax, %ecx
1049; X64-NEXT:    xorl %eax, %eax
1050; X64-NEXT:    testl %ecx, %edx
1051; X64-NEXT:    sete %al
1052; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1053; X64-NEXT:    retq
1054entry:
1055  %conv = zext i16 %c to i32
1056  %shl = shl nuw i32 1, %conv
1057  %conv1 = trunc i32 %shl to i16
1058  %0 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
1059  %conv2 = zext i16 %0 to i32
1060  %and = and i32 %shl, %conv2
1061  %tobool.not = icmp eq i32 %and, 0
1062  %conv5 = zext i1 %tobool.not to i16
1063  ret i16 %conv5
1064}
1065
1066define zeroext i16 @atomic_shl1_small_mask_xor_16_gpr_valz(ptr %v, i16 zeroext %c) nounwind {
1067; X86-LABEL: atomic_shl1_small_mask_xor_16_gpr_valz:
1068; X86:       # %bb.0: # %entry
1069; X86-NEXT:    pushl %edi
1070; X86-NEXT:    pushl %esi
1071; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1072; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
1073; X86-NEXT:    andl $7, %ecx
1074; X86-NEXT:    movl $1, %esi
1075; X86-NEXT:    shll %cl, %esi
1076; X86-NEXT:    movzwl (%edx), %eax
1077; X86-NEXT:    movzwl %si, %esi
1078; X86-NEXT:    .p2align 4
1079; X86-NEXT:  .LBB19_1: # %atomicrmw.start
1080; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1081; X86-NEXT:    movl %eax, %edi
1082; X86-NEXT:    xorl %esi, %edi
1083; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1084; X86-NEXT:    lock cmpxchgw %di, (%edx)
1085; X86-NEXT:    # kill: def $ax killed $ax def $eax
1086; X86-NEXT:    jne .LBB19_1
1087; X86-NEXT:  # %bb.2: # %atomicrmw.end
1088; X86-NEXT:    movzwl %ax, %edx
1089; X86-NEXT:    xorl %eax, %eax
1090; X86-NEXT:    btl %ecx, %edx
1091; X86-NEXT:    setae %al
1092; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1093; X86-NEXT:    popl %esi
1094; X86-NEXT:    popl %edi
1095; X86-NEXT:    retl
1096;
1097; X64-LABEL: atomic_shl1_small_mask_xor_16_gpr_valz:
1098; X64:       # %bb.0: # %entry
1099; X64-NEXT:    movl %esi, %ecx
1100; X64-NEXT:    andl $7, %ecx
1101; X64-NEXT:    movl $1, %edx
1102; X64-NEXT:    shll %cl, %edx
1103; X64-NEXT:    movzwl (%rdi), %eax
1104; X64-NEXT:    movzwl %dx, %edx
1105; X64-NEXT:    .p2align 4
1106; X64-NEXT:  .LBB19_1: # %atomicrmw.start
1107; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1108; X64-NEXT:    movl %eax, %esi
1109; X64-NEXT:    xorl %edx, %esi
1110; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1111; X64-NEXT:    lock cmpxchgw %si, (%rdi)
1112; X64-NEXT:    # kill: def $ax killed $ax def $eax
1113; X64-NEXT:    jne .LBB19_1
1114; X64-NEXT:  # %bb.2: # %atomicrmw.end
1115; X64-NEXT:    movzwl %ax, %edx
1116; X64-NEXT:    xorl %eax, %eax
1117; X64-NEXT:    btl %ecx, %edx
1118; X64-NEXT:    setae %al
1119; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1120; X64-NEXT:    retq
1121entry:
1122  %0 = and i16 %c, 7
1123  %shl = shl nuw nsw i16 1, %0
1124  %1 = atomicrmw xor ptr %v, i16 %shl monotonic, align 2
1125  %conv5 = zext i16 %1 to i32
1126  %conv6 = zext i16 %0 to i32
1127  %shl7 = shl nuw nsw i32 1, %conv6
1128  %and = and i32 %shl7, %conv5
1129  %tobool.not = icmp eq i32 %and, 0
1130  %conv8 = zext i1 %tobool.not to i16
1131  ret i16 %conv8
1132}
1133
1134define zeroext i16 @atomic_shl1_mask0_xor_16_gpr_valz(ptr %v, i16 zeroext %c) nounwind {
1135; X86-LABEL: atomic_shl1_mask0_xor_16_gpr_valz:
1136; X86:       # %bb.0: # %entry
1137; X86-NEXT:    pushl %edi
1138; X86-NEXT:    pushl %esi
1139; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
1140; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1141; X86-NEXT:    movl %edx, %ecx
1142; X86-NEXT:    andb $15, %cl
1143; X86-NEXT:    movl $1, %edi
1144; X86-NEXT:    shll %cl, %edi
1145; X86-NEXT:    movzwl (%esi), %eax
1146; X86-NEXT:    .p2align 4
1147; X86-NEXT:  .LBB20_1: # %atomicrmw.start
1148; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1149; X86-NEXT:    movl %eax, %ecx
1150; X86-NEXT:    xorl %edi, %ecx
1151; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1152; X86-NEXT:    lock cmpxchgw %cx, (%esi)
1153; X86-NEXT:    # kill: def $ax killed $ax def $eax
1154; X86-NEXT:    jne .LBB20_1
1155; X86-NEXT:  # %bb.2: # %atomicrmw.end
1156; X86-NEXT:    movzwl %ax, %ecx
1157; X86-NEXT:    xorl %eax, %eax
1158; X86-NEXT:    btl %edx, %ecx
1159; X86-NEXT:    setae %al
1160; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1161; X86-NEXT:    popl %esi
1162; X86-NEXT:    popl %edi
1163; X86-NEXT:    retl
1164;
1165; X64-LABEL: atomic_shl1_mask0_xor_16_gpr_valz:
1166; X64:       # %bb.0: # %entry
1167; X64-NEXT:    movl %esi, %ecx
1168; X64-NEXT:    andb $15, %cl
1169; X64-NEXT:    movl $1, %edx
1170; X64-NEXT:    shll %cl, %edx
1171; X64-NEXT:    movzwl (%rdi), %eax
1172; X64-NEXT:    .p2align 4
1173; X64-NEXT:  .LBB20_1: # %atomicrmw.start
1174; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1175; X64-NEXT:    movl %eax, %ecx
1176; X64-NEXT:    xorl %edx, %ecx
1177; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1178; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
1179; X64-NEXT:    # kill: def $ax killed $ax def $eax
1180; X64-NEXT:    jne .LBB20_1
1181; X64-NEXT:  # %bb.2: # %atomicrmw.end
1182; X64-NEXT:    movzwl %ax, %ecx
1183; X64-NEXT:    xorl %eax, %eax
1184; X64-NEXT:    btl %esi, %ecx
1185; X64-NEXT:    setae %al
1186; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1187; X64-NEXT:    retq
1188entry:
1189  %0 = and i16 %c, 15
1190  %shl = shl nuw i16 1, %0
1191  %1 = atomicrmw xor ptr %v, i16 %shl monotonic, align 2
1192  %conv2 = zext i16 %1 to i32
1193  %conv3 = zext i16 %c to i32
1194  %shl4 = shl nuw i32 1, %conv3
1195  %and = and i32 %shl4, %conv2
1196  %tobool.not = icmp eq i32 %and, 0
1197  %conv5 = zext i1 %tobool.not to i16
1198  ret i16 %conv5
1199}
1200
1201define zeroext i16 @atomic_shl1_mask1_xor_16_gpr_valz(ptr %v, i16 zeroext %c) nounwind {
1202; X86-LABEL: atomic_shl1_mask1_xor_16_gpr_valz:
1203; X86:       # %bb.0: # %entry
1204; X86-NEXT:    pushl %edi
1205; X86-NEXT:    pushl %esi
1206; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
1207; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1208; X86-NEXT:    movl $1, %esi
1209; X86-NEXT:    shll %cl, %esi
1210; X86-NEXT:    movzwl (%edx), %eax
1211; X86-NEXT:    .p2align 4
1212; X86-NEXT:  .LBB21_1: # %atomicrmw.start
1213; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1214; X86-NEXT:    movl %eax, %edi
1215; X86-NEXT:    xorl %esi, %edi
1216; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1217; X86-NEXT:    lock cmpxchgw %di, (%edx)
1218; X86-NEXT:    # kill: def $ax killed $ax def $eax
1219; X86-NEXT:    jne .LBB21_1
1220; X86-NEXT:  # %bb.2: # %atomicrmw.end
1221; X86-NEXT:    movzwl %ax, %edx
1222; X86-NEXT:    andl $15, %ecx
1223; X86-NEXT:    xorl %eax, %eax
1224; X86-NEXT:    btl %ecx, %edx
1225; X86-NEXT:    setae %al
1226; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1227; X86-NEXT:    popl %esi
1228; X86-NEXT:    popl %edi
1229; X86-NEXT:    retl
1230;
1231; X64-LABEL: atomic_shl1_mask1_xor_16_gpr_valz:
1232; X64:       # %bb.0: # %entry
1233; X64-NEXT:    movl %esi, %ecx
1234; X64-NEXT:    movl $1, %edx
1235; X64-NEXT:    shll %cl, %edx
1236; X64-NEXT:    movzwl (%rdi), %eax
1237; X64-NEXT:    .p2align 4
1238; X64-NEXT:  .LBB21_1: # %atomicrmw.start
1239; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1240; X64-NEXT:    movl %eax, %esi
1241; X64-NEXT:    xorl %edx, %esi
1242; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1243; X64-NEXT:    lock cmpxchgw %si, (%rdi)
1244; X64-NEXT:    # kill: def $ax killed $ax def $eax
1245; X64-NEXT:    jne .LBB21_1
1246; X64-NEXT:  # %bb.2: # %atomicrmw.end
1247; X64-NEXT:    movzwl %ax, %edx
1248; X64-NEXT:    andl $15, %ecx
1249; X64-NEXT:    xorl %eax, %eax
1250; X64-NEXT:    btl %ecx, %edx
1251; X64-NEXT:    setae %al
1252; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1253; X64-NEXT:    retq
1254entry:
1255  %conv = zext i16 %c to i32
1256  %shl = shl nuw i32 1, %conv
1257  %conv1 = trunc i32 %shl to i16
1258  %0 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
1259  %conv2 = zext i16 %0 to i32
1260  %1 = and i16 %c, 15
1261  %sh_prom = zext i16 %1 to i32
1262  %shl4 = shl nuw nsw i32 1, %sh_prom
1263  %and = and i32 %shl4, %conv2
1264  %tobool.not = icmp eq i32 %and, 0
1265  %conv5 = zext i1 %tobool.not to i16
1266  ret i16 %conv5
1267}
1268
1269define zeroext i16 @atomic_shl1_mask01_xor_16_gpr_valz(ptr %v, i16 zeroext %c) nounwind {
1270; X86-LABEL: atomic_shl1_mask01_xor_16_gpr_valz:
1271; X86:       # %bb.0: # %entry
1272; X86-NEXT:    pushl %esi
1273; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1274; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1275; X86-NEXT:    andb $15, %cl
1276; X86-NEXT:    movl $1, %esi
1277; X86-NEXT:    shll %cl, %esi
1278; X86-NEXT:    movzwl (%edx), %eax
1279; X86-NEXT:    .p2align 4
1280; X86-NEXT:  .LBB22_1: # %atomicrmw.start
1281; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1282; X86-NEXT:    movl %eax, %ecx
1283; X86-NEXT:    xorl %esi, %ecx
1284; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1285; X86-NEXT:    lock cmpxchgw %cx, (%edx)
1286; X86-NEXT:    # kill: def $ax killed $ax def $eax
1287; X86-NEXT:    jne .LBB22_1
1288; X86-NEXT:  # %bb.2: # %atomicrmw.end
1289; X86-NEXT:    movzwl %ax, %ecx
1290; X86-NEXT:    xorl %eax, %eax
1291; X86-NEXT:    testl %ecx, %esi
1292; X86-NEXT:    sete %al
1293; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1294; X86-NEXT:    popl %esi
1295; X86-NEXT:    retl
1296;
1297; X64-LABEL: atomic_shl1_mask01_xor_16_gpr_valz:
1298; X64:       # %bb.0: # %entry
1299; X64-NEXT:    movl %esi, %ecx
1300; X64-NEXT:    andb $15, %cl
1301; X64-NEXT:    movl $1, %edx
1302; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1303; X64-NEXT:    shll %cl, %edx
1304; X64-NEXT:    movzwl (%rdi), %eax
1305; X64-NEXT:    .p2align 4
1306; X64-NEXT:  .LBB22_1: # %atomicrmw.start
1307; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1308; X64-NEXT:    movl %eax, %ecx
1309; X64-NEXT:    xorl %edx, %ecx
1310; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1311; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
1312; X64-NEXT:    # kill: def $ax killed $ax def $eax
1313; X64-NEXT:    jne .LBB22_1
1314; X64-NEXT:  # %bb.2: # %atomicrmw.end
1315; X64-NEXT:    movzwl %ax, %ecx
1316; X64-NEXT:    xorl %eax, %eax
1317; X64-NEXT:    testl %ecx, %edx
1318; X64-NEXT:    sete %al
1319; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1320; X64-NEXT:    retq
1321entry:
1322  %0 = and i16 %c, 15
1323  %sh_prom = zext i16 %0 to i32
1324  %shl = shl nuw nsw i32 1, %sh_prom
1325  %conv1 = trunc i32 %shl to i16
1326  %1 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
1327  %conv2 = zext i16 %1 to i32
1328  %and = and i32 %shl, %conv2
1329  %tobool.not = icmp eq i32 %and, 0
1330  %conv7 = zext i1 %tobool.not to i16
1331  ret i16 %conv7
1332}
1333
1334define zeroext i16 @atomic_blsi_xor_16_gpr_valz(ptr %v, i16 zeroext %c) nounwind {
1335; X86-LABEL: atomic_blsi_xor_16_gpr_valz:
1336; X86:       # %bb.0: # %entry
1337; X86-NEXT:    pushl %esi
1338; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1339; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
1340; X86-NEXT:    movl %eax, %ecx
1341; X86-NEXT:    negl %ecx
1342; X86-NEXT:    andl %eax, %ecx
1343; X86-NEXT:    movzwl (%edx), %eax
1344; X86-NEXT:    .p2align 4
1345; X86-NEXT:  .LBB23_1: # %atomicrmw.start
1346; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1347; X86-NEXT:    movl %eax, %esi
1348; X86-NEXT:    xorl %ecx, %esi
1349; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1350; X86-NEXT:    lock cmpxchgw %si, (%edx)
1351; X86-NEXT:    # kill: def $ax killed $ax def $eax
1352; X86-NEXT:    jne .LBB23_1
1353; X86-NEXT:  # %bb.2: # %atomicrmw.end
1354; X86-NEXT:    movzwl %ax, %edx
1355; X86-NEXT:    xorl %eax, %eax
1356; X86-NEXT:    testl %edx, %ecx
1357; X86-NEXT:    sete %al
1358; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1359; X86-NEXT:    popl %esi
1360; X86-NEXT:    retl
1361;
1362; X64-LABEL: atomic_blsi_xor_16_gpr_valz:
1363; X64:       # %bb.0: # %entry
1364; X64-NEXT:    movl %esi, %ecx
1365; X64-NEXT:    negl %ecx
1366; X64-NEXT:    andl %esi, %ecx
1367; X64-NEXT:    movzwl (%rdi), %eax
1368; X64-NEXT:    .p2align 4
1369; X64-NEXT:  .LBB23_1: # %atomicrmw.start
1370; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1371; X64-NEXT:    movl %eax, %edx
1372; X64-NEXT:    xorl %ecx, %edx
1373; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1374; X64-NEXT:    lock cmpxchgw %dx, (%rdi)
1375; X64-NEXT:    # kill: def $ax killed $ax def $eax
1376; X64-NEXT:    jne .LBB23_1
1377; X64-NEXT:  # %bb.2: # %atomicrmw.end
1378; X64-NEXT:    movzwl %ax, %edx
1379; X64-NEXT:    xorl %eax, %eax
1380; X64-NEXT:    testl %edx, %ecx
1381; X64-NEXT:    sete %al
1382; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1383; X64-NEXT:    retq
1384entry:
1385  %conv = zext i16 %c to i32
1386  %sub = sub nsw i32 0, %conv
1387  %and = and i32 %conv, %sub
1388  %conv2 = trunc i32 %and to i16
1389  %0 = atomicrmw xor ptr %v, i16 %conv2 monotonic, align 2
1390  %conv3 = zext i16 %0 to i32
1391  %and8 = and i32 %and, %conv3
1392  %tobool.not = icmp eq i32 %and8, 0
1393  %conv9 = zext i1 %tobool.not to i16
1394  ret i16 %conv9
1395}
1396
1397define zeroext i16 @atomic_shl1_xor_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
1398; X86-LABEL: atomic_shl1_xor_16_gpr_valnz:
1399; X86:       # %bb.0: # %entry
1400; X86-NEXT:    pushl %esi
1401; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1402; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1403; X86-NEXT:    movl $1, %edx
1404; X86-NEXT:    shll %cl, %edx
1405; X86-NEXT:    movzwl (%esi), %eax
1406; X86-NEXT:    .p2align 4
1407; X86-NEXT:  .LBB24_1: # %atomicrmw.start
1408; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1409; X86-NEXT:    movl %eax, %ecx
1410; X86-NEXT:    xorl %edx, %ecx
1411; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1412; X86-NEXT:    lock cmpxchgw %cx, (%esi)
1413; X86-NEXT:    # kill: def $ax killed $ax def $eax
1414; X86-NEXT:    jne .LBB24_1
1415; X86-NEXT:  # %bb.2: # %atomicrmw.end
1416; X86-NEXT:    movzwl %ax, %ecx
1417; X86-NEXT:    xorl %eax, %eax
1418; X86-NEXT:    testl %ecx, %edx
1419; X86-NEXT:    setne %al
1420; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1421; X86-NEXT:    popl %esi
1422; X86-NEXT:    retl
1423;
1424; X64-LABEL: atomic_shl1_xor_16_gpr_valnz:
1425; X64:       # %bb.0: # %entry
1426; X64-NEXT:    movl %esi, %ecx
1427; X64-NEXT:    movl $1, %edx
1428; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1429; X64-NEXT:    shll %cl, %edx
1430; X64-NEXT:    movzwl (%rdi), %eax
1431; X64-NEXT:    .p2align 4
1432; X64-NEXT:  .LBB24_1: # %atomicrmw.start
1433; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1434; X64-NEXT:    movl %eax, %ecx
1435; X64-NEXT:    xorl %edx, %ecx
1436; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1437; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
1438; X64-NEXT:    # kill: def $ax killed $ax def $eax
1439; X64-NEXT:    jne .LBB24_1
1440; X64-NEXT:  # %bb.2: # %atomicrmw.end
1441; X64-NEXT:    movzwl %ax, %ecx
1442; X64-NEXT:    xorl %eax, %eax
1443; X64-NEXT:    testl %ecx, %edx
1444; X64-NEXT:    setne %al
1445; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1446; X64-NEXT:    retq
1447entry:
1448  %conv = zext i16 %c to i32
1449  %shl = shl nuw i32 1, %conv
1450  %conv1 = trunc i32 %shl to i16
1451  %0 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
1452  %conv2 = zext i16 %0 to i32
1453  %and = and i32 %shl, %conv2
1454  %tobool = icmp ne i32 %and, 0
1455  %conv6 = zext i1 %tobool to i16
1456  ret i16 %conv6
1457}
1458
1459define zeroext i16 @atomic_shl1_small_mask_xor_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
1460; X86-LABEL: atomic_shl1_small_mask_xor_16_gpr_valnz:
1461; X86:       # %bb.0: # %entry
1462; X86-NEXT:    pushl %edi
1463; X86-NEXT:    pushl %esi
1464; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1465; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
1466; X86-NEXT:    andl $7, %ecx
1467; X86-NEXT:    movl $1, %esi
1468; X86-NEXT:    shll %cl, %esi
1469; X86-NEXT:    movzwl (%edx), %eax
1470; X86-NEXT:    movzwl %si, %esi
1471; X86-NEXT:    .p2align 4
1472; X86-NEXT:  .LBB25_1: # %atomicrmw.start
1473; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1474; X86-NEXT:    movl %eax, %edi
1475; X86-NEXT:    xorl %esi, %edi
1476; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1477; X86-NEXT:    lock cmpxchgw %di, (%edx)
1478; X86-NEXT:    # kill: def $ax killed $ax def $eax
1479; X86-NEXT:    jne .LBB25_1
1480; X86-NEXT:  # %bb.2: # %atomicrmw.end
1481; X86-NEXT:    movzwl %ax, %edx
1482; X86-NEXT:    xorl %eax, %eax
1483; X86-NEXT:    btl %ecx, %edx
1484; X86-NEXT:    setb %al
1485; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1486; X86-NEXT:    popl %esi
1487; X86-NEXT:    popl %edi
1488; X86-NEXT:    retl
1489;
1490; X64-LABEL: atomic_shl1_small_mask_xor_16_gpr_valnz:
1491; X64:       # %bb.0: # %entry
1492; X64-NEXT:    movl %esi, %ecx
1493; X64-NEXT:    andl $7, %ecx
1494; X64-NEXT:    movl $1, %edx
1495; X64-NEXT:    shll %cl, %edx
1496; X64-NEXT:    movzwl (%rdi), %eax
1497; X64-NEXT:    movzwl %dx, %edx
1498; X64-NEXT:    .p2align 4
1499; X64-NEXT:  .LBB25_1: # %atomicrmw.start
1500; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1501; X64-NEXT:    movl %eax, %esi
1502; X64-NEXT:    xorl %edx, %esi
1503; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1504; X64-NEXT:    lock cmpxchgw %si, (%rdi)
1505; X64-NEXT:    # kill: def $ax killed $ax def $eax
1506; X64-NEXT:    jne .LBB25_1
1507; X64-NEXT:  # %bb.2: # %atomicrmw.end
1508; X64-NEXT:    movzwl %ax, %edx
1509; X64-NEXT:    xorl %eax, %eax
1510; X64-NEXT:    btl %ecx, %edx
1511; X64-NEXT:    setb %al
1512; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1513; X64-NEXT:    retq
1514entry:
1515  %0 = and i16 %c, 7
1516  %shl = shl nuw nsw i16 1, %0
1517  %1 = atomicrmw xor ptr %v, i16 %shl monotonic, align 2
1518  %conv5 = zext i16 %1 to i32
1519  %conv6 = zext i16 %0 to i32
1520  %shl7 = shl nuw nsw i32 1, %conv6
1521  %and = and i32 %shl7, %conv5
1522  %tobool = icmp ne i32 %and, 0
1523  %conv9 = zext i1 %tobool to i16
1524  ret i16 %conv9
1525}
1526
1527define zeroext i16 @atomic_shl1_mask0_xor_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
1528; X86-LABEL: atomic_shl1_mask0_xor_16_gpr_valnz:
1529; X86:       # %bb.0: # %entry
1530; X86-NEXT:    pushl %edi
1531; X86-NEXT:    pushl %esi
1532; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %edx
1533; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
1534; X86-NEXT:    movl %edx, %ecx
1535; X86-NEXT:    andb $15, %cl
1536; X86-NEXT:    movl $1, %edi
1537; X86-NEXT:    shll %cl, %edi
1538; X86-NEXT:    movzwl (%esi), %eax
1539; X86-NEXT:    .p2align 4
1540; X86-NEXT:  .LBB26_1: # %atomicrmw.start
1541; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1542; X86-NEXT:    movl %eax, %ecx
1543; X86-NEXT:    xorl %edi, %ecx
1544; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1545; X86-NEXT:    lock cmpxchgw %cx, (%esi)
1546; X86-NEXT:    # kill: def $ax killed $ax def $eax
1547; X86-NEXT:    jne .LBB26_1
1548; X86-NEXT:  # %bb.2: # %atomicrmw.end
1549; X86-NEXT:    movzwl %ax, %ecx
1550; X86-NEXT:    xorl %eax, %eax
1551; X86-NEXT:    btl %edx, %ecx
1552; X86-NEXT:    setb %al
1553; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1554; X86-NEXT:    popl %esi
1555; X86-NEXT:    popl %edi
1556; X86-NEXT:    retl
1557;
1558; X64-LABEL: atomic_shl1_mask0_xor_16_gpr_valnz:
1559; X64:       # %bb.0: # %entry
1560; X64-NEXT:    movl %esi, %ecx
1561; X64-NEXT:    andb $15, %cl
1562; X64-NEXT:    movl $1, %edx
1563; X64-NEXT:    shll %cl, %edx
1564; X64-NEXT:    movzwl (%rdi), %eax
1565; X64-NEXT:    .p2align 4
1566; X64-NEXT:  .LBB26_1: # %atomicrmw.start
1567; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1568; X64-NEXT:    movl %eax, %ecx
1569; X64-NEXT:    xorl %edx, %ecx
1570; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1571; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
1572; X64-NEXT:    # kill: def $ax killed $ax def $eax
1573; X64-NEXT:    jne .LBB26_1
1574; X64-NEXT:  # %bb.2: # %atomicrmw.end
1575; X64-NEXT:    movzwl %ax, %ecx
1576; X64-NEXT:    xorl %eax, %eax
1577; X64-NEXT:    btl %esi, %ecx
1578; X64-NEXT:    setb %al
1579; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1580; X64-NEXT:    retq
1581entry:
1582  %0 = and i16 %c, 15
1583  %shl = shl nuw i16 1, %0
1584  %1 = atomicrmw xor ptr %v, i16 %shl monotonic, align 2
1585  %conv2 = zext i16 %1 to i32
1586  %conv3 = zext i16 %c to i32
1587  %shl4 = shl nuw i32 1, %conv3
1588  %and = and i32 %shl4, %conv2
1589  %tobool = icmp ne i32 %and, 0
1590  %conv6 = zext i1 %tobool to i16
1591  ret i16 %conv6
1592}
1593
1594define zeroext i16 @atomic_shl1_mask1_xor_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
1595; X86-LABEL: atomic_shl1_mask1_xor_16_gpr_valnz:
1596; X86:       # %bb.0: # %entry
1597; X86-NEXT:    pushl %edi
1598; X86-NEXT:    pushl %esi
1599; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
1600; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1601; X86-NEXT:    movl $1, %esi
1602; X86-NEXT:    shll %cl, %esi
1603; X86-NEXT:    movzwl (%edx), %eax
1604; X86-NEXT:    .p2align 4
1605; X86-NEXT:  .LBB27_1: # %atomicrmw.start
1606; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1607; X86-NEXT:    movl %eax, %edi
1608; X86-NEXT:    xorl %esi, %edi
1609; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1610; X86-NEXT:    lock cmpxchgw %di, (%edx)
1611; X86-NEXT:    # kill: def $ax killed $ax def $eax
1612; X86-NEXT:    jne .LBB27_1
1613; X86-NEXT:  # %bb.2: # %atomicrmw.end
1614; X86-NEXT:    movzwl %ax, %edx
1615; X86-NEXT:    andl $15, %ecx
1616; X86-NEXT:    xorl %eax, %eax
1617; X86-NEXT:    btl %ecx, %edx
1618; X86-NEXT:    setb %al
1619; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1620; X86-NEXT:    popl %esi
1621; X86-NEXT:    popl %edi
1622; X86-NEXT:    retl
1623;
1624; X64-LABEL: atomic_shl1_mask1_xor_16_gpr_valnz:
1625; X64:       # %bb.0: # %entry
1626; X64-NEXT:    movl %esi, %ecx
1627; X64-NEXT:    movl $1, %edx
1628; X64-NEXT:    shll %cl, %edx
1629; X64-NEXT:    movzwl (%rdi), %eax
1630; X64-NEXT:    .p2align 4
1631; X64-NEXT:  .LBB27_1: # %atomicrmw.start
1632; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1633; X64-NEXT:    movl %eax, %esi
1634; X64-NEXT:    xorl %edx, %esi
1635; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1636; X64-NEXT:    lock cmpxchgw %si, (%rdi)
1637; X64-NEXT:    # kill: def $ax killed $ax def $eax
1638; X64-NEXT:    jne .LBB27_1
1639; X64-NEXT:  # %bb.2: # %atomicrmw.end
1640; X64-NEXT:    movzwl %ax, %edx
1641; X64-NEXT:    andl $15, %ecx
1642; X64-NEXT:    xorl %eax, %eax
1643; X64-NEXT:    btl %ecx, %edx
1644; X64-NEXT:    setb %al
1645; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1646; X64-NEXT:    retq
1647entry:
1648  %conv = zext i16 %c to i32
1649  %shl = shl nuw i32 1, %conv
1650  %conv1 = trunc i32 %shl to i16
1651  %0 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
1652  %conv2 = zext i16 %0 to i32
1653  %1 = and i16 %c, 15
1654  %sh_prom = zext i16 %1 to i32
1655  %shl4 = shl nuw nsw i32 1, %sh_prom
1656  %and = and i32 %shl4, %conv2
1657  %tobool = icmp ne i32 %and, 0
1658  %conv6 = zext i1 %tobool to i16
1659  ret i16 %conv6
1660}
1661
1662define zeroext i16 @atomic_shl1_mask01_xor_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
1663; X86-LABEL: atomic_shl1_mask01_xor_16_gpr_valnz:
1664; X86:       # %bb.0: # %entry
1665; X86-NEXT:    pushl %esi
1666; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1667; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
1668; X86-NEXT:    andb $15, %cl
1669; X86-NEXT:    movl $1, %esi
1670; X86-NEXT:    shll %cl, %esi
1671; X86-NEXT:    movzwl (%edx), %eax
1672; X86-NEXT:    .p2align 4
1673; X86-NEXT:  .LBB28_1: # %atomicrmw.start
1674; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1675; X86-NEXT:    movl %eax, %ecx
1676; X86-NEXT:    xorl %esi, %ecx
1677; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1678; X86-NEXT:    lock cmpxchgw %cx, (%edx)
1679; X86-NEXT:    # kill: def $ax killed $ax def $eax
1680; X86-NEXT:    jne .LBB28_1
1681; X86-NEXT:  # %bb.2: # %atomicrmw.end
1682; X86-NEXT:    movzwl %ax, %ecx
1683; X86-NEXT:    xorl %eax, %eax
1684; X86-NEXT:    testl %ecx, %esi
1685; X86-NEXT:    setne %al
1686; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1687; X86-NEXT:    popl %esi
1688; X86-NEXT:    retl
1689;
1690; X64-LABEL: atomic_shl1_mask01_xor_16_gpr_valnz:
1691; X64:       # %bb.0: # %entry
1692; X64-NEXT:    movl %esi, %ecx
1693; X64-NEXT:    andb $15, %cl
1694; X64-NEXT:    movl $1, %edx
1695; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
1696; X64-NEXT:    shll %cl, %edx
1697; X64-NEXT:    movzwl (%rdi), %eax
1698; X64-NEXT:    .p2align 4
1699; X64-NEXT:  .LBB28_1: # %atomicrmw.start
1700; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1701; X64-NEXT:    movl %eax, %ecx
1702; X64-NEXT:    xorl %edx, %ecx
1703; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1704; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
1705; X64-NEXT:    # kill: def $ax killed $ax def $eax
1706; X64-NEXT:    jne .LBB28_1
1707; X64-NEXT:  # %bb.2: # %atomicrmw.end
1708; X64-NEXT:    movzwl %ax, %ecx
1709; X64-NEXT:    xorl %eax, %eax
1710; X64-NEXT:    testl %ecx, %edx
1711; X64-NEXT:    setne %al
1712; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1713; X64-NEXT:    retq
1714entry:
1715  %0 = and i16 %c, 15
1716  %sh_prom = zext i16 %0 to i32
1717  %shl = shl nuw nsw i32 1, %sh_prom
1718  %conv1 = trunc i32 %shl to i16
1719  %1 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
1720  %conv2 = zext i16 %1 to i32
1721  %and = and i32 %shl, %conv2
1722  %tobool = icmp ne i32 %and, 0
1723  %conv8 = zext i1 %tobool to i16
1724  ret i16 %conv8
1725}
1726
1727define zeroext i16 @atomic_blsi_xor_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
1728; X86-LABEL: atomic_blsi_xor_16_gpr_valnz:
1729; X86:       # %bb.0: # %entry
1730; X86-NEXT:    pushl %esi
1731; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1732; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
1733; X86-NEXT:    movl %eax, %ecx
1734; X86-NEXT:    negl %ecx
1735; X86-NEXT:    andl %eax, %ecx
1736; X86-NEXT:    movzwl (%edx), %eax
1737; X86-NEXT:    .p2align 4
1738; X86-NEXT:  .LBB29_1: # %atomicrmw.start
1739; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1740; X86-NEXT:    movl %eax, %esi
1741; X86-NEXT:    xorl %ecx, %esi
1742; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1743; X86-NEXT:    lock cmpxchgw %si, (%edx)
1744; X86-NEXT:    # kill: def $ax killed $ax def $eax
1745; X86-NEXT:    jne .LBB29_1
1746; X86-NEXT:  # %bb.2: # %atomicrmw.end
1747; X86-NEXT:    movzwl %ax, %edx
1748; X86-NEXT:    xorl %eax, %eax
1749; X86-NEXT:    testl %edx, %ecx
1750; X86-NEXT:    setne %al
1751; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1752; X86-NEXT:    popl %esi
1753; X86-NEXT:    retl
1754;
1755; X64-LABEL: atomic_blsi_xor_16_gpr_valnz:
1756; X64:       # %bb.0: # %entry
1757; X64-NEXT:    movl %esi, %ecx
1758; X64-NEXT:    negl %ecx
1759; X64-NEXT:    andl %esi, %ecx
1760; X64-NEXT:    movzwl (%rdi), %eax
1761; X64-NEXT:    .p2align 4
1762; X64-NEXT:  .LBB29_1: # %atomicrmw.start
1763; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1764; X64-NEXT:    movl %eax, %edx
1765; X64-NEXT:    xorl %ecx, %edx
1766; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1767; X64-NEXT:    lock cmpxchgw %dx, (%rdi)
1768; X64-NEXT:    # kill: def $ax killed $ax def $eax
1769; X64-NEXT:    jne .LBB29_1
1770; X64-NEXT:  # %bb.2: # %atomicrmw.end
1771; X64-NEXT:    movzwl %ax, %edx
1772; X64-NEXT:    xorl %eax, %eax
1773; X64-NEXT:    testl %edx, %ecx
1774; X64-NEXT:    setne %al
1775; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1776; X64-NEXT:    retq
1777entry:
1778  %conv = zext i16 %c to i32
1779  %sub = sub nsw i32 0, %conv
1780  %and = and i32 %conv, %sub
1781  %conv2 = trunc i32 %and to i16
1782  %0 = atomicrmw xor ptr %v, i16 %conv2 monotonic, align 2
1783  %conv3 = zext i16 %0 to i32
1784  %and8 = and i32 %and, %conv3
1785  %tobool = icmp ne i32 %and8, 0
1786  %conv10 = zext i1 %tobool to i16
1787  ret i16 %conv10
1788}
1789
1790define zeroext i16 @atomic_shl1_xor_16_gpr_brz(ptr %v, i16 zeroext %c) nounwind {
1791; X86-LABEL: atomic_shl1_xor_16_gpr_brz:
1792; X86:       # %bb.0: # %entry
1793; X86-NEXT:    pushl %edi
1794; X86-NEXT:    pushl %esi
1795; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
1796; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1797; X86-NEXT:    movl $1, %esi
1798; X86-NEXT:    shll %cl, %esi
1799; X86-NEXT:    movzwl (%edx), %eax
1800; X86-NEXT:    .p2align 4
1801; X86-NEXT:  .LBB30_1: # %atomicrmw.start
1802; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1803; X86-NEXT:    movl %eax, %edi
1804; X86-NEXT:    xorl %esi, %edi
1805; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1806; X86-NEXT:    lock cmpxchgw %di, (%edx)
1807; X86-NEXT:    # kill: def $ax killed $ax def $eax
1808; X86-NEXT:    jne .LBB30_1
1809; X86-NEXT:  # %bb.2: # %atomicrmw.end
1810; X86-NEXT:    movzwl %ax, %edi
1811; X86-NEXT:    movw $123, %ax
1812; X86-NEXT:    testl %edi, %esi
1813; X86-NEXT:    jne .LBB30_4
1814; X86-NEXT:  # %bb.3: # %if.then
1815; X86-NEXT:    movzwl %cx, %eax
1816; X86-NEXT:    movzwl (%edx,%eax,2), %eax
1817; X86-NEXT:  .LBB30_4: # %return
1818; X86-NEXT:    popl %esi
1819; X86-NEXT:    popl %edi
1820; X86-NEXT:    retl
1821;
1822; X64-LABEL: atomic_shl1_xor_16_gpr_brz:
1823; X64:       # %bb.0: # %entry
1824; X64-NEXT:    movl %esi, %ecx
1825; X64-NEXT:    movl $1, %edx
1826; X64-NEXT:    shll %cl, %edx
1827; X64-NEXT:    movzwl (%rdi), %eax
1828; X64-NEXT:    .p2align 4
1829; X64-NEXT:  .LBB30_1: # %atomicrmw.start
1830; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1831; X64-NEXT:    movl %eax, %esi
1832; X64-NEXT:    xorl %edx, %esi
1833; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1834; X64-NEXT:    lock cmpxchgw %si, (%rdi)
1835; X64-NEXT:    # kill: def $ax killed $ax def $eax
1836; X64-NEXT:    jne .LBB30_1
1837; X64-NEXT:  # %bb.2: # %atomicrmw.end
1838; X64-NEXT:    movzwl %ax, %esi
1839; X64-NEXT:    movw $123, %ax
1840; X64-NEXT:    testl %esi, %edx
1841; X64-NEXT:    je .LBB30_3
1842; X64-NEXT:  # %bb.4: # %return
1843; X64-NEXT:    retq
1844; X64-NEXT:  .LBB30_3: # %if.then
1845; X64-NEXT:    movzwl %cx, %eax
1846; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
1847; X64-NEXT:    retq
1848entry:
1849  %conv = zext i16 %c to i32
1850  %shl = shl nuw i32 1, %conv
1851  %conv1 = trunc i32 %shl to i16
1852  %0 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
1853  %conv2 = zext i16 %0 to i32
1854  %and = and i32 %shl, %conv2
1855  %tobool.not = icmp eq i32 %and, 0
1856  br i1 %tobool.not, label %if.then, label %return
1857
1858if.then:                                          ; preds = %entry
1859  %idxprom = zext i16 %c to i64
1860  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %idxprom
1861  %1 = load i16, ptr %arrayidx, align 2
1862  br label %return
1863
1864return:                                           ; preds = %entry, %if.then
1865  %retval.0 = phi i16 [ %1, %if.then ], [ 123, %entry ]
1866  ret i16 %retval.0
1867}
1868
1869define zeroext i16 @atomic_shl1_small_mask_xor_16_gpr_brz(ptr %v, i16 zeroext %c) nounwind {
1870; X86-LABEL: atomic_shl1_small_mask_xor_16_gpr_brz:
1871; X86:       # %bb.0: # %entry
1872; X86-NEXT:    pushl %edi
1873; X86-NEXT:    pushl %esi
1874; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1875; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
1876; X86-NEXT:    andl $7, %ecx
1877; X86-NEXT:    movl $1, %esi
1878; X86-NEXT:    shll %cl, %esi
1879; X86-NEXT:    movzwl (%edx), %eax
1880; X86-NEXT:    movzwl %si, %esi
1881; X86-NEXT:    .p2align 4
1882; X86-NEXT:  .LBB31_1: # %atomicrmw.start
1883; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1884; X86-NEXT:    movl %eax, %edi
1885; X86-NEXT:    xorl %esi, %edi
1886; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1887; X86-NEXT:    lock cmpxchgw %di, (%edx)
1888; X86-NEXT:    # kill: def $ax killed $ax def $eax
1889; X86-NEXT:    jne .LBB31_1
1890; X86-NEXT:  # %bb.2: # %atomicrmw.end
1891; X86-NEXT:    movzwl %ax, %esi
1892; X86-NEXT:    movw $123, %ax
1893; X86-NEXT:    btl %ecx, %esi
1894; X86-NEXT:    jb .LBB31_4
1895; X86-NEXT:  # %bb.3: # %if.then
1896; X86-NEXT:    movzwl %cx, %eax
1897; X86-NEXT:    movzwl (%edx,%eax,2), %eax
1898; X86-NEXT:  .LBB31_4: # %return
1899; X86-NEXT:    popl %esi
1900; X86-NEXT:    popl %edi
1901; X86-NEXT:    retl
1902;
1903; X64-LABEL: atomic_shl1_small_mask_xor_16_gpr_brz:
1904; X64:       # %bb.0: # %entry
1905; X64-NEXT:    movl %esi, %ecx
1906; X64-NEXT:    andl $7, %ecx
1907; X64-NEXT:    movl $1, %edx
1908; X64-NEXT:    shll %cl, %edx
1909; X64-NEXT:    movzwl (%rdi), %eax
1910; X64-NEXT:    movzwl %dx, %edx
1911; X64-NEXT:    .p2align 4
1912; X64-NEXT:  .LBB31_1: # %atomicrmw.start
1913; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1914; X64-NEXT:    movl %eax, %esi
1915; X64-NEXT:    xorl %edx, %esi
1916; X64-NEXT:    # kill: def $ax killed $ax killed $eax
1917; X64-NEXT:    lock cmpxchgw %si, (%rdi)
1918; X64-NEXT:    # kill: def $ax killed $ax def $eax
1919; X64-NEXT:    jne .LBB31_1
1920; X64-NEXT:  # %bb.2: # %atomicrmw.end
1921; X64-NEXT:    movzwl %ax, %edx
1922; X64-NEXT:    movw $123, %ax
1923; X64-NEXT:    btl %ecx, %edx
1924; X64-NEXT:    jae .LBB31_3
1925; X64-NEXT:  # %bb.4: # %return
1926; X64-NEXT:    retq
1927; X64-NEXT:  .LBB31_3: # %if.then
1928; X64-NEXT:    movzwl %cx, %eax
1929; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
1930; X64-NEXT:    retq
1931entry:
1932  %0 = and i16 %c, 7
1933  %shl = shl nuw nsw i16 1, %0
1934  %1 = atomicrmw xor ptr %v, i16 %shl monotonic, align 2
1935  %conv5 = zext i16 %1 to i32
1936  %conv6 = zext i16 %0 to i32
1937  %shl7 = shl nuw nsw i32 1, %conv6
1938  %and = and i32 %shl7, %conv5
1939  %tobool.not = icmp eq i32 %and, 0
1940  br i1 %tobool.not, label %if.then, label %return
1941
1942if.then:                                          ; preds = %entry
1943  %conv2 = zext i16 %0 to i64
1944  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %conv2
1945  %2 = load i16, ptr %arrayidx, align 2
1946  br label %return
1947
1948return:                                           ; preds = %entry, %if.then
1949  %retval.0 = phi i16 [ %2, %if.then ], [ 123, %entry ]
1950  ret i16 %retval.0
1951}
1952
1953define zeroext i16 @atomic_shl1_mask0_xor_16_gpr_brz(ptr %v, i16 zeroext %c) nounwind {
1954; X86-LABEL: atomic_shl1_mask0_xor_16_gpr_brz:
1955; X86:       # %bb.0: # %entry
1956; X86-NEXT:    pushl %ebx
1957; X86-NEXT:    pushl %esi
1958; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ebx
1959; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
1960; X86-NEXT:    movl %ebx, %ecx
1961; X86-NEXT:    andb $15, %cl
1962; X86-NEXT:    movl $1, %esi
1963; X86-NEXT:    shll %cl, %esi
1964; X86-NEXT:    movzwl (%edx), %eax
1965; X86-NEXT:    .p2align 4
1966; X86-NEXT:  .LBB32_1: # %atomicrmw.start
1967; X86-NEXT:    # =>This Inner Loop Header: Depth=1
1968; X86-NEXT:    movl %eax, %ecx
1969; X86-NEXT:    xorl %esi, %ecx
1970; X86-NEXT:    # kill: def $ax killed $ax killed $eax
1971; X86-NEXT:    lock cmpxchgw %cx, (%edx)
1972; X86-NEXT:    # kill: def $ax killed $ax def $eax
1973; X86-NEXT:    jne .LBB32_1
1974; X86-NEXT:  # %bb.2: # %atomicrmw.end
1975; X86-NEXT:    movzwl %ax, %ecx
1976; X86-NEXT:    movw $123, %ax
1977; X86-NEXT:    btl %ebx, %ecx
1978; X86-NEXT:    jb .LBB32_4
1979; X86-NEXT:  # %bb.3: # %if.then
1980; X86-NEXT:    movzwl %bx, %eax
1981; X86-NEXT:    movzwl (%edx,%eax,2), %eax
1982; X86-NEXT:  .LBB32_4: # %return
1983; X86-NEXT:    popl %esi
1984; X86-NEXT:    popl %ebx
1985; X86-NEXT:    retl
1986;
1987; X64-LABEL: atomic_shl1_mask0_xor_16_gpr_brz:
1988; X64:       # %bb.0: # %entry
1989; X64-NEXT:    movl %esi, %ecx
1990; X64-NEXT:    andb $15, %cl
1991; X64-NEXT:    movl $1, %edx
1992; X64-NEXT:    shll %cl, %edx
1993; X64-NEXT:    movzwl (%rdi), %eax
1994; X64-NEXT:    .p2align 4
1995; X64-NEXT:  .LBB32_1: # %atomicrmw.start
1996; X64-NEXT:    # =>This Inner Loop Header: Depth=1
1997; X64-NEXT:    movl %eax, %ecx
1998; X64-NEXT:    xorl %edx, %ecx
1999; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2000; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
2001; X64-NEXT:    # kill: def $ax killed $ax def $eax
2002; X64-NEXT:    jne .LBB32_1
2003; X64-NEXT:  # %bb.2: # %atomicrmw.end
2004; X64-NEXT:    movzwl %ax, %ecx
2005; X64-NEXT:    movw $123, %ax
2006; X64-NEXT:    btl %esi, %ecx
2007; X64-NEXT:    jae .LBB32_3
2008; X64-NEXT:  # %bb.4: # %return
2009; X64-NEXT:    retq
2010; X64-NEXT:  .LBB32_3: # %if.then
2011; X64-NEXT:    movzwl %si, %eax
2012; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
2013; X64-NEXT:    retq
2014entry:
2015  %0 = and i16 %c, 15
2016  %shl = shl nuw i16 1, %0
2017  %1 = atomicrmw xor ptr %v, i16 %shl monotonic, align 2
2018  %conv2 = zext i16 %1 to i32
2019  %conv3 = zext i16 %c to i32
2020  %shl4 = shl nuw i32 1, %conv3
2021  %and = and i32 %shl4, %conv2
2022  %tobool.not = icmp eq i32 %and, 0
2023  br i1 %tobool.not, label %if.then, label %return
2024
2025if.then:                                          ; preds = %entry
2026  %conv = zext i16 %c to i64
2027  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %conv
2028  %2 = load i16, ptr %arrayidx, align 2
2029  br label %return
2030
2031return:                                           ; preds = %entry, %if.then
2032  %retval.0 = phi i16 [ %2, %if.then ], [ 123, %entry ]
2033  ret i16 %retval.0
2034}
2035
2036define zeroext i16 @atomic_shl1_mask1_xor_16_gpr_brz(ptr %v, i16 zeroext %c) nounwind {
2037; X86-LABEL: atomic_shl1_mask1_xor_16_gpr_brz:
2038; X86:       # %bb.0: # %entry
2039; X86-NEXT:    pushl %edi
2040; X86-NEXT:    pushl %esi
2041; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
2042; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2043; X86-NEXT:    movl $1, %esi
2044; X86-NEXT:    shll %cl, %esi
2045; X86-NEXT:    movzwl (%edx), %eax
2046; X86-NEXT:    .p2align 4
2047; X86-NEXT:  .LBB33_1: # %atomicrmw.start
2048; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2049; X86-NEXT:    movl %eax, %edi
2050; X86-NEXT:    xorl %esi, %edi
2051; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2052; X86-NEXT:    lock cmpxchgw %di, (%edx)
2053; X86-NEXT:    # kill: def $ax killed $ax def $eax
2054; X86-NEXT:    jne .LBB33_1
2055; X86-NEXT:  # %bb.2: # %atomicrmw.end
2056; X86-NEXT:    movzwl %ax, %esi
2057; X86-NEXT:    movl %ecx, %edi
2058; X86-NEXT:    andl $15, %edi
2059; X86-NEXT:    movw $123, %ax
2060; X86-NEXT:    btl %edi, %esi
2061; X86-NEXT:    jb .LBB33_4
2062; X86-NEXT:  # %bb.3: # %if.then
2063; X86-NEXT:    movzwl %cx, %eax
2064; X86-NEXT:    movzwl (%edx,%eax,2), %eax
2065; X86-NEXT:  .LBB33_4: # %return
2066; X86-NEXT:    popl %esi
2067; X86-NEXT:    popl %edi
2068; X86-NEXT:    retl
2069;
2070; X64-LABEL: atomic_shl1_mask1_xor_16_gpr_brz:
2071; X64:       # %bb.0: # %entry
2072; X64-NEXT:    movl %esi, %ecx
2073; X64-NEXT:    movl $1, %edx
2074; X64-NEXT:    shll %cl, %edx
2075; X64-NEXT:    movzwl (%rdi), %eax
2076; X64-NEXT:    .p2align 4
2077; X64-NEXT:  .LBB33_1: # %atomicrmw.start
2078; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2079; X64-NEXT:    movl %eax, %esi
2080; X64-NEXT:    xorl %edx, %esi
2081; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2082; X64-NEXT:    lock cmpxchgw %si, (%rdi)
2083; X64-NEXT:    # kill: def $ax killed $ax def $eax
2084; X64-NEXT:    jne .LBB33_1
2085; X64-NEXT:  # %bb.2: # %atomicrmw.end
2086; X64-NEXT:    movzwl %ax, %edx
2087; X64-NEXT:    movl %ecx, %esi
2088; X64-NEXT:    andl $15, %esi
2089; X64-NEXT:    movw $123, %ax
2090; X64-NEXT:    btl %esi, %edx
2091; X64-NEXT:    jae .LBB33_3
2092; X64-NEXT:  # %bb.4: # %return
2093; X64-NEXT:    retq
2094; X64-NEXT:  .LBB33_3: # %if.then
2095; X64-NEXT:    movzwl %cx, %eax
2096; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
2097; X64-NEXT:    retq
2098entry:
2099  %conv = zext i16 %c to i32
2100  %shl = shl nuw i32 1, %conv
2101  %conv1 = trunc i32 %shl to i16
2102  %0 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
2103  %conv2 = zext i16 %0 to i32
2104  %1 = and i16 %c, 15
2105  %sh_prom = zext i16 %1 to i32
2106  %shl4 = shl nuw nsw i32 1, %sh_prom
2107  %and = and i32 %shl4, %conv2
2108  %tobool.not = icmp eq i32 %and, 0
2109  br i1 %tobool.not, label %if.then, label %return
2110
2111if.then:                                          ; preds = %entry
2112  %conv3 = zext i16 %c to i64
2113  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %conv3
2114  %2 = load i16, ptr %arrayidx, align 2
2115  br label %return
2116
2117return:                                           ; preds = %entry, %if.then
2118  %retval.0 = phi i16 [ %2, %if.then ], [ 123, %entry ]
2119  ret i16 %retval.0
2120}
2121
2122define zeroext i16 @atomic_shl1_mask01_xor_16_gpr_brz(ptr %v, i16 zeroext %c) nounwind {
2123; X86-LABEL: atomic_shl1_mask01_xor_16_gpr_brz:
2124; X86:       # %bb.0: # %entry
2125; X86-NEXT:    pushl %ebx
2126; X86-NEXT:    pushl %esi
2127; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ebx
2128; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2129; X86-NEXT:    movl %ebx, %ecx
2130; X86-NEXT:    andb $15, %cl
2131; X86-NEXT:    movl $1, %esi
2132; X86-NEXT:    shll %cl, %esi
2133; X86-NEXT:    movzwl (%edx), %eax
2134; X86-NEXT:    .p2align 4
2135; X86-NEXT:  .LBB34_1: # %atomicrmw.start
2136; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2137; X86-NEXT:    movl %eax, %ecx
2138; X86-NEXT:    xorl %esi, %ecx
2139; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2140; X86-NEXT:    lock cmpxchgw %cx, (%edx)
2141; X86-NEXT:    # kill: def $ax killed $ax def $eax
2142; X86-NEXT:    jne .LBB34_1
2143; X86-NEXT:  # %bb.2: # %atomicrmw.end
2144; X86-NEXT:    movzwl %ax, %ecx
2145; X86-NEXT:    movw $123, %ax
2146; X86-NEXT:    testl %ecx, %esi
2147; X86-NEXT:    jne .LBB34_4
2148; X86-NEXT:  # %bb.3: # %if.then
2149; X86-NEXT:    movzwl %bx, %eax
2150; X86-NEXT:    movzwl (%edx,%eax,2), %eax
2151; X86-NEXT:  .LBB34_4: # %return
2152; X86-NEXT:    popl %esi
2153; X86-NEXT:    popl %ebx
2154; X86-NEXT:    retl
2155;
2156; X64-LABEL: atomic_shl1_mask01_xor_16_gpr_brz:
2157; X64:       # %bb.0: # %entry
2158; X64-NEXT:    movl %esi, %ecx
2159; X64-NEXT:    andb $15, %cl
2160; X64-NEXT:    movl $1, %edx
2161; X64-NEXT:    shll %cl, %edx
2162; X64-NEXT:    movzwl (%rdi), %eax
2163; X64-NEXT:    .p2align 4
2164; X64-NEXT:  .LBB34_1: # %atomicrmw.start
2165; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2166; X64-NEXT:    movl %eax, %ecx
2167; X64-NEXT:    xorl %edx, %ecx
2168; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2169; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
2170; X64-NEXT:    # kill: def $ax killed $ax def $eax
2171; X64-NEXT:    jne .LBB34_1
2172; X64-NEXT:  # %bb.2: # %atomicrmw.end
2173; X64-NEXT:    movzwl %ax, %ecx
2174; X64-NEXT:    movw $123, %ax
2175; X64-NEXT:    testl %ecx, %edx
2176; X64-NEXT:    je .LBB34_3
2177; X64-NEXT:  # %bb.4: # %return
2178; X64-NEXT:    retq
2179; X64-NEXT:  .LBB34_3: # %if.then
2180; X64-NEXT:    movzwl %si, %eax
2181; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
2182; X64-NEXT:    retq
2183entry:
2184  %0 = and i16 %c, 15
2185  %sh_prom = zext i16 %0 to i32
2186  %shl = shl nuw nsw i32 1, %sh_prom
2187  %conv1 = trunc i32 %shl to i16
2188  %1 = atomicrmw xor ptr %v, i16 %conv1 monotonic, align 2
2189  %conv2 = zext i16 %1 to i32
2190  %and = and i32 %shl, %conv2
2191  %tobool.not = icmp eq i32 %and, 0
2192  br i1 %tobool.not, label %if.then, label %return
2193
2194if.then:                                          ; preds = %entry
2195  %conv = zext i16 %c to i64
2196  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %conv
2197  %2 = load i16, ptr %arrayidx, align 2
2198  br label %return
2199
2200return:                                           ; preds = %entry, %if.then
2201  %retval.0 = phi i16 [ %2, %if.then ], [ 123, %entry ]
2202  ret i16 %retval.0
2203}
2204
2205define zeroext i16 @atomic_blsi_xor_16_gpr_brz(ptr %v, i16 zeroext %c) nounwind {
2206; X86-LABEL: atomic_blsi_xor_16_gpr_brz:
2207; X86:       # %bb.0: # %entry
2208; X86-NEXT:    pushl %edi
2209; X86-NEXT:    pushl %esi
2210; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
2211; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2212; X86-NEXT:    movl %ecx, %esi
2213; X86-NEXT:    negl %esi
2214; X86-NEXT:    andl %ecx, %esi
2215; X86-NEXT:    movzwl (%edx), %eax
2216; X86-NEXT:    .p2align 4
2217; X86-NEXT:  .LBB35_1: # %atomicrmw.start
2218; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2219; X86-NEXT:    movl %eax, %edi
2220; X86-NEXT:    xorl %esi, %edi
2221; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2222; X86-NEXT:    lock cmpxchgw %di, (%edx)
2223; X86-NEXT:    # kill: def $ax killed $ax def $eax
2224; X86-NEXT:    jne .LBB35_1
2225; X86-NEXT:  # %bb.2: # %atomicrmw.end
2226; X86-NEXT:    movzwl %ax, %edi
2227; X86-NEXT:    movw $123, %ax
2228; X86-NEXT:    testl %edi, %esi
2229; X86-NEXT:    jne .LBB35_4
2230; X86-NEXT:  # %bb.3: # %if.then
2231; X86-NEXT:    movzwl %cx, %eax
2232; X86-NEXT:    movzwl (%edx,%eax,2), %eax
2233; X86-NEXT:  .LBB35_4: # %return
2234; X86-NEXT:    popl %esi
2235; X86-NEXT:    popl %edi
2236; X86-NEXT:    retl
2237;
2238; X64-LABEL: atomic_blsi_xor_16_gpr_brz:
2239; X64:       # %bb.0: # %entry
2240; X64-NEXT:    movl %esi, %ecx
2241; X64-NEXT:    negl %ecx
2242; X64-NEXT:    andl %esi, %ecx
2243; X64-NEXT:    movzwl (%rdi), %eax
2244; X64-NEXT:    .p2align 4
2245; X64-NEXT:  .LBB35_1: # %atomicrmw.start
2246; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2247; X64-NEXT:    movl %eax, %edx
2248; X64-NEXT:    xorl %ecx, %edx
2249; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2250; X64-NEXT:    lock cmpxchgw %dx, (%rdi)
2251; X64-NEXT:    # kill: def $ax killed $ax def $eax
2252; X64-NEXT:    jne .LBB35_1
2253; X64-NEXT:  # %bb.2: # %atomicrmw.end
2254; X64-NEXT:    movzwl %ax, %edx
2255; X64-NEXT:    movw $123, %ax
2256; X64-NEXT:    testl %edx, %ecx
2257; X64-NEXT:    je .LBB35_3
2258; X64-NEXT:  # %bb.4: # %return
2259; X64-NEXT:    retq
2260; X64-NEXT:  .LBB35_3: # %if.then
2261; X64-NEXT:    movzwl %si, %eax
2262; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
2263; X64-NEXT:    retq
2264entry:
2265  %conv = zext i16 %c to i32
2266  %sub = sub nsw i32 0, %conv
2267  %and = and i32 %conv, %sub
2268  %conv2 = trunc i32 %and to i16
2269  %0 = atomicrmw xor ptr %v, i16 %conv2 monotonic, align 2
2270  %conv3 = zext i16 %0 to i32
2271  %and8 = and i32 %and, %conv3
2272  %tobool.not = icmp eq i32 %and8, 0
2273  br i1 %tobool.not, label %if.then, label %return
2274
2275if.then:                                          ; preds = %entry
2276  %idxprom = zext i16 %c to i64
2277  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %idxprom
2278  %1 = load i16, ptr %arrayidx, align 2
2279  br label %return
2280
2281return:                                           ; preds = %entry, %if.then
2282  %retval.0 = phi i16 [ %1, %if.then ], [ 123, %entry ]
2283  ret i16 %retval.0
2284}
2285
2286define zeroext i16 @atomic_shl1_and_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
2287; X86-LABEL: atomic_shl1_and_16_gpr_val:
2288; X86:       # %bb.0: # %entry
2289; X86-NEXT:    pushl %edi
2290; X86-NEXT:    pushl %esi
2291; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
2292; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2293; X86-NEXT:    movl $1, %edx
2294; X86-NEXT:    shll %cl, %edx
2295; X86-NEXT:    movl $-2, %edi
2296; X86-NEXT:    roll %cl, %edi
2297; X86-NEXT:    movzwl (%esi), %eax
2298; X86-NEXT:    .p2align 4
2299; X86-NEXT:  .LBB36_1: # %atomicrmw.start
2300; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2301; X86-NEXT:    movl %eax, %ecx
2302; X86-NEXT:    andl %edi, %ecx
2303; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2304; X86-NEXT:    lock cmpxchgw %cx, (%esi)
2305; X86-NEXT:    # kill: def $ax killed $ax def $eax
2306; X86-NEXT:    jne .LBB36_1
2307; X86-NEXT:  # %bb.2: # %atomicrmw.end
2308; X86-NEXT:    andl %edx, %eax
2309; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2310; X86-NEXT:    popl %esi
2311; X86-NEXT:    popl %edi
2312; X86-NEXT:    retl
2313;
2314; X64-LABEL: atomic_shl1_and_16_gpr_val:
2315; X64:       # %bb.0: # %entry
2316; X64-NEXT:    movl %esi, %ecx
2317; X64-NEXT:    movl $1, %edx
2318; X64-NEXT:    shll %cl, %edx
2319; X64-NEXT:    movl $-2, %esi
2320; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
2321; X64-NEXT:    roll %cl, %esi
2322; X64-NEXT:    movzwl (%rdi), %eax
2323; X64-NEXT:    .p2align 4
2324; X64-NEXT:  .LBB36_1: # %atomicrmw.start
2325; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2326; X64-NEXT:    movl %eax, %ecx
2327; X64-NEXT:    andl %esi, %ecx
2328; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2329; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
2330; X64-NEXT:    # kill: def $ax killed $ax def $eax
2331; X64-NEXT:    jne .LBB36_1
2332; X64-NEXT:  # %bb.2: # %atomicrmw.end
2333; X64-NEXT:    andl %edx, %eax
2334; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2335; X64-NEXT:    retq
2336entry:
2337  %conv = zext i16 %c to i32
2338  %shl = shl nuw i32 1, %conv
2339  %0 = trunc i32 %shl to i16
2340  %conv1 = xor i16 %0, -1
2341  %1 = atomicrmw and ptr %v, i16 %conv1 monotonic, align 2
2342  %conv5 = and i16 %1, %0
2343  ret i16 %conv5
2344}
2345
2346define zeroext i16 @atomic_shl1_small_mask_and_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
2347; X86-LABEL: atomic_shl1_small_mask_and_16_gpr_val:
2348; X86:       # %bb.0: # %entry
2349; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2350; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
2351; X86-NEXT:    andl $7, %ecx
2352; X86-NEXT:    xorl %eax, %eax
2353; X86-NEXT:    lock btrw %cx, (%edx)
2354; X86-NEXT:    setb %al
2355; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
2356; X86-NEXT:    shll %cl, %eax
2357; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2358; X86-NEXT:    retl
2359;
2360; X64-LABEL: atomic_shl1_small_mask_and_16_gpr_val:
2361; X64:       # %bb.0: # %entry
2362; X64-NEXT:    movl %esi, %ecx
2363; X64-NEXT:    andl $7, %ecx
2364; X64-NEXT:    xorl %eax, %eax
2365; X64-NEXT:    lock btrw %cx, (%rdi)
2366; X64-NEXT:    setb %al
2367; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
2368; X64-NEXT:    shll %cl, %eax
2369; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2370; X64-NEXT:    retq
2371entry:
2372  %0 = and i16 %c, 7
2373  %shl = shl nuw nsw i16 1, %0
2374  %not = xor i16 %shl, -1
2375  %1 = atomicrmw and ptr %v, i16 %not monotonic, align 2
2376  %and = and i16 %shl, %1
2377  ret i16 %and
2378}
2379
2380define zeroext i16 @atomic_shl1_mask0_and_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
2381; X86-LABEL: atomic_shl1_mask0_and_16_gpr_val:
2382; X86:       # %bb.0: # %entry
2383; X86-NEXT:    pushl %edi
2384; X86-NEXT:    pushl %esi
2385; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
2386; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2387; X86-NEXT:    movw $-2, %si
2388; X86-NEXT:    rolw %cl, %si
2389; X86-NEXT:    movzwl (%edx), %eax
2390; X86-NEXT:    .p2align 4
2391; X86-NEXT:  .LBB38_1: # %atomicrmw.start
2392; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2393; X86-NEXT:    movl %eax, %edi
2394; X86-NEXT:    andl %esi, %edi
2395; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2396; X86-NEXT:    lock cmpxchgw %di, (%edx)
2397; X86-NEXT:    # kill: def $ax killed $ax def $eax
2398; X86-NEXT:    jne .LBB38_1
2399; X86-NEXT:  # %bb.2: # %atomicrmw.end
2400; X86-NEXT:    movl $1, %edx
2401; X86-NEXT:    # kill: def $cl killed $cl killed $cx
2402; X86-NEXT:    shll %cl, %edx
2403; X86-NEXT:    andl %edx, %eax
2404; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2405; X86-NEXT:    popl %esi
2406; X86-NEXT:    popl %edi
2407; X86-NEXT:    retl
2408;
2409; X64-LABEL: atomic_shl1_mask0_and_16_gpr_val:
2410; X64:       # %bb.0: # %entry
2411; X64-NEXT:    movl %esi, %ecx
2412; X64-NEXT:    movw $-2, %dx
2413; X64-NEXT:    rolw %cl, %dx
2414; X64-NEXT:    movzwl (%rdi), %eax
2415; X64-NEXT:    .p2align 4
2416; X64-NEXT:  .LBB38_1: # %atomicrmw.start
2417; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2418; X64-NEXT:    movl %eax, %esi
2419; X64-NEXT:    andl %edx, %esi
2420; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2421; X64-NEXT:    lock cmpxchgw %si, (%rdi)
2422; X64-NEXT:    # kill: def $ax killed $ax def $eax
2423; X64-NEXT:    jne .LBB38_1
2424; X64-NEXT:  # %bb.2: # %atomicrmw.end
2425; X64-NEXT:    movl $1, %edx
2426; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
2427; X64-NEXT:    shll %cl, %edx
2428; X64-NEXT:    andl %edx, %eax
2429; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2430; X64-NEXT:    retq
2431entry:
2432  %0 = and i16 %c, 15
2433  %shl = shl nuw i16 1, %0
2434  %not = xor i16 %shl, -1
2435  %1 = atomicrmw and ptr %v, i16 %not monotonic, align 2
2436  %conv3 = zext i16 %c to i32
2437  %shl4 = shl nuw i32 1, %conv3
2438  %2 = trunc i32 %shl4 to i16
2439  %conv5 = and i16 %1, %2
2440  ret i16 %conv5
2441}
2442
2443define zeroext i16 @atomic_shl1_mask1_and_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
2444; X86-LABEL: atomic_shl1_mask1_and_16_gpr_val:
2445; X86:       # %bb.0: # %entry
2446; X86-NEXT:    pushl %edi
2447; X86-NEXT:    pushl %esi
2448; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
2449; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2450; X86-NEXT:    movl $-2, %esi
2451; X86-NEXT:    roll %cl, %esi
2452; X86-NEXT:    movzwl (%edx), %eax
2453; X86-NEXT:    .p2align 4
2454; X86-NEXT:  .LBB39_1: # %atomicrmw.start
2455; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2456; X86-NEXT:    movl %eax, %edi
2457; X86-NEXT:    andl %esi, %edi
2458; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2459; X86-NEXT:    lock cmpxchgw %di, (%edx)
2460; X86-NEXT:    # kill: def $ax killed $ax def $eax
2461; X86-NEXT:    jne .LBB39_1
2462; X86-NEXT:  # %bb.2: # %atomicrmw.end
2463; X86-NEXT:    andb $15, %cl
2464; X86-NEXT:    movl $1, %edx
2465; X86-NEXT:    # kill: def $cl killed $cl killed $cx
2466; X86-NEXT:    shll %cl, %edx
2467; X86-NEXT:    andl %edx, %eax
2468; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2469; X86-NEXT:    popl %esi
2470; X86-NEXT:    popl %edi
2471; X86-NEXT:    retl
2472;
2473; X64-LABEL: atomic_shl1_mask1_and_16_gpr_val:
2474; X64:       # %bb.0: # %entry
2475; X64-NEXT:    movl %esi, %ecx
2476; X64-NEXT:    movl $-2, %edx
2477; X64-NEXT:    roll %cl, %edx
2478; X64-NEXT:    movzwl (%rdi), %eax
2479; X64-NEXT:    .p2align 4
2480; X64-NEXT:  .LBB39_1: # %atomicrmw.start
2481; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2482; X64-NEXT:    movl %eax, %esi
2483; X64-NEXT:    andl %edx, %esi
2484; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2485; X64-NEXT:    lock cmpxchgw %si, (%rdi)
2486; X64-NEXT:    # kill: def $ax killed $ax def $eax
2487; X64-NEXT:    jne .LBB39_1
2488; X64-NEXT:  # %bb.2: # %atomicrmw.end
2489; X64-NEXT:    andb $15, %cl
2490; X64-NEXT:    movl $1, %edx
2491; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
2492; X64-NEXT:    shll %cl, %edx
2493; X64-NEXT:    andl %edx, %eax
2494; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2495; X64-NEXT:    retq
2496entry:
2497  %conv = zext i16 %c to i32
2498  %shl = shl nuw i32 1, %conv
2499  %0 = trunc i32 %shl to i16
2500  %conv1 = xor i16 %0, -1
2501  %1 = atomicrmw and ptr %v, i16 %conv1 monotonic, align 2
2502  %2 = and i16 %c, 15
2503  %shl4 = shl nuw i16 1, %2
2504  %and = and i16 %1, %shl4
2505  ret i16 %and
2506}
2507
2508define zeroext i16 @atomic_shl1_mask01_and_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
2509; X86-LABEL: atomic_shl1_mask01_and_16_gpr_val:
2510; X86:       # %bb.0: # %entry
2511; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2512; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
2513; X86-NEXT:    andl $15, %ecx
2514; X86-NEXT:    xorl %eax, %eax
2515; X86-NEXT:    lock btrw %cx, (%edx)
2516; X86-NEXT:    setb %al
2517; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
2518; X86-NEXT:    shll %cl, %eax
2519; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2520; X86-NEXT:    retl
2521;
2522; X64-LABEL: atomic_shl1_mask01_and_16_gpr_val:
2523; X64:       # %bb.0: # %entry
2524; X64-NEXT:    movl %esi, %ecx
2525; X64-NEXT:    andl $15, %ecx
2526; X64-NEXT:    xorl %eax, %eax
2527; X64-NEXT:    lock btrw %cx, (%rdi)
2528; X64-NEXT:    setb %al
2529; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
2530; X64-NEXT:    shll %cl, %eax
2531; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2532; X64-NEXT:    retq
2533entry:
2534  %0 = and i16 %c, 15
2535  %shl = shl nuw i16 1, %0
2536  %conv1 = xor i16 %shl, -1
2537  %1 = atomicrmw and ptr %v, i16 %conv1 monotonic, align 2
2538  %conv7 = and i16 %1, %shl
2539  ret i16 %conv7
2540}
2541
2542define zeroext i16 @atomic_blsi_and_16_gpr_val(ptr %v, i16 zeroext %c) nounwind {
2543; X86-LABEL: atomic_blsi_and_16_gpr_val:
2544; X86:       # %bb.0: # %entry
2545; X86-NEXT:    pushl %edi
2546; X86-NEXT:    pushl %esi
2547; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2548; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
2549; X86-NEXT:    movl %eax, %ecx
2550; X86-NEXT:    negl %ecx
2551; X86-NEXT:    andl %eax, %ecx
2552; X86-NEXT:    movl %ecx, %esi
2553; X86-NEXT:    notl %esi
2554; X86-NEXT:    movzwl (%edx), %eax
2555; X86-NEXT:    .p2align 4
2556; X86-NEXT:  .LBB41_1: # %atomicrmw.start
2557; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2558; X86-NEXT:    movl %eax, %edi
2559; X86-NEXT:    andl %esi, %edi
2560; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2561; X86-NEXT:    lock cmpxchgw %di, (%edx)
2562; X86-NEXT:    # kill: def $ax killed $ax def $eax
2563; X86-NEXT:    jne .LBB41_1
2564; X86-NEXT:  # %bb.2: # %atomicrmw.end
2565; X86-NEXT:    andl %ecx, %eax
2566; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2567; X86-NEXT:    popl %esi
2568; X86-NEXT:    popl %edi
2569; X86-NEXT:    retl
2570;
2571; X64-LABEL: atomic_blsi_and_16_gpr_val:
2572; X64:       # %bb.0: # %entry
2573; X64-NEXT:    movl %esi, %ecx
2574; X64-NEXT:    negl %ecx
2575; X64-NEXT:    andl %esi, %ecx
2576; X64-NEXT:    movl %ecx, %edx
2577; X64-NEXT:    notl %edx
2578; X64-NEXT:    movzwl (%rdi), %eax
2579; X64-NEXT:    .p2align 4
2580; X64-NEXT:  .LBB41_1: # %atomicrmw.start
2581; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2582; X64-NEXT:    movl %eax, %esi
2583; X64-NEXT:    andl %edx, %esi
2584; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2585; X64-NEXT:    lock cmpxchgw %si, (%rdi)
2586; X64-NEXT:    # kill: def $ax killed $ax def $eax
2587; X64-NEXT:    jne .LBB41_1
2588; X64-NEXT:  # %bb.2: # %atomicrmw.end
2589; X64-NEXT:    andl %ecx, %eax
2590; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2591; X64-NEXT:    retq
2592entry:
2593  %sub = sub i16 0, %c
2594  %and = and i16 %sub, %c
2595  %conv2 = xor i16 %and, -1
2596  %0 = atomicrmw and ptr %v, i16 %conv2 monotonic, align 2
2597  %conv9 = and i16 %0, %and
2598  ret i16 %conv9
2599}
2600
2601define zeroext i16 @atomic_shl1_and_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
2602; X86-LABEL: atomic_shl1_and_16_gpr_valnz:
2603; X86:       # %bb.0: # %entry
2604; X86-NEXT:    pushl %edi
2605; X86-NEXT:    pushl %esi
2606; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
2607; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2608; X86-NEXT:    movl $1, %edx
2609; X86-NEXT:    shll %cl, %edx
2610; X86-NEXT:    movl $-2, %edi
2611; X86-NEXT:    roll %cl, %edi
2612; X86-NEXT:    movzwl (%esi), %eax
2613; X86-NEXT:    .p2align 4
2614; X86-NEXT:  .LBB42_1: # %atomicrmw.start
2615; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2616; X86-NEXT:    movl %eax, %ecx
2617; X86-NEXT:    andl %edi, %ecx
2618; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2619; X86-NEXT:    lock cmpxchgw %cx, (%esi)
2620; X86-NEXT:    # kill: def $ax killed $ax def $eax
2621; X86-NEXT:    jne .LBB42_1
2622; X86-NEXT:  # %bb.2: # %atomicrmw.end
2623; X86-NEXT:    movzwl %ax, %ecx
2624; X86-NEXT:    xorl %eax, %eax
2625; X86-NEXT:    testl %ecx, %edx
2626; X86-NEXT:    setne %al
2627; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2628; X86-NEXT:    popl %esi
2629; X86-NEXT:    popl %edi
2630; X86-NEXT:    retl
2631;
2632; X64-LABEL: atomic_shl1_and_16_gpr_valnz:
2633; X64:       # %bb.0: # %entry
2634; X64-NEXT:    movl %esi, %ecx
2635; X64-NEXT:    movl $1, %edx
2636; X64-NEXT:    shll %cl, %edx
2637; X64-NEXT:    movl $-2, %esi
2638; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
2639; X64-NEXT:    roll %cl, %esi
2640; X64-NEXT:    movzwl (%rdi), %eax
2641; X64-NEXT:    .p2align 4
2642; X64-NEXT:  .LBB42_1: # %atomicrmw.start
2643; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2644; X64-NEXT:    movl %eax, %ecx
2645; X64-NEXT:    andl %esi, %ecx
2646; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2647; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
2648; X64-NEXT:    # kill: def $ax killed $ax def $eax
2649; X64-NEXT:    jne .LBB42_1
2650; X64-NEXT:  # %bb.2: # %atomicrmw.end
2651; X64-NEXT:    movzwl %ax, %ecx
2652; X64-NEXT:    xorl %eax, %eax
2653; X64-NEXT:    testl %ecx, %edx
2654; X64-NEXT:    setne %al
2655; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2656; X64-NEXT:    retq
2657entry:
2658  %conv = zext i16 %c to i32
2659  %shl = shl nuw i32 1, %conv
2660  %0 = trunc i32 %shl to i16
2661  %conv1 = xor i16 %0, -1
2662  %1 = atomicrmw and ptr %v, i16 %conv1 monotonic, align 2
2663  %conv2 = zext i16 %1 to i32
2664  %and = and i32 %shl, %conv2
2665  %tobool = icmp ne i32 %and, 0
2666  %conv6 = zext i1 %tobool to i16
2667  ret i16 %conv6
2668}
2669
2670define zeroext i16 @atomic_shl1_small_mask_and_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
2671; X86-LABEL: atomic_shl1_small_mask_and_16_gpr_valnz:
2672; X86:       # %bb.0: # %entry
2673; X86-NEXT:    pushl %edi
2674; X86-NEXT:    pushl %esi
2675; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2676; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
2677; X86-NEXT:    andl $7, %ecx
2678; X86-NEXT:    movw $-2, %si
2679; X86-NEXT:    rolw %cl, %si
2680; X86-NEXT:    movzwl (%edx), %eax
2681; X86-NEXT:    .p2align 4
2682; X86-NEXT:  .LBB43_1: # %atomicrmw.start
2683; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2684; X86-NEXT:    movl %eax, %edi
2685; X86-NEXT:    andl %esi, %edi
2686; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2687; X86-NEXT:    lock cmpxchgw %di, (%edx)
2688; X86-NEXT:    # kill: def $ax killed $ax def $eax
2689; X86-NEXT:    jne .LBB43_1
2690; X86-NEXT:  # %bb.2: # %atomicrmw.end
2691; X86-NEXT:    movzwl %ax, %edx
2692; X86-NEXT:    xorl %eax, %eax
2693; X86-NEXT:    btl %ecx, %edx
2694; X86-NEXT:    setb %al
2695; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2696; X86-NEXT:    popl %esi
2697; X86-NEXT:    popl %edi
2698; X86-NEXT:    retl
2699;
2700; X64-LABEL: atomic_shl1_small_mask_and_16_gpr_valnz:
2701; X64:       # %bb.0: # %entry
2702; X64-NEXT:    movl %esi, %ecx
2703; X64-NEXT:    andl $7, %ecx
2704; X64-NEXT:    movw $-2, %dx
2705; X64-NEXT:    rolw %cl, %dx
2706; X64-NEXT:    movzwl (%rdi), %eax
2707; X64-NEXT:    .p2align 4
2708; X64-NEXT:  .LBB43_1: # %atomicrmw.start
2709; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2710; X64-NEXT:    movl %eax, %esi
2711; X64-NEXT:    andl %edx, %esi
2712; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2713; X64-NEXT:    lock cmpxchgw %si, (%rdi)
2714; X64-NEXT:    # kill: def $ax killed $ax def $eax
2715; X64-NEXT:    jne .LBB43_1
2716; X64-NEXT:  # %bb.2: # %atomicrmw.end
2717; X64-NEXT:    movzwl %ax, %edx
2718; X64-NEXT:    xorl %eax, %eax
2719; X64-NEXT:    btl %ecx, %edx
2720; X64-NEXT:    setb %al
2721; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2722; X64-NEXT:    retq
2723entry:
2724  %0 = and i16 %c, 7
2725  %shl = shl nuw nsw i16 1, %0
2726  %not = xor i16 %shl, -1
2727  %1 = atomicrmw and ptr %v, i16 %not monotonic, align 2
2728  %conv5 = zext i16 %1 to i32
2729  %conv6 = zext i16 %0 to i32
2730  %shl7 = shl nuw nsw i32 1, %conv6
2731  %and = and i32 %shl7, %conv5
2732  %tobool = icmp ne i32 %and, 0
2733  %conv9 = zext i1 %tobool to i16
2734  ret i16 %conv9
2735}
2736
2737define zeroext i16 @atomic_shl1_mask0_and_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
2738; X86-LABEL: atomic_shl1_mask0_and_16_gpr_valnz:
2739; X86:       # %bb.0: # %entry
2740; X86-NEXT:    pushl %edi
2741; X86-NEXT:    pushl %esi
2742; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
2743; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2744; X86-NEXT:    movw $-2, %si
2745; X86-NEXT:    rolw %cl, %si
2746; X86-NEXT:    movzwl (%edx), %eax
2747; X86-NEXT:    .p2align 4
2748; X86-NEXT:  .LBB44_1: # %atomicrmw.start
2749; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2750; X86-NEXT:    movl %eax, %edi
2751; X86-NEXT:    andl %esi, %edi
2752; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2753; X86-NEXT:    lock cmpxchgw %di, (%edx)
2754; X86-NEXT:    # kill: def $ax killed $ax def $eax
2755; X86-NEXT:    jne .LBB44_1
2756; X86-NEXT:  # %bb.2: # %atomicrmw.end
2757; X86-NEXT:    movzwl %ax, %edx
2758; X86-NEXT:    xorl %eax, %eax
2759; X86-NEXT:    btl %ecx, %edx
2760; X86-NEXT:    setb %al
2761; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2762; X86-NEXT:    popl %esi
2763; X86-NEXT:    popl %edi
2764; X86-NEXT:    retl
2765;
2766; X64-LABEL: atomic_shl1_mask0_and_16_gpr_valnz:
2767; X64:       # %bb.0: # %entry
2768; X64-NEXT:    movl %esi, %ecx
2769; X64-NEXT:    movw $-2, %dx
2770; X64-NEXT:    rolw %cl, %dx
2771; X64-NEXT:    movzwl (%rdi), %eax
2772; X64-NEXT:    .p2align 4
2773; X64-NEXT:  .LBB44_1: # %atomicrmw.start
2774; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2775; X64-NEXT:    movl %eax, %esi
2776; X64-NEXT:    andl %edx, %esi
2777; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2778; X64-NEXT:    lock cmpxchgw %si, (%rdi)
2779; X64-NEXT:    # kill: def $ax killed $ax def $eax
2780; X64-NEXT:    jne .LBB44_1
2781; X64-NEXT:  # %bb.2: # %atomicrmw.end
2782; X64-NEXT:    movzwl %ax, %edx
2783; X64-NEXT:    xorl %eax, %eax
2784; X64-NEXT:    btl %ecx, %edx
2785; X64-NEXT:    setb %al
2786; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2787; X64-NEXT:    retq
2788entry:
2789  %0 = and i16 %c, 15
2790  %shl = shl nuw i16 1, %0
2791  %not = xor i16 %shl, -1
2792  %1 = atomicrmw and ptr %v, i16 %not monotonic, align 2
2793  %conv2 = zext i16 %1 to i32
2794  %conv3 = zext i16 %c to i32
2795  %shl4 = shl nuw i32 1, %conv3
2796  %and = and i32 %shl4, %conv2
2797  %tobool = icmp ne i32 %and, 0
2798  %conv6 = zext i1 %tobool to i16
2799  ret i16 %conv6
2800}
2801
2802define zeroext i16 @atomic_shl1_mask1_and_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
2803; X86-LABEL: atomic_shl1_mask1_and_16_gpr_valnz:
2804; X86:       # %bb.0: # %entry
2805; X86-NEXT:    pushl %edi
2806; X86-NEXT:    pushl %esi
2807; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
2808; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2809; X86-NEXT:    movl $-2, %esi
2810; X86-NEXT:    roll %cl, %esi
2811; X86-NEXT:    movzwl (%edx), %eax
2812; X86-NEXT:    .p2align 4
2813; X86-NEXT:  .LBB45_1: # %atomicrmw.start
2814; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2815; X86-NEXT:    movl %eax, %edi
2816; X86-NEXT:    andl %esi, %edi
2817; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2818; X86-NEXT:    lock cmpxchgw %di, (%edx)
2819; X86-NEXT:    # kill: def $ax killed $ax def $eax
2820; X86-NEXT:    jne .LBB45_1
2821; X86-NEXT:  # %bb.2: # %atomicrmw.end
2822; X86-NEXT:    movzwl %ax, %edx
2823; X86-NEXT:    andl $15, %ecx
2824; X86-NEXT:    xorl %eax, %eax
2825; X86-NEXT:    btl %ecx, %edx
2826; X86-NEXT:    setb %al
2827; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2828; X86-NEXT:    popl %esi
2829; X86-NEXT:    popl %edi
2830; X86-NEXT:    retl
2831;
2832; X64-LABEL: atomic_shl1_mask1_and_16_gpr_valnz:
2833; X64:       # %bb.0: # %entry
2834; X64-NEXT:    movl %esi, %ecx
2835; X64-NEXT:    movl $-2, %edx
2836; X64-NEXT:    roll %cl, %edx
2837; X64-NEXT:    movzwl (%rdi), %eax
2838; X64-NEXT:    .p2align 4
2839; X64-NEXT:  .LBB45_1: # %atomicrmw.start
2840; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2841; X64-NEXT:    movl %eax, %esi
2842; X64-NEXT:    andl %edx, %esi
2843; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2844; X64-NEXT:    lock cmpxchgw %si, (%rdi)
2845; X64-NEXT:    # kill: def $ax killed $ax def $eax
2846; X64-NEXT:    jne .LBB45_1
2847; X64-NEXT:  # %bb.2: # %atomicrmw.end
2848; X64-NEXT:    movzwl %ax, %edx
2849; X64-NEXT:    andl $15, %ecx
2850; X64-NEXT:    xorl %eax, %eax
2851; X64-NEXT:    btl %ecx, %edx
2852; X64-NEXT:    setb %al
2853; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2854; X64-NEXT:    retq
2855entry:
2856  %conv = zext i16 %c to i32
2857  %shl = shl nuw i32 1, %conv
2858  %0 = trunc i32 %shl to i16
2859  %conv1 = xor i16 %0, -1
2860  %1 = atomicrmw and ptr %v, i16 %conv1 monotonic, align 2
2861  %conv2 = zext i16 %1 to i32
2862  %2 = and i16 %c, 15
2863  %sh_prom = zext i16 %2 to i32
2864  %shl4 = shl nuw nsw i32 1, %sh_prom
2865  %and = and i32 %shl4, %conv2
2866  %tobool = icmp ne i32 %and, 0
2867  %conv6 = zext i1 %tobool to i16
2868  ret i16 %conv6
2869}
2870
2871define zeroext i16 @atomic_shl1_mask01_and_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
2872; X86-LABEL: atomic_shl1_mask01_and_16_gpr_valnz:
2873; X86:       # %bb.0: # %entry
2874; X86-NEXT:    pushl %edi
2875; X86-NEXT:    pushl %esi
2876; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2877; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
2878; X86-NEXT:    andb $15, %cl
2879; X86-NEXT:    movl $1, %esi
2880; X86-NEXT:    shll %cl, %esi
2881; X86-NEXT:    movl $-2, %edi
2882; X86-NEXT:    roll %cl, %edi
2883; X86-NEXT:    movzwl (%edx), %eax
2884; X86-NEXT:    .p2align 4
2885; X86-NEXT:  .LBB46_1: # %atomicrmw.start
2886; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2887; X86-NEXT:    movl %eax, %ecx
2888; X86-NEXT:    andl %edi, %ecx
2889; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2890; X86-NEXT:    lock cmpxchgw %cx, (%edx)
2891; X86-NEXT:    # kill: def $ax killed $ax def $eax
2892; X86-NEXT:    jne .LBB46_1
2893; X86-NEXT:  # %bb.2: # %atomicrmw.end
2894; X86-NEXT:    movzwl %ax, %ecx
2895; X86-NEXT:    xorl %eax, %eax
2896; X86-NEXT:    testl %ecx, %esi
2897; X86-NEXT:    setne %al
2898; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2899; X86-NEXT:    popl %esi
2900; X86-NEXT:    popl %edi
2901; X86-NEXT:    retl
2902;
2903; X64-LABEL: atomic_shl1_mask01_and_16_gpr_valnz:
2904; X64:       # %bb.0: # %entry
2905; X64-NEXT:    movl %esi, %ecx
2906; X64-NEXT:    andb $15, %cl
2907; X64-NEXT:    movl $1, %edx
2908; X64-NEXT:    shll %cl, %edx
2909; X64-NEXT:    movl $-2, %esi
2910; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
2911; X64-NEXT:    roll %cl, %esi
2912; X64-NEXT:    movzwl (%rdi), %eax
2913; X64-NEXT:    .p2align 4
2914; X64-NEXT:  .LBB46_1: # %atomicrmw.start
2915; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2916; X64-NEXT:    movl %eax, %ecx
2917; X64-NEXT:    andl %esi, %ecx
2918; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2919; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
2920; X64-NEXT:    # kill: def $ax killed $ax def $eax
2921; X64-NEXT:    jne .LBB46_1
2922; X64-NEXT:  # %bb.2: # %atomicrmw.end
2923; X64-NEXT:    movzwl %ax, %ecx
2924; X64-NEXT:    xorl %eax, %eax
2925; X64-NEXT:    testl %ecx, %edx
2926; X64-NEXT:    setne %al
2927; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2928; X64-NEXT:    retq
2929entry:
2930  %0 = and i16 %c, 15
2931  %sh_prom = zext i16 %0 to i32
2932  %shl = shl nuw nsw i32 1, %sh_prom
2933  %1 = trunc i32 %shl to i16
2934  %conv1 = xor i16 %1, -1
2935  %2 = atomicrmw and ptr %v, i16 %conv1 monotonic, align 2
2936  %conv2 = zext i16 %2 to i32
2937  %and = and i32 %shl, %conv2
2938  %tobool = icmp ne i32 %and, 0
2939  %conv8 = zext i1 %tobool to i16
2940  ret i16 %conv8
2941}
2942
2943define zeroext i16 @atomic_blsi_and_16_gpr_valnz(ptr %v, i16 zeroext %c) nounwind {
2944; X86-LABEL: atomic_blsi_and_16_gpr_valnz:
2945; X86:       # %bb.0: # %entry
2946; X86-NEXT:    pushl %edi
2947; X86-NEXT:    pushl %esi
2948; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
2949; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
2950; X86-NEXT:    movl %eax, %ecx
2951; X86-NEXT:    negl %ecx
2952; X86-NEXT:    andl %eax, %ecx
2953; X86-NEXT:    movl %ecx, %esi
2954; X86-NEXT:    notl %esi
2955; X86-NEXT:    movzwl (%edx), %eax
2956; X86-NEXT:    .p2align 4
2957; X86-NEXT:  .LBB47_1: # %atomicrmw.start
2958; X86-NEXT:    # =>This Inner Loop Header: Depth=1
2959; X86-NEXT:    movl %eax, %edi
2960; X86-NEXT:    andl %esi, %edi
2961; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2962; X86-NEXT:    lock cmpxchgw %di, (%edx)
2963; X86-NEXT:    # kill: def $ax killed $ax def $eax
2964; X86-NEXT:    jne .LBB47_1
2965; X86-NEXT:  # %bb.2: # %atomicrmw.end
2966; X86-NEXT:    movzwl %ax, %edx
2967; X86-NEXT:    xorl %eax, %eax
2968; X86-NEXT:    testl %edx, %ecx
2969; X86-NEXT:    setne %al
2970; X86-NEXT:    # kill: def $ax killed $ax killed $eax
2971; X86-NEXT:    popl %esi
2972; X86-NEXT:    popl %edi
2973; X86-NEXT:    retl
2974;
2975; X64-LABEL: atomic_blsi_and_16_gpr_valnz:
2976; X64:       # %bb.0: # %entry
2977; X64-NEXT:    movl %esi, %ecx
2978; X64-NEXT:    negl %ecx
2979; X64-NEXT:    andl %esi, %ecx
2980; X64-NEXT:    movl %ecx, %edx
2981; X64-NEXT:    notl %edx
2982; X64-NEXT:    movzwl (%rdi), %eax
2983; X64-NEXT:    .p2align 4
2984; X64-NEXT:  .LBB47_1: # %atomicrmw.start
2985; X64-NEXT:    # =>This Inner Loop Header: Depth=1
2986; X64-NEXT:    movl %eax, %esi
2987; X64-NEXT:    andl %edx, %esi
2988; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2989; X64-NEXT:    lock cmpxchgw %si, (%rdi)
2990; X64-NEXT:    # kill: def $ax killed $ax def $eax
2991; X64-NEXT:    jne .LBB47_1
2992; X64-NEXT:  # %bb.2: # %atomicrmw.end
2993; X64-NEXT:    movzwl %ax, %edx
2994; X64-NEXT:    xorl %eax, %eax
2995; X64-NEXT:    testl %edx, %ecx
2996; X64-NEXT:    setne %al
2997; X64-NEXT:    # kill: def $ax killed $ax killed $eax
2998; X64-NEXT:    retq
2999entry:
3000  %conv = zext i16 %c to i32
3001  %sub = sub nsw i32 0, %conv
3002  %and = and i32 %conv, %sub
3003  %0 = trunc i32 %and to i16
3004  %conv2 = xor i16 %0, -1
3005  %1 = atomicrmw and ptr %v, i16 %conv2 monotonic, align 2
3006  %conv3 = zext i16 %1 to i32
3007  %and8 = and i32 %and, %conv3
3008  %tobool = icmp ne i32 %and8, 0
3009  %conv10 = zext i1 %tobool to i16
3010  ret i16 %conv10
3011}
3012
3013define zeroext i16 @atomic_shl1_and_16_gpr_brnz(ptr %v, i16 zeroext %c) nounwind {
3014; X86-LABEL: atomic_shl1_and_16_gpr_brnz:
3015; X86:       # %bb.0: # %entry
3016; X86-NEXT:    pushl %ebx
3017; X86-NEXT:    pushl %edi
3018; X86-NEXT:    pushl %esi
3019; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
3020; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3021; X86-NEXT:    movl $1, %esi
3022; X86-NEXT:    shll %cl, %esi
3023; X86-NEXT:    movl $-2, %edi
3024; X86-NEXT:    roll %cl, %edi
3025; X86-NEXT:    movzwl (%edx), %eax
3026; X86-NEXT:    .p2align 4
3027; X86-NEXT:  .LBB48_1: # %atomicrmw.start
3028; X86-NEXT:    # =>This Inner Loop Header: Depth=1
3029; X86-NEXT:    movl %eax, %ebx
3030; X86-NEXT:    andl %edi, %ebx
3031; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3032; X86-NEXT:    lock cmpxchgw %bx, (%edx)
3033; X86-NEXT:    # kill: def $ax killed $ax def $eax
3034; X86-NEXT:    jne .LBB48_1
3035; X86-NEXT:  # %bb.2: # %atomicrmw.end
3036; X86-NEXT:    movzwl %ax, %eax
3037; X86-NEXT:    testl %eax, %esi
3038; X86-NEXT:    je .LBB48_3
3039; X86-NEXT:  # %bb.4: # %if.then
3040; X86-NEXT:    movzwl %cx, %eax
3041; X86-NEXT:    movzwl (%edx,%eax,2), %eax
3042; X86-NEXT:    jmp .LBB48_5
3043; X86-NEXT:  .LBB48_3:
3044; X86-NEXT:    movw $123, %ax
3045; X86-NEXT:  .LBB48_5: # %return
3046; X86-NEXT:    popl %esi
3047; X86-NEXT:    popl %edi
3048; X86-NEXT:    popl %ebx
3049; X86-NEXT:    retl
3050;
3051; X64-LABEL: atomic_shl1_and_16_gpr_brnz:
3052; X64:       # %bb.0: # %entry
3053; X64-NEXT:    movl %esi, %ecx
3054; X64-NEXT:    movl $1, %edx
3055; X64-NEXT:    shll %cl, %edx
3056; X64-NEXT:    movl $-2, %esi
3057; X64-NEXT:    roll %cl, %esi
3058; X64-NEXT:    movzwl (%rdi), %eax
3059; X64-NEXT:    .p2align 4
3060; X64-NEXT:  .LBB48_1: # %atomicrmw.start
3061; X64-NEXT:    # =>This Inner Loop Header: Depth=1
3062; X64-NEXT:    movl %eax, %r8d
3063; X64-NEXT:    andl %esi, %r8d
3064; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3065; X64-NEXT:    lock cmpxchgw %r8w, (%rdi)
3066; X64-NEXT:    # kill: def $ax killed $ax def $eax
3067; X64-NEXT:    jne .LBB48_1
3068; X64-NEXT:  # %bb.2: # %atomicrmw.end
3069; X64-NEXT:    movzwl %ax, %eax
3070; X64-NEXT:    testl %eax, %edx
3071; X64-NEXT:    je .LBB48_3
3072; X64-NEXT:  # %bb.4: # %if.then
3073; X64-NEXT:    movzwl %cx, %eax
3074; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
3075; X64-NEXT:    retq
3076; X64-NEXT:  .LBB48_3:
3077; X64-NEXT:    movw $123, %ax
3078; X64-NEXT:    retq
3079entry:
3080  %conv = zext i16 %c to i32
3081  %shl = shl nuw i32 1, %conv
3082  %0 = trunc i32 %shl to i16
3083  %conv1 = xor i16 %0, -1
3084  %1 = atomicrmw and ptr %v, i16 %conv1 monotonic, align 2
3085  %conv2 = zext i16 %1 to i32
3086  %and = and i32 %shl, %conv2
3087  %tobool.not = icmp eq i32 %and, 0
3088  br i1 %tobool.not, label %return, label %if.then
3089
3090if.then:                                          ; preds = %entry
3091  %idxprom = zext i16 %c to i64
3092  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %idxprom
3093  %2 = load i16, ptr %arrayidx, align 2
3094  br label %return
3095
3096return:                                           ; preds = %entry, %if.then
3097  %retval.0 = phi i16 [ %2, %if.then ], [ 123, %entry ]
3098  ret i16 %retval.0
3099}
3100
3101define zeroext i16 @atomic_shl1_small_mask_and_16_gpr_brnz(ptr %v, i16 zeroext %c) nounwind {
3102; X86-LABEL: atomic_shl1_small_mask_and_16_gpr_brnz:
3103; X86:       # %bb.0: # %entry
3104; X86-NEXT:    pushl %edi
3105; X86-NEXT:    pushl %esi
3106; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3107; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
3108; X86-NEXT:    andl $7, %ecx
3109; X86-NEXT:    movw $-2, %si
3110; X86-NEXT:    rolw %cl, %si
3111; X86-NEXT:    movzwl (%edx), %eax
3112; X86-NEXT:    .p2align 4
3113; X86-NEXT:  .LBB49_1: # %atomicrmw.start
3114; X86-NEXT:    # =>This Inner Loop Header: Depth=1
3115; X86-NEXT:    movl %eax, %edi
3116; X86-NEXT:    andl %esi, %edi
3117; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3118; X86-NEXT:    lock cmpxchgw %di, (%edx)
3119; X86-NEXT:    # kill: def $ax killed $ax def $eax
3120; X86-NEXT:    jne .LBB49_1
3121; X86-NEXT:  # %bb.2: # %atomicrmw.end
3122; X86-NEXT:    movzwl %ax, %eax
3123; X86-NEXT:    btl %ecx, %eax
3124; X86-NEXT:    jae .LBB49_3
3125; X86-NEXT:  # %bb.4: # %if.then
3126; X86-NEXT:    movzwl %cx, %eax
3127; X86-NEXT:    movzwl (%edx,%eax,2), %eax
3128; X86-NEXT:    jmp .LBB49_5
3129; X86-NEXT:  .LBB49_3:
3130; X86-NEXT:    movw $123, %ax
3131; X86-NEXT:  .LBB49_5: # %return
3132; X86-NEXT:    popl %esi
3133; X86-NEXT:    popl %edi
3134; X86-NEXT:    retl
3135;
3136; X64-LABEL: atomic_shl1_small_mask_and_16_gpr_brnz:
3137; X64:       # %bb.0: # %entry
3138; X64-NEXT:    movl %esi, %ecx
3139; X64-NEXT:    andl $7, %ecx
3140; X64-NEXT:    movw $-2, %dx
3141; X64-NEXT:    rolw %cl, %dx
3142; X64-NEXT:    movzwl (%rdi), %eax
3143; X64-NEXT:    .p2align 4
3144; X64-NEXT:  .LBB49_1: # %atomicrmw.start
3145; X64-NEXT:    # =>This Inner Loop Header: Depth=1
3146; X64-NEXT:    movl %eax, %esi
3147; X64-NEXT:    andl %edx, %esi
3148; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3149; X64-NEXT:    lock cmpxchgw %si, (%rdi)
3150; X64-NEXT:    # kill: def $ax killed $ax def $eax
3151; X64-NEXT:    jne .LBB49_1
3152; X64-NEXT:  # %bb.2: # %atomicrmw.end
3153; X64-NEXT:    movzwl %ax, %eax
3154; X64-NEXT:    btl %ecx, %eax
3155; X64-NEXT:    jae .LBB49_3
3156; X64-NEXT:  # %bb.4: # %if.then
3157; X64-NEXT:    movzwl %cx, %eax
3158; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
3159; X64-NEXT:    retq
3160; X64-NEXT:  .LBB49_3:
3161; X64-NEXT:    movw $123, %ax
3162; X64-NEXT:    retq
3163entry:
3164  %0 = and i16 %c, 7
3165  %shl = shl nuw nsw i16 1, %0
3166  %not = xor i16 %shl, -1
3167  %1 = atomicrmw and ptr %v, i16 %not monotonic, align 2
3168  %conv5 = zext i16 %1 to i32
3169  %conv6 = zext i16 %0 to i32
3170  %shl7 = shl nuw nsw i32 1, %conv6
3171  %and = and i32 %shl7, %conv5
3172  %tobool.not = icmp eq i32 %and, 0
3173  br i1 %tobool.not, label %return, label %if.then
3174
3175if.then:                                          ; preds = %entry
3176  %conv2 = zext i16 %0 to i64
3177  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %conv2
3178  %2 = load i16, ptr %arrayidx, align 2
3179  br label %return
3180
3181return:                                           ; preds = %entry, %if.then
3182  %retval.0 = phi i16 [ %2, %if.then ], [ 123, %entry ]
3183  ret i16 %retval.0
3184}
3185
3186define zeroext i16 @atomic_shl1_mask0_and_16_gpr_brnz(ptr %v, i16 zeroext %c) nounwind {
3187; X86-LABEL: atomic_shl1_mask0_and_16_gpr_brnz:
3188; X86:       # %bb.0: # %entry
3189; X86-NEXT:    pushl %edi
3190; X86-NEXT:    pushl %esi
3191; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
3192; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3193; X86-NEXT:    movw $-2, %si
3194; X86-NEXT:    rolw %cl, %si
3195; X86-NEXT:    movzwl (%edx), %eax
3196; X86-NEXT:    .p2align 4
3197; X86-NEXT:  .LBB50_1: # %atomicrmw.start
3198; X86-NEXT:    # =>This Inner Loop Header: Depth=1
3199; X86-NEXT:    movl %eax, %edi
3200; X86-NEXT:    andl %esi, %edi
3201; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3202; X86-NEXT:    lock cmpxchgw %di, (%edx)
3203; X86-NEXT:    # kill: def $ax killed $ax def $eax
3204; X86-NEXT:    jne .LBB50_1
3205; X86-NEXT:  # %bb.2: # %atomicrmw.end
3206; X86-NEXT:    movzwl %ax, %eax
3207; X86-NEXT:    btl %ecx, %eax
3208; X86-NEXT:    jae .LBB50_3
3209; X86-NEXT:  # %bb.4: # %if.then
3210; X86-NEXT:    movzwl %cx, %eax
3211; X86-NEXT:    movzwl (%edx,%eax,2), %eax
3212; X86-NEXT:    jmp .LBB50_5
3213; X86-NEXT:  .LBB50_3:
3214; X86-NEXT:    movw $123, %ax
3215; X86-NEXT:  .LBB50_5: # %return
3216; X86-NEXT:    popl %esi
3217; X86-NEXT:    popl %edi
3218; X86-NEXT:    retl
3219;
3220; X64-LABEL: atomic_shl1_mask0_and_16_gpr_brnz:
3221; X64:       # %bb.0: # %entry
3222; X64-NEXT:    movl %esi, %ecx
3223; X64-NEXT:    movw $-2, %dx
3224; X64-NEXT:    rolw %cl, %dx
3225; X64-NEXT:    movzwl (%rdi), %eax
3226; X64-NEXT:    .p2align 4
3227; X64-NEXT:  .LBB50_1: # %atomicrmw.start
3228; X64-NEXT:    # =>This Inner Loop Header: Depth=1
3229; X64-NEXT:    movl %eax, %esi
3230; X64-NEXT:    andl %edx, %esi
3231; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3232; X64-NEXT:    lock cmpxchgw %si, (%rdi)
3233; X64-NEXT:    # kill: def $ax killed $ax def $eax
3234; X64-NEXT:    jne .LBB50_1
3235; X64-NEXT:  # %bb.2: # %atomicrmw.end
3236; X64-NEXT:    movzwl %ax, %eax
3237; X64-NEXT:    btl %ecx, %eax
3238; X64-NEXT:    jae .LBB50_3
3239; X64-NEXT:  # %bb.4: # %if.then
3240; X64-NEXT:    movzwl %cx, %eax
3241; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
3242; X64-NEXT:    retq
3243; X64-NEXT:  .LBB50_3:
3244; X64-NEXT:    movw $123, %ax
3245; X64-NEXT:    retq
3246entry:
3247  %0 = and i16 %c, 15
3248  %shl = shl nuw i16 1, %0
3249  %not = xor i16 %shl, -1
3250  %1 = atomicrmw and ptr %v, i16 %not monotonic, align 2
3251  %conv2 = zext i16 %1 to i32
3252  %conv3 = zext i16 %c to i32
3253  %shl4 = shl nuw i32 1, %conv3
3254  %and = and i32 %shl4, %conv2
3255  %tobool.not = icmp eq i32 %and, 0
3256  br i1 %tobool.not, label %return, label %if.then
3257
3258if.then:                                          ; preds = %entry
3259  %conv = zext i16 %c to i64
3260  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %conv
3261  %2 = load i16, ptr %arrayidx, align 2
3262  br label %return
3263
3264return:                                           ; preds = %entry, %if.then
3265  %retval.0 = phi i16 [ %2, %if.then ], [ 123, %entry ]
3266  ret i16 %retval.0
3267}
3268
3269define zeroext i16 @atomic_shl1_mask1_and_16_gpr_brnz(ptr %v, i16 zeroext %c) nounwind {
3270; X86-LABEL: atomic_shl1_mask1_and_16_gpr_brnz:
3271; X86:       # %bb.0: # %entry
3272; X86-NEXT:    pushl %edi
3273; X86-NEXT:    pushl %esi
3274; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
3275; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3276; X86-NEXT:    movl $-2, %esi
3277; X86-NEXT:    roll %cl, %esi
3278; X86-NEXT:    movzwl (%edx), %eax
3279; X86-NEXT:    .p2align 4
3280; X86-NEXT:  .LBB51_1: # %atomicrmw.start
3281; X86-NEXT:    # =>This Inner Loop Header: Depth=1
3282; X86-NEXT:    movl %eax, %edi
3283; X86-NEXT:    andl %esi, %edi
3284; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3285; X86-NEXT:    lock cmpxchgw %di, (%edx)
3286; X86-NEXT:    # kill: def $ax killed $ax def $eax
3287; X86-NEXT:    jne .LBB51_1
3288; X86-NEXT:  # %bb.2: # %atomicrmw.end
3289; X86-NEXT:    movzwl %ax, %eax
3290; X86-NEXT:    movl %ecx, %esi
3291; X86-NEXT:    andl $15, %esi
3292; X86-NEXT:    btl %esi, %eax
3293; X86-NEXT:    jae .LBB51_3
3294; X86-NEXT:  # %bb.4: # %if.then
3295; X86-NEXT:    movzwl %cx, %eax
3296; X86-NEXT:    movzwl (%edx,%eax,2), %eax
3297; X86-NEXT:    jmp .LBB51_5
3298; X86-NEXT:  .LBB51_3:
3299; X86-NEXT:    movw $123, %ax
3300; X86-NEXT:  .LBB51_5: # %return
3301; X86-NEXT:    popl %esi
3302; X86-NEXT:    popl %edi
3303; X86-NEXT:    retl
3304;
3305; X64-LABEL: atomic_shl1_mask1_and_16_gpr_brnz:
3306; X64:       # %bb.0: # %entry
3307; X64-NEXT:    movl %esi, %ecx
3308; X64-NEXT:    movl $-2, %edx
3309; X64-NEXT:    roll %cl, %edx
3310; X64-NEXT:    movzwl (%rdi), %eax
3311; X64-NEXT:    .p2align 4
3312; X64-NEXT:  .LBB51_1: # %atomicrmw.start
3313; X64-NEXT:    # =>This Inner Loop Header: Depth=1
3314; X64-NEXT:    movl %eax, %esi
3315; X64-NEXT:    andl %edx, %esi
3316; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3317; X64-NEXT:    lock cmpxchgw %si, (%rdi)
3318; X64-NEXT:    # kill: def $ax killed $ax def $eax
3319; X64-NEXT:    jne .LBB51_1
3320; X64-NEXT:  # %bb.2: # %atomicrmw.end
3321; X64-NEXT:    movzwl %ax, %eax
3322; X64-NEXT:    movl %ecx, %edx
3323; X64-NEXT:    andl $15, %edx
3324; X64-NEXT:    btl %edx, %eax
3325; X64-NEXT:    jae .LBB51_3
3326; X64-NEXT:  # %bb.4: # %if.then
3327; X64-NEXT:    movzwl %cx, %eax
3328; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
3329; X64-NEXT:    retq
3330; X64-NEXT:  .LBB51_3:
3331; X64-NEXT:    movw $123, %ax
3332; X64-NEXT:    retq
3333entry:
3334  %conv = zext i16 %c to i32
3335  %shl = shl nuw i32 1, %conv
3336  %0 = trunc i32 %shl to i16
3337  %conv1 = xor i16 %0, -1
3338  %1 = atomicrmw and ptr %v, i16 %conv1 monotonic, align 2
3339  %conv2 = zext i16 %1 to i32
3340  %2 = and i16 %c, 15
3341  %sh_prom = zext i16 %2 to i32
3342  %shl4 = shl nuw nsw i32 1, %sh_prom
3343  %and = and i32 %shl4, %conv2
3344  %tobool.not = icmp eq i32 %and, 0
3345  br i1 %tobool.not, label %return, label %if.then
3346
3347if.then:                                          ; preds = %entry
3348  %conv3 = zext i16 %c to i64
3349  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %conv3
3350  %3 = load i16, ptr %arrayidx, align 2
3351  br label %return
3352
3353return:                                           ; preds = %entry, %if.then
3354  %retval.0 = phi i16 [ %3, %if.then ], [ 123, %entry ]
3355  ret i16 %retval.0
3356}
3357
3358define zeroext i16 @atomic_shl1_mask01_and_16_gpr_brnz(ptr %v, i16 zeroext %c) nounwind {
3359; X86-LABEL: atomic_shl1_mask01_and_16_gpr_brnz:
3360; X86:       # %bb.0: # %entry
3361; X86-NEXT:    pushl %ebx
3362; X86-NEXT:    pushl %edi
3363; X86-NEXT:    pushl %esi
3364; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ebx
3365; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3366; X86-NEXT:    movl %ebx, %ecx
3367; X86-NEXT:    andb $15, %cl
3368; X86-NEXT:    movl $1, %esi
3369; X86-NEXT:    shll %cl, %esi
3370; X86-NEXT:    movl $-2, %edi
3371; X86-NEXT:    roll %cl, %edi
3372; X86-NEXT:    movzwl (%edx), %eax
3373; X86-NEXT:    .p2align 4
3374; X86-NEXT:  .LBB52_1: # %atomicrmw.start
3375; X86-NEXT:    # =>This Inner Loop Header: Depth=1
3376; X86-NEXT:    movl %eax, %ecx
3377; X86-NEXT:    andl %edi, %ecx
3378; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3379; X86-NEXT:    lock cmpxchgw %cx, (%edx)
3380; X86-NEXT:    # kill: def $ax killed $ax def $eax
3381; X86-NEXT:    jne .LBB52_1
3382; X86-NEXT:  # %bb.2: # %atomicrmw.end
3383; X86-NEXT:    movzwl %ax, %eax
3384; X86-NEXT:    testl %eax, %esi
3385; X86-NEXT:    je .LBB52_3
3386; X86-NEXT:  # %bb.4: # %if.then
3387; X86-NEXT:    movzwl %bx, %eax
3388; X86-NEXT:    movzwl (%edx,%eax,2), %eax
3389; X86-NEXT:    jmp .LBB52_5
3390; X86-NEXT:  .LBB52_3:
3391; X86-NEXT:    movw $123, %ax
3392; X86-NEXT:  .LBB52_5: # %return
3393; X86-NEXT:    popl %esi
3394; X86-NEXT:    popl %edi
3395; X86-NEXT:    popl %ebx
3396; X86-NEXT:    retl
3397;
3398; X64-LABEL: atomic_shl1_mask01_and_16_gpr_brnz:
3399; X64:       # %bb.0: # %entry
3400; X64-NEXT:    movl %esi, %ecx
3401; X64-NEXT:    andb $15, %cl
3402; X64-NEXT:    movl $1, %edx
3403; X64-NEXT:    shll %cl, %edx
3404; X64-NEXT:    movl $-2, %r8d
3405; X64-NEXT:    roll %cl, %r8d
3406; X64-NEXT:    movzwl (%rdi), %eax
3407; X64-NEXT:    .p2align 4
3408; X64-NEXT:  .LBB52_1: # %atomicrmw.start
3409; X64-NEXT:    # =>This Inner Loop Header: Depth=1
3410; X64-NEXT:    movl %eax, %ecx
3411; X64-NEXT:    andl %r8d, %ecx
3412; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3413; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
3414; X64-NEXT:    # kill: def $ax killed $ax def $eax
3415; X64-NEXT:    jne .LBB52_1
3416; X64-NEXT:  # %bb.2: # %atomicrmw.end
3417; X64-NEXT:    movzwl %ax, %eax
3418; X64-NEXT:    testl %eax, %edx
3419; X64-NEXT:    je .LBB52_3
3420; X64-NEXT:  # %bb.4: # %if.then
3421; X64-NEXT:    movzwl %si, %eax
3422; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
3423; X64-NEXT:    retq
3424; X64-NEXT:  .LBB52_3:
3425; X64-NEXT:    movw $123, %ax
3426; X64-NEXT:    retq
3427entry:
3428  %0 = and i16 %c, 15
3429  %sh_prom = zext i16 %0 to i32
3430  %shl = shl nuw nsw i32 1, %sh_prom
3431  %1 = trunc i32 %shl to i16
3432  %conv1 = xor i16 %1, -1
3433  %2 = atomicrmw and ptr %v, i16 %conv1 monotonic, align 2
3434  %conv2 = zext i16 %2 to i32
3435  %and = and i32 %shl, %conv2
3436  %tobool.not = icmp eq i32 %and, 0
3437  br i1 %tobool.not, label %return, label %if.then
3438
3439if.then:                                          ; preds = %entry
3440  %conv = zext i16 %c to i64
3441  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %conv
3442  %3 = load i16, ptr %arrayidx, align 2
3443  br label %return
3444
3445return:                                           ; preds = %entry, %if.then
3446  %retval.0 = phi i16 [ %3, %if.then ], [ 123, %entry ]
3447  ret i16 %retval.0
3448}
3449
3450define zeroext i16 @atomic_blsi_and_16_gpr_brnz(ptr %v, i16 zeroext %c) nounwind {
3451; X86-LABEL: atomic_blsi_and_16_gpr_brnz:
3452; X86:       # %bb.0: # %entry
3453; X86-NEXT:    pushl %ebx
3454; X86-NEXT:    pushl %edi
3455; X86-NEXT:    pushl %esi
3456; X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
3457; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3458; X86-NEXT:    movl %ecx, %esi
3459; X86-NEXT:    negl %esi
3460; X86-NEXT:    andl %ecx, %esi
3461; X86-NEXT:    movl %esi, %edi
3462; X86-NEXT:    notl %edi
3463; X86-NEXT:    movzwl (%edx), %eax
3464; X86-NEXT:    .p2align 4
3465; X86-NEXT:  .LBB53_1: # %atomicrmw.start
3466; X86-NEXT:    # =>This Inner Loop Header: Depth=1
3467; X86-NEXT:    movl %eax, %ebx
3468; X86-NEXT:    andl %edi, %ebx
3469; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3470; X86-NEXT:    lock cmpxchgw %bx, (%edx)
3471; X86-NEXT:    # kill: def $ax killed $ax def $eax
3472; X86-NEXT:    jne .LBB53_1
3473; X86-NEXT:  # %bb.2: # %atomicrmw.end
3474; X86-NEXT:    movzwl %ax, %eax
3475; X86-NEXT:    testl %eax, %esi
3476; X86-NEXT:    je .LBB53_3
3477; X86-NEXT:  # %bb.4: # %if.then
3478; X86-NEXT:    movzwl %cx, %eax
3479; X86-NEXT:    movzwl (%edx,%eax,2), %eax
3480; X86-NEXT:    jmp .LBB53_5
3481; X86-NEXT:  .LBB53_3:
3482; X86-NEXT:    movw $123, %ax
3483; X86-NEXT:  .LBB53_5: # %return
3484; X86-NEXT:    popl %esi
3485; X86-NEXT:    popl %edi
3486; X86-NEXT:    popl %ebx
3487; X86-NEXT:    retl
3488;
3489; X64-LABEL: atomic_blsi_and_16_gpr_brnz:
3490; X64:       # %bb.0: # %entry
3491; X64-NEXT:    movl %esi, %ecx
3492; X64-NEXT:    negl %ecx
3493; X64-NEXT:    andl %esi, %ecx
3494; X64-NEXT:    movl %ecx, %edx
3495; X64-NEXT:    notl %edx
3496; X64-NEXT:    movzwl (%rdi), %eax
3497; X64-NEXT:    .p2align 4
3498; X64-NEXT:  .LBB53_1: # %atomicrmw.start
3499; X64-NEXT:    # =>This Inner Loop Header: Depth=1
3500; X64-NEXT:    movl %eax, %r8d
3501; X64-NEXT:    andl %edx, %r8d
3502; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3503; X64-NEXT:    lock cmpxchgw %r8w, (%rdi)
3504; X64-NEXT:    # kill: def $ax killed $ax def $eax
3505; X64-NEXT:    jne .LBB53_1
3506; X64-NEXT:  # %bb.2: # %atomicrmw.end
3507; X64-NEXT:    movzwl %ax, %eax
3508; X64-NEXT:    testl %eax, %ecx
3509; X64-NEXT:    je .LBB53_3
3510; X64-NEXT:  # %bb.4: # %if.then
3511; X64-NEXT:    movzwl %si, %eax
3512; X64-NEXT:    movzwl (%rdi,%rax,2), %eax
3513; X64-NEXT:    retq
3514; X64-NEXT:  .LBB53_3:
3515; X64-NEXT:    movw $123, %ax
3516; X64-NEXT:    retq
3517entry:
3518  %conv = zext i16 %c to i32
3519  %sub = sub nsw i32 0, %conv
3520  %and = and i32 %conv, %sub
3521  %0 = trunc i32 %and to i16
3522  %conv2 = xor i16 %0, -1
3523  %1 = atomicrmw and ptr %v, i16 %conv2 monotonic, align 2
3524  %conv3 = zext i16 %1 to i32
3525  %and8 = and i32 %and, %conv3
3526  %tobool.not = icmp eq i32 %and8, 0
3527  br i1 %tobool.not, label %return, label %if.then
3528
3529if.then:                                          ; preds = %entry
3530  %idxprom = zext i16 %c to i64
3531  %arrayidx = getelementptr inbounds i16, ptr %v, i64 %idxprom
3532  %2 = load i16, ptr %arrayidx, align 2
3533  br label %return
3534
3535return:                                           ; preds = %entry, %if.then
3536  %retval.0 = phi i16 [ %2, %if.then ], [ 123, %entry ]
3537  ret i16 %retval.0
3538}
3539
3540define zeroext i16 @atomic_shl1_or_16_const_val(ptr %v) nounwind {
3541; X86-LABEL: atomic_shl1_or_16_const_val:
3542; X86:       # %bb.0: # %entry
3543; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3544; X86-NEXT:    xorl %eax, %eax
3545; X86-NEXT:    lock btsw $4, (%ecx)
3546; X86-NEXT:    setb %al
3547; X86-NEXT:    shll $4, %eax
3548; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3549; X86-NEXT:    retl
3550;
3551; X64-LABEL: atomic_shl1_or_16_const_val:
3552; X64:       # %bb.0: # %entry
3553; X64-NEXT:    xorl %eax, %eax
3554; X64-NEXT:    lock btsw $4, (%rdi)
3555; X64-NEXT:    setb %al
3556; X64-NEXT:    shll $4, %eax
3557; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3558; X64-NEXT:    retq
3559entry:
3560  %0 = atomicrmw or ptr %v, i16 16 monotonic, align 2
3561  %1 = and i16 16, %0
3562  ret i16 %1
3563}
3564
3565define zeroext i16 @atomic_shl1_or_16_const_valnz(ptr %v) nounwind {
3566; X86-LABEL: atomic_shl1_or_16_const_valnz:
3567; X86:       # %bb.0: # %entry
3568; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3569; X86-NEXT:    movzwl (%ecx), %eax
3570; X86-NEXT:    .p2align 4
3571; X86-NEXT:  .LBB55_1: # %atomicrmw.start
3572; X86-NEXT:    # =>This Inner Loop Header: Depth=1
3573; X86-NEXT:    movl %eax, %edx
3574; X86-NEXT:    orl $16, %edx
3575; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3576; X86-NEXT:    lock cmpxchgw %dx, (%ecx)
3577; X86-NEXT:    # kill: def $ax killed $ax def $eax
3578; X86-NEXT:    jne .LBB55_1
3579; X86-NEXT:  # %bb.2: # %atomicrmw.end
3580; X86-NEXT:    shrl $4, %eax
3581; X86-NEXT:    andl $1, %eax
3582; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3583; X86-NEXT:    retl
3584;
3585; X64-LABEL: atomic_shl1_or_16_const_valnz:
3586; X64:       # %bb.0: # %entry
3587; X64-NEXT:    movzwl (%rdi), %eax
3588; X64-NEXT:    .p2align 4
3589; X64-NEXT:  .LBB55_1: # %atomicrmw.start
3590; X64-NEXT:    # =>This Inner Loop Header: Depth=1
3591; X64-NEXT:    movl %eax, %ecx
3592; X64-NEXT:    orl $16, %ecx
3593; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3594; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
3595; X64-NEXT:    # kill: def $ax killed $ax def $eax
3596; X64-NEXT:    jne .LBB55_1
3597; X64-NEXT:  # %bb.2: # %atomicrmw.end
3598; X64-NEXT:    shrl $4, %eax
3599; X64-NEXT:    andl $1, %eax
3600; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3601; X64-NEXT:    retq
3602entry:
3603  %0 = atomicrmw or ptr %v, i16 16 monotonic, align 2
3604  %1 = lshr i16 %0, 4
3605  %.lobit = and i16 %1, 1
3606  ret i16 %.lobit
3607}
3608
3609define zeroext i16 @atomic_shl1_or_16_const_brnz(ptr %v) nounwind {
3610; X86-LABEL: atomic_shl1_or_16_const_brnz:
3611; X86:       # %bb.0: # %entry
3612; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
3613; X86-NEXT:    lock btsw $4, (%eax)
3614; X86-NEXT:    jae .LBB56_1
3615; X86-NEXT:  # %bb.2: # %if.then
3616; X86-NEXT:    movzwl 8(%eax), %eax
3617; X86-NEXT:    retl
3618; X86-NEXT:  .LBB56_1:
3619; X86-NEXT:    movw $123, %ax
3620; X86-NEXT:    retl
3621;
3622; X64-LABEL: atomic_shl1_or_16_const_brnz:
3623; X64:       # %bb.0: # %entry
3624; X64-NEXT:    lock btsw $4, (%rdi)
3625; X64-NEXT:    jae .LBB56_1
3626; X64-NEXT:  # %bb.2: # %if.then
3627; X64-NEXT:    movzwl 8(%rdi), %eax
3628; X64-NEXT:    retq
3629; X64-NEXT:  .LBB56_1:
3630; X64-NEXT:    movw $123, %ax
3631; X64-NEXT:    retq
3632entry:
3633  %0 = atomicrmw or ptr %v, i16 16 monotonic, align 2
3634  %1 = and i16 %0, 16
3635  %tobool.not = icmp eq i16 %1, 0
3636  br i1 %tobool.not, label %return, label %if.then
3637
3638if.then:                                          ; preds = %entry
3639  %arrayidx = getelementptr inbounds i16, ptr %v, i64 4
3640  %2 = load i16, ptr %arrayidx, align 2
3641  br label %return
3642
3643return:                                           ; preds = %entry, %if.then
3644  %retval.0 = phi i16 [ %2, %if.then ], [ 123, %entry ]
3645  ret i16 %retval.0
3646}
3647
3648define zeroext i16 @atomic_shl1_and_16_const_val(ptr %v) nounwind {
3649; X86-LABEL: atomic_shl1_and_16_const_val:
3650; X86:       # %bb.0: # %entry
3651; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3652; X86-NEXT:    xorl %eax, %eax
3653; X86-NEXT:    lock btrw $4, (%ecx)
3654; X86-NEXT:    setb %al
3655; X86-NEXT:    shll $4, %eax
3656; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3657; X86-NEXT:    retl
3658;
3659; X64-LABEL: atomic_shl1_and_16_const_val:
3660; X64:       # %bb.0: # %entry
3661; X64-NEXT:    xorl %eax, %eax
3662; X64-NEXT:    lock btrw $4, (%rdi)
3663; X64-NEXT:    setb %al
3664; X64-NEXT:    shll $4, %eax
3665; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3666; X64-NEXT:    retq
3667entry:
3668  %0 = atomicrmw and ptr %v, i16 -17 monotonic, align 2
3669  %1 = and i16 %0, 16
3670  ret i16 %1
3671}
3672
3673define zeroext i16 @atomic_shl1_and_16_const_valz(ptr %v) nounwind {
3674; X86-LABEL: atomic_shl1_and_16_const_valz:
3675; X86:       # %bb.0: # %entry
3676; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3677; X86-NEXT:    movzwl (%ecx), %eax
3678; X86-NEXT:    .p2align 4
3679; X86-NEXT:  .LBB58_1: # %atomicrmw.start
3680; X86-NEXT:    # =>This Inner Loop Header: Depth=1
3681; X86-NEXT:    movl %eax, %edx
3682; X86-NEXT:    andl $65519, %edx # imm = 0xFFEF
3683; X86-NEXT:    # kill: def $ax killed $ax killed $eax
3684; X86-NEXT:    lock cmpxchgw %dx, (%ecx)
3685; X86-NEXT:    # kill: def $ax killed $ax def $eax
3686; X86-NEXT:    jne .LBB58_1
3687; X86-NEXT:  # %bb.2: # %atomicrmw.end
3688; X86-NEXT:    xorl %ecx, %ecx
3689; X86-NEXT:    testb $16, %al
3690; X86-NEXT:    sete %cl
3691; X86-NEXT:    movl %ecx, %eax
3692; X86-NEXT:    retl
3693;
3694; X64-LABEL: atomic_shl1_and_16_const_valz:
3695; X64:       # %bb.0: # %entry
3696; X64-NEXT:    movzwl (%rdi), %eax
3697; X64-NEXT:    .p2align 4
3698; X64-NEXT:  .LBB58_1: # %atomicrmw.start
3699; X64-NEXT:    # =>This Inner Loop Header: Depth=1
3700; X64-NEXT:    movl %eax, %ecx
3701; X64-NEXT:    andl $65519, %ecx # imm = 0xFFEF
3702; X64-NEXT:    # kill: def $ax killed $ax killed $eax
3703; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
3704; X64-NEXT:    # kill: def $ax killed $ax def $eax
3705; X64-NEXT:    jne .LBB58_1
3706; X64-NEXT:  # %bb.2: # %atomicrmw.end
3707; X64-NEXT:    xorl %ecx, %ecx
3708; X64-NEXT:    testb $16, %al
3709; X64-NEXT:    sete %cl
3710; X64-NEXT:    movl %ecx, %eax
3711; X64-NEXT:    retq
3712entry:
3713  %0 = atomicrmw and ptr %v, i16 -17 monotonic, align 2
3714  %1 = lshr i16 %0, 4
3715  %.lobit = and i16 %1, 1
3716  %conv1 = xor i16 %.lobit, 1
3717  ret i16 %conv1
3718}
3719
3720define zeroext i16 @atomic_shl1_and_16_const_brz(ptr %v) nounwind {
3721; X86-LABEL: atomic_shl1_and_16_const_brz:
3722; X86:       # %bb.0: # %entry
3723; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3724; X86-NEXT:    lock btrw $4, (%ecx)
3725; X86-NEXT:    movw $123, %ax
3726; X86-NEXT:    jae .LBB59_1
3727; X86-NEXT:  # %bb.2: # %return
3728; X86-NEXT:    retl
3729; X86-NEXT:  .LBB59_1: # %if.then
3730; X86-NEXT:    movzwl 8(%ecx), %eax
3731; X86-NEXT:    retl
3732;
3733; X64-LABEL: atomic_shl1_and_16_const_brz:
3734; X64:       # %bb.0: # %entry
3735; X64-NEXT:    lock btrw $4, (%rdi)
3736; X64-NEXT:    movw $123, %ax
3737; X64-NEXT:    jae .LBB59_1
3738; X64-NEXT:  # %bb.2: # %return
3739; X64-NEXT:    retq
3740; X64-NEXT:  .LBB59_1: # %if.then
3741; X64-NEXT:    movzwl 8(%rdi), %eax
3742; X64-NEXT:    retq
3743entry:
3744  %0 = atomicrmw and ptr %v, i16 -17 monotonic, align 2
3745  %1 = and i16 %0, 16
3746  %tobool.not = icmp eq i16 %1, 0
3747  br i1 %tobool.not, label %if.then, label %return
3748
3749if.then:                                          ; preds = %entry
3750  %arrayidx = getelementptr inbounds i16, ptr %v, i64 4
3751  %2 = load i16, ptr %arrayidx, align 2
3752  br label %return
3753
3754return:                                           ; preds = %entry, %if.then
3755  %retval.0 = phi i16 [ %2, %if.then ], [ 123, %entry ]
3756  ret i16 %retval.0
3757}
3758
3759define i32 @atomic_shl1_or_32_gpr_val(ptr %v, i32 %c) nounwind {
3760; X86-LABEL: atomic_shl1_or_32_gpr_val:
3761; X86:       # %bb.0: # %entry
3762; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3763; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3764; X86-NEXT:    andl $31, %ecx
3765; X86-NEXT:    xorl %eax, %eax
3766; X86-NEXT:    lock btsl %ecx, (%edx)
3767; X86-NEXT:    setb %al
3768; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
3769; X86-NEXT:    shll %cl, %eax
3770; X86-NEXT:    retl
3771;
3772; X64-LABEL: atomic_shl1_or_32_gpr_val:
3773; X64:       # %bb.0: # %entry
3774; X64-NEXT:    movl %esi, %ecx
3775; X64-NEXT:    andl $31, %ecx
3776; X64-NEXT:    xorl %eax, %eax
3777; X64-NEXT:    lock btsl %ecx, (%rdi)
3778; X64-NEXT:    setb %al
3779; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
3780; X64-NEXT:    shll %cl, %eax
3781; X64-NEXT:    retq
3782entry:
3783  %shl = shl nuw i32 1, %c
3784  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
3785  %and = and i32 %shl, %0
3786  ret i32 %and
3787}
3788
3789define i32 @atomic_shl1_small_mask_or_32_gpr_val(ptr %v, i32 %c) nounwind {
3790; X86-LABEL: atomic_shl1_small_mask_or_32_gpr_val:
3791; X86:       # %bb.0: # %entry
3792; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3793; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3794; X86-NEXT:    andl $15, %ecx
3795; X86-NEXT:    xorl %eax, %eax
3796; X86-NEXT:    lock btsl %ecx, (%edx)
3797; X86-NEXT:    setb %al
3798; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
3799; X86-NEXT:    shll %cl, %eax
3800; X86-NEXT:    retl
3801;
3802; X64-LABEL: atomic_shl1_small_mask_or_32_gpr_val:
3803; X64:       # %bb.0: # %entry
3804; X64-NEXT:    movl %esi, %ecx
3805; X64-NEXT:    andl $15, %ecx
3806; X64-NEXT:    xorl %eax, %eax
3807; X64-NEXT:    lock btsl %ecx, (%rdi)
3808; X64-NEXT:    setb %al
3809; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
3810; X64-NEXT:    shll %cl, %eax
3811; X64-NEXT:    retq
3812entry:
3813  %0 = and i32 %c, 15
3814  %shl = shl nuw nsw i32 1, %0
3815  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
3816  %and = and i32 %1, %shl
3817  ret i32 %and
3818}
3819
3820define i32 @atomic_shl1_mask0_or_32_gpr_val(ptr %v, i32 %c) nounwind {
3821; X86-LABEL: atomic_shl1_mask0_or_32_gpr_val:
3822; X86:       # %bb.0: # %entry
3823; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3824; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3825; X86-NEXT:    andl $31, %ecx
3826; X86-NEXT:    xorl %eax, %eax
3827; X86-NEXT:    lock btsl %ecx, (%edx)
3828; X86-NEXT:    setb %al
3829; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
3830; X86-NEXT:    shll %cl, %eax
3831; X86-NEXT:    retl
3832;
3833; X64-LABEL: atomic_shl1_mask0_or_32_gpr_val:
3834; X64:       # %bb.0: # %entry
3835; X64-NEXT:    movl %esi, %ecx
3836; X64-NEXT:    andl $31, %ecx
3837; X64-NEXT:    xorl %eax, %eax
3838; X64-NEXT:    lock btsl %ecx, (%rdi)
3839; X64-NEXT:    setb %al
3840; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
3841; X64-NEXT:    shll %cl, %eax
3842; X64-NEXT:    retq
3843entry:
3844  %0 = and i32 %c, 31
3845  %shl = shl nuw i32 1, %0
3846  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
3847  %shl1 = shl nuw i32 1, %c
3848  %and = and i32 %1, %shl1
3849  ret i32 %and
3850}
3851
3852define i32 @atomic_shl1_mask1_or_32_gpr_val(ptr %v, i32 %c) nounwind {
3853; X86-LABEL: atomic_shl1_mask1_or_32_gpr_val:
3854; X86:       # %bb.0: # %entry
3855; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3856; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3857; X86-NEXT:    andl $31, %ecx
3858; X86-NEXT:    xorl %eax, %eax
3859; X86-NEXT:    lock btsl %ecx, (%edx)
3860; X86-NEXT:    setb %al
3861; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
3862; X86-NEXT:    shll %cl, %eax
3863; X86-NEXT:    retl
3864;
3865; X64-LABEL: atomic_shl1_mask1_or_32_gpr_val:
3866; X64:       # %bb.0: # %entry
3867; X64-NEXT:    movl %esi, %ecx
3868; X64-NEXT:    andl $31, %ecx
3869; X64-NEXT:    xorl %eax, %eax
3870; X64-NEXT:    lock btsl %ecx, (%rdi)
3871; X64-NEXT:    setb %al
3872; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
3873; X64-NEXT:    shll %cl, %eax
3874; X64-NEXT:    retq
3875entry:
3876  %shl = shl nuw i32 1, %c
3877  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
3878  %1 = and i32 %c, 31
3879  %shl1 = shl nuw i32 1, %1
3880  %and = and i32 %shl1, %0
3881  ret i32 %and
3882}
3883
3884define i32 @atomic_shl1_mask01_or_32_gpr_val(ptr %v, i32 %c) nounwind {
3885; X86-LABEL: atomic_shl1_mask01_or_32_gpr_val:
3886; X86:       # %bb.0: # %entry
3887; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3888; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3889; X86-NEXT:    andl $31, %ecx
3890; X86-NEXT:    xorl %eax, %eax
3891; X86-NEXT:    lock btsl %ecx, (%edx)
3892; X86-NEXT:    setb %al
3893; X86-NEXT:    # kill: def $cl killed $cl killed $ecx
3894; X86-NEXT:    shll %cl, %eax
3895; X86-NEXT:    retl
3896;
3897; X64-LABEL: atomic_shl1_mask01_or_32_gpr_val:
3898; X64:       # %bb.0: # %entry
3899; X64-NEXT:    movl %esi, %ecx
3900; X64-NEXT:    andl $31, %ecx
3901; X64-NEXT:    xorl %eax, %eax
3902; X64-NEXT:    lock btsl %ecx, (%rdi)
3903; X64-NEXT:    setb %al
3904; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
3905; X64-NEXT:    shll %cl, %eax
3906; X64-NEXT:    retq
3907entry:
3908  %0 = and i32 %c, 31
3909  %shl = shl nuw i32 1, %0
3910  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
3911  %and = and i32 %1, %shl
3912  ret i32 %and
3913}
3914
3915define i32 @atomic_blsi_or_32_gpr_val(ptr %v, i32 %c) nounwind {
3916; X86-LABEL: atomic_blsi_or_32_gpr_val:
3917; X86:       # %bb.0: # %entry
3918; X86-NEXT:    pushl %esi
3919; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3920; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
3921; X86-NEXT:    movl %eax, %ecx
3922; X86-NEXT:    negl %ecx
3923; X86-NEXT:    andl %eax, %ecx
3924; X86-NEXT:    movl (%edx), %eax
3925; X86-NEXT:    .p2align 4
3926; X86-NEXT:  .LBB65_1: # %atomicrmw.start
3927; X86-NEXT:    # =>This Inner Loop Header: Depth=1
3928; X86-NEXT:    movl %eax, %esi
3929; X86-NEXT:    orl %ecx, %esi
3930; X86-NEXT:    lock cmpxchgl %esi, (%edx)
3931; X86-NEXT:    jne .LBB65_1
3932; X86-NEXT:  # %bb.2: # %atomicrmw.end
3933; X86-NEXT:    andl %ecx, %eax
3934; X86-NEXT:    popl %esi
3935; X86-NEXT:    retl
3936;
3937; X64-LABEL: atomic_blsi_or_32_gpr_val:
3938; X64:       # %bb.0: # %entry
3939; X64-NEXT:    movl %esi, %ecx
3940; X64-NEXT:    negl %ecx
3941; X64-NEXT:    andl %esi, %ecx
3942; X64-NEXT:    movl (%rdi), %eax
3943; X64-NEXT:    .p2align 4
3944; X64-NEXT:  .LBB65_1: # %atomicrmw.start
3945; X64-NEXT:    # =>This Inner Loop Header: Depth=1
3946; X64-NEXT:    movl %eax, %edx
3947; X64-NEXT:    orl %ecx, %edx
3948; X64-NEXT:    lock cmpxchgl %edx, (%rdi)
3949; X64-NEXT:    jne .LBB65_1
3950; X64-NEXT:  # %bb.2: # %atomicrmw.end
3951; X64-NEXT:    andl %ecx, %eax
3952; X64-NEXT:    retq
3953entry:
3954  %sub = sub i32 0, %c
3955  %and = and i32 %sub, %c
3956  %0 = atomicrmw or ptr %v, i32 %and monotonic, align 4
3957  %and3 = and i32 %0, %and
3958  ret i32 %and3
3959}
3960
3961define i32 @atomic_shl1_or_32_gpr_valz(ptr %v, i32 %c) nounwind {
3962; X86-LABEL: atomic_shl1_or_32_gpr_valz:
3963; X86:       # %bb.0: # %entry
3964; X86-NEXT:    pushl %edi
3965; X86-NEXT:    pushl %esi
3966; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
3967; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
3968; X86-NEXT:    movl $1, %esi
3969; X86-NEXT:    shll %cl, %esi
3970; X86-NEXT:    movl (%edx), %eax
3971; X86-NEXT:    .p2align 4
3972; X86-NEXT:  .LBB66_1: # %atomicrmw.start
3973; X86-NEXT:    # =>This Inner Loop Header: Depth=1
3974; X86-NEXT:    movl %eax, %edi
3975; X86-NEXT:    orl %esi, %edi
3976; X86-NEXT:    lock cmpxchgl %edi, (%edx)
3977; X86-NEXT:    jne .LBB66_1
3978; X86-NEXT:  # %bb.2: # %atomicrmw.end
3979; X86-NEXT:    xorl %edx, %edx
3980; X86-NEXT:    btl %ecx, %eax
3981; X86-NEXT:    setae %dl
3982; X86-NEXT:    movl %edx, %eax
3983; X86-NEXT:    popl %esi
3984; X86-NEXT:    popl %edi
3985; X86-NEXT:    retl
3986;
3987; X64-LABEL: atomic_shl1_or_32_gpr_valz:
3988; X64:       # %bb.0: # %entry
3989; X64-NEXT:    movl %esi, %ecx
3990; X64-NEXT:    movl $1, %edx
3991; X64-NEXT:    shll %cl, %edx
3992; X64-NEXT:    movl (%rdi), %eax
3993; X64-NEXT:    .p2align 4
3994; X64-NEXT:  .LBB66_1: # %atomicrmw.start
3995; X64-NEXT:    # =>This Inner Loop Header: Depth=1
3996; X64-NEXT:    movl %eax, %esi
3997; X64-NEXT:    orl %edx, %esi
3998; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
3999; X64-NEXT:    jne .LBB66_1
4000; X64-NEXT:  # %bb.2: # %atomicrmw.end
4001; X64-NEXT:    xorl %edx, %edx
4002; X64-NEXT:    btl %ecx, %eax
4003; X64-NEXT:    setae %dl
4004; X64-NEXT:    movl %edx, %eax
4005; X64-NEXT:    retq
4006entry:
4007  %shl = shl nuw i32 1, %c
4008  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4009  %1 = xor i32 %0, -1
4010  %2 = lshr i32 %1, %c
4011  %lnot.ext = and i32 %2, 1
4012  ret i32 %lnot.ext
4013}
4014
4015define i32 @atomic_shl1_small_mask_or_32_gpr_valz(ptr %v, i32 %c) nounwind {
4016; X86-LABEL: atomic_shl1_small_mask_or_32_gpr_valz:
4017; X86:       # %bb.0: # %entry
4018; X86-NEXT:    pushl %edi
4019; X86-NEXT:    pushl %esi
4020; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4021; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4022; X86-NEXT:    andl $15, %ecx
4023; X86-NEXT:    movl $1, %esi
4024; X86-NEXT:    shll %cl, %esi
4025; X86-NEXT:    movl (%edx), %eax
4026; X86-NEXT:    .p2align 4
4027; X86-NEXT:  .LBB67_1: # %atomicrmw.start
4028; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4029; X86-NEXT:    movl %eax, %edi
4030; X86-NEXT:    orl %esi, %edi
4031; X86-NEXT:    lock cmpxchgl %edi, (%edx)
4032; X86-NEXT:    jne .LBB67_1
4033; X86-NEXT:  # %bb.2: # %atomicrmw.end
4034; X86-NEXT:    xorl %edx, %edx
4035; X86-NEXT:    btl %ecx, %eax
4036; X86-NEXT:    setae %dl
4037; X86-NEXT:    movl %edx, %eax
4038; X86-NEXT:    popl %esi
4039; X86-NEXT:    popl %edi
4040; X86-NEXT:    retl
4041;
4042; X64-LABEL: atomic_shl1_small_mask_or_32_gpr_valz:
4043; X64:       # %bb.0: # %entry
4044; X64-NEXT:    movl %esi, %ecx
4045; X64-NEXT:    andl $15, %ecx
4046; X64-NEXT:    movl $1, %edx
4047; X64-NEXT:    shll %cl, %edx
4048; X64-NEXT:    movl (%rdi), %eax
4049; X64-NEXT:    .p2align 4
4050; X64-NEXT:  .LBB67_1: # %atomicrmw.start
4051; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4052; X64-NEXT:    movl %eax, %esi
4053; X64-NEXT:    orl %edx, %esi
4054; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
4055; X64-NEXT:    jne .LBB67_1
4056; X64-NEXT:  # %bb.2: # %atomicrmw.end
4057; X64-NEXT:    xorl %edx, %edx
4058; X64-NEXT:    btl %ecx, %eax
4059; X64-NEXT:    setae %dl
4060; X64-NEXT:    movl %edx, %eax
4061; X64-NEXT:    retq
4062entry:
4063  %0 = and i32 %c, 15
4064  %shl = shl nuw nsw i32 1, %0
4065  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4066  %2 = xor i32 %1, -1
4067  %3 = lshr i32 %2, %0
4068  %lnot.ext = and i32 %3, 1
4069  ret i32 %lnot.ext
4070}
4071
4072define i32 @atomic_shl1_mask0_or_32_gpr_valz(ptr %v, i32 %c) nounwind {
4073; X86-LABEL: atomic_shl1_mask0_or_32_gpr_valz:
4074; X86:       # %bb.0: # %entry
4075; X86-NEXT:    pushl %edi
4076; X86-NEXT:    pushl %esi
4077; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4078; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4079; X86-NEXT:    movl $1, %esi
4080; X86-NEXT:    shll %cl, %esi
4081; X86-NEXT:    movl (%edx), %eax
4082; X86-NEXT:    .p2align 4
4083; X86-NEXT:  .LBB68_1: # %atomicrmw.start
4084; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4085; X86-NEXT:    movl %eax, %edi
4086; X86-NEXT:    orl %esi, %edi
4087; X86-NEXT:    lock cmpxchgl %edi, (%edx)
4088; X86-NEXT:    jne .LBB68_1
4089; X86-NEXT:  # %bb.2: # %atomicrmw.end
4090; X86-NEXT:    xorl %edx, %edx
4091; X86-NEXT:    btl %ecx, %eax
4092; X86-NEXT:    setae %dl
4093; X86-NEXT:    movl %edx, %eax
4094; X86-NEXT:    popl %esi
4095; X86-NEXT:    popl %edi
4096; X86-NEXT:    retl
4097;
4098; X64-LABEL: atomic_shl1_mask0_or_32_gpr_valz:
4099; X64:       # %bb.0: # %entry
4100; X64-NEXT:    movl %esi, %ecx
4101; X64-NEXT:    movl $1, %edx
4102; X64-NEXT:    shll %cl, %edx
4103; X64-NEXT:    movl (%rdi), %eax
4104; X64-NEXT:    .p2align 4
4105; X64-NEXT:  .LBB68_1: # %atomicrmw.start
4106; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4107; X64-NEXT:    movl %eax, %esi
4108; X64-NEXT:    orl %edx, %esi
4109; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
4110; X64-NEXT:    jne .LBB68_1
4111; X64-NEXT:  # %bb.2: # %atomicrmw.end
4112; X64-NEXT:    xorl %edx, %edx
4113; X64-NEXT:    btl %ecx, %eax
4114; X64-NEXT:    setae %dl
4115; X64-NEXT:    movl %edx, %eax
4116; X64-NEXT:    retq
4117entry:
4118  %0 = and i32 %c, 31
4119  %shl = shl nuw i32 1, %0
4120  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4121  %2 = xor i32 %1, -1
4122  %3 = lshr i32 %2, %c
4123  %lnot.ext = and i32 %3, 1
4124  ret i32 %lnot.ext
4125}
4126
4127define i32 @atomic_shl1_mask1_or_32_gpr_valz(ptr %v, i32 %c) nounwind {
4128; X86-LABEL: atomic_shl1_mask1_or_32_gpr_valz:
4129; X86:       # %bb.0: # %entry
4130; X86-NEXT:    pushl %edi
4131; X86-NEXT:    pushl %esi
4132; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4133; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4134; X86-NEXT:    movl $1, %esi
4135; X86-NEXT:    shll %cl, %esi
4136; X86-NEXT:    movl (%edx), %eax
4137; X86-NEXT:    .p2align 4
4138; X86-NEXT:  .LBB69_1: # %atomicrmw.start
4139; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4140; X86-NEXT:    movl %eax, %edi
4141; X86-NEXT:    orl %esi, %edi
4142; X86-NEXT:    lock cmpxchgl %edi, (%edx)
4143; X86-NEXT:    jne .LBB69_1
4144; X86-NEXT:  # %bb.2: # %atomicrmw.end
4145; X86-NEXT:    xorl %edx, %edx
4146; X86-NEXT:    btl %ecx, %eax
4147; X86-NEXT:    setae %dl
4148; X86-NEXT:    movl %edx, %eax
4149; X86-NEXT:    popl %esi
4150; X86-NEXT:    popl %edi
4151; X86-NEXT:    retl
4152;
4153; X64-LABEL: atomic_shl1_mask1_or_32_gpr_valz:
4154; X64:       # %bb.0: # %entry
4155; X64-NEXT:    movl %esi, %ecx
4156; X64-NEXT:    movl $1, %edx
4157; X64-NEXT:    shll %cl, %edx
4158; X64-NEXT:    movl (%rdi), %eax
4159; X64-NEXT:    .p2align 4
4160; X64-NEXT:  .LBB69_1: # %atomicrmw.start
4161; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4162; X64-NEXT:    movl %eax, %esi
4163; X64-NEXT:    orl %edx, %esi
4164; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
4165; X64-NEXT:    jne .LBB69_1
4166; X64-NEXT:  # %bb.2: # %atomicrmw.end
4167; X64-NEXT:    xorl %edx, %edx
4168; X64-NEXT:    btl %ecx, %eax
4169; X64-NEXT:    setae %dl
4170; X64-NEXT:    movl %edx, %eax
4171; X64-NEXT:    retq
4172entry:
4173  %shl = shl nuw i32 1, %c
4174  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4175  %1 = and i32 %c, 31
4176  %2 = xor i32 %0, -1
4177  %3 = lshr i32 %2, %1
4178  %lnot.ext = and i32 %3, 1
4179  ret i32 %lnot.ext
4180}
4181
4182define i32 @atomic_shl1_mask01_or_32_gpr_valz(ptr %v, i32 %c) nounwind {
4183; X86-LABEL: atomic_shl1_mask01_or_32_gpr_valz:
4184; X86:       # %bb.0: # %entry
4185; X86-NEXT:    pushl %edi
4186; X86-NEXT:    pushl %esi
4187; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4188; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4189; X86-NEXT:    andl $31, %ecx
4190; X86-NEXT:    movl $1, %esi
4191; X86-NEXT:    shll %cl, %esi
4192; X86-NEXT:    movl (%edx), %eax
4193; X86-NEXT:    .p2align 4
4194; X86-NEXT:  .LBB70_1: # %atomicrmw.start
4195; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4196; X86-NEXT:    movl %eax, %edi
4197; X86-NEXT:    orl %esi, %edi
4198; X86-NEXT:    lock cmpxchgl %edi, (%edx)
4199; X86-NEXT:    jne .LBB70_1
4200; X86-NEXT:  # %bb.2: # %atomicrmw.end
4201; X86-NEXT:    xorl %edx, %edx
4202; X86-NEXT:    btl %ecx, %eax
4203; X86-NEXT:    setae %dl
4204; X86-NEXT:    movl %edx, %eax
4205; X86-NEXT:    popl %esi
4206; X86-NEXT:    popl %edi
4207; X86-NEXT:    retl
4208;
4209; X64-LABEL: atomic_shl1_mask01_or_32_gpr_valz:
4210; X64:       # %bb.0: # %entry
4211; X64-NEXT:    movl %esi, %ecx
4212; X64-NEXT:    andl $31, %ecx
4213; X64-NEXT:    movl $1, %edx
4214; X64-NEXT:    shll %cl, %edx
4215; X64-NEXT:    movl (%rdi), %eax
4216; X64-NEXT:    .p2align 4
4217; X64-NEXT:  .LBB70_1: # %atomicrmw.start
4218; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4219; X64-NEXT:    movl %eax, %esi
4220; X64-NEXT:    orl %edx, %esi
4221; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
4222; X64-NEXT:    jne .LBB70_1
4223; X64-NEXT:  # %bb.2: # %atomicrmw.end
4224; X64-NEXT:    xorl %edx, %edx
4225; X64-NEXT:    btl %ecx, %eax
4226; X64-NEXT:    setae %dl
4227; X64-NEXT:    movl %edx, %eax
4228; X64-NEXT:    retq
4229entry:
4230  %0 = and i32 %c, 31
4231  %shl = shl nuw i32 1, %0
4232  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4233  %2 = xor i32 %1, -1
4234  %3 = lshr i32 %2, %0
4235  %lnot.ext = and i32 %3, 1
4236  ret i32 %lnot.ext
4237}
4238
4239define i32 @atomic_blsi_or_32_gpr_valz(ptr %v, i32 %c) nounwind {
4240; X86-LABEL: atomic_blsi_or_32_gpr_valz:
4241; X86:       # %bb.0: # %entry
4242; X86-NEXT:    pushl %esi
4243; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4244; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
4245; X86-NEXT:    movl %eax, %edx
4246; X86-NEXT:    negl %edx
4247; X86-NEXT:    andl %eax, %edx
4248; X86-NEXT:    movl (%ecx), %eax
4249; X86-NEXT:    .p2align 4
4250; X86-NEXT:  .LBB71_1: # %atomicrmw.start
4251; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4252; X86-NEXT:    movl %eax, %esi
4253; X86-NEXT:    orl %edx, %esi
4254; X86-NEXT:    lock cmpxchgl %esi, (%ecx)
4255; X86-NEXT:    jne .LBB71_1
4256; X86-NEXT:  # %bb.2: # %atomicrmw.end
4257; X86-NEXT:    xorl %ecx, %ecx
4258; X86-NEXT:    testl %edx, %eax
4259; X86-NEXT:    sete %cl
4260; X86-NEXT:    movl %ecx, %eax
4261; X86-NEXT:    popl %esi
4262; X86-NEXT:    retl
4263;
4264; X64-LABEL: atomic_blsi_or_32_gpr_valz:
4265; X64:       # %bb.0: # %entry
4266; X64-NEXT:    movl %esi, %edx
4267; X64-NEXT:    negl %edx
4268; X64-NEXT:    andl %esi, %edx
4269; X64-NEXT:    movl (%rdi), %eax
4270; X64-NEXT:    .p2align 4
4271; X64-NEXT:  .LBB71_1: # %atomicrmw.start
4272; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4273; X64-NEXT:    movl %eax, %ecx
4274; X64-NEXT:    orl %edx, %ecx
4275; X64-NEXT:    lock cmpxchgl %ecx, (%rdi)
4276; X64-NEXT:    jne .LBB71_1
4277; X64-NEXT:  # %bb.2: # %atomicrmw.end
4278; X64-NEXT:    xorl %ecx, %ecx
4279; X64-NEXT:    testl %edx, %eax
4280; X64-NEXT:    sete %cl
4281; X64-NEXT:    movl %ecx, %eax
4282; X64-NEXT:    retq
4283entry:
4284  %sub = sub i32 0, %c
4285  %and = and i32 %sub, %c
4286  %0 = atomicrmw or ptr %v, i32 %and monotonic, align 4
4287  %and3 = and i32 %0, %and
4288  %tobool.not = icmp eq i32 %and3, 0
4289  %lnot.ext = zext i1 %tobool.not to i32
4290  ret i32 %lnot.ext
4291}
4292
4293define i32 @atomic_shl1_or_32_gpr_valnz(ptr %v, i32 %c) nounwind {
4294; X86-LABEL: atomic_shl1_or_32_gpr_valnz:
4295; X86:       # %bb.0: # %entry
4296; X86-NEXT:    pushl %edi
4297; X86-NEXT:    pushl %esi
4298; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4299; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4300; X86-NEXT:    movl $1, %esi
4301; X86-NEXT:    shll %cl, %esi
4302; X86-NEXT:    movl (%edx), %eax
4303; X86-NEXT:    .p2align 4
4304; X86-NEXT:  .LBB72_1: # %atomicrmw.start
4305; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4306; X86-NEXT:    movl %eax, %edi
4307; X86-NEXT:    orl %esi, %edi
4308; X86-NEXT:    lock cmpxchgl %edi, (%edx)
4309; X86-NEXT:    jne .LBB72_1
4310; X86-NEXT:  # %bb.2: # %atomicrmw.end
4311; X86-NEXT:    xorl %edx, %edx
4312; X86-NEXT:    btl %ecx, %eax
4313; X86-NEXT:    setb %dl
4314; X86-NEXT:    movl %edx, %eax
4315; X86-NEXT:    popl %esi
4316; X86-NEXT:    popl %edi
4317; X86-NEXT:    retl
4318;
4319; X64-LABEL: atomic_shl1_or_32_gpr_valnz:
4320; X64:       # %bb.0: # %entry
4321; X64-NEXT:    movl %esi, %ecx
4322; X64-NEXT:    movl $1, %edx
4323; X64-NEXT:    shll %cl, %edx
4324; X64-NEXT:    movl (%rdi), %eax
4325; X64-NEXT:    .p2align 4
4326; X64-NEXT:  .LBB72_1: # %atomicrmw.start
4327; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4328; X64-NEXT:    movl %eax, %esi
4329; X64-NEXT:    orl %edx, %esi
4330; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
4331; X64-NEXT:    jne .LBB72_1
4332; X64-NEXT:  # %bb.2: # %atomicrmw.end
4333; X64-NEXT:    xorl %edx, %edx
4334; X64-NEXT:    btl %ecx, %eax
4335; X64-NEXT:    setb %dl
4336; X64-NEXT:    movl %edx, %eax
4337; X64-NEXT:    retq
4338entry:
4339  %shl = shl nuw i32 1, %c
4340  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4341  %1 = lshr i32 %0, %c
4342  %lnot.ext = and i32 %1, 1
4343  ret i32 %lnot.ext
4344}
4345
4346define i32 @atomic_shl1_small_mask_or_32_gpr_valnz(ptr %v, i32 %c) nounwind {
4347; X86-LABEL: atomic_shl1_small_mask_or_32_gpr_valnz:
4348; X86:       # %bb.0: # %entry
4349; X86-NEXT:    pushl %edi
4350; X86-NEXT:    pushl %esi
4351; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4352; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4353; X86-NEXT:    andl $15, %ecx
4354; X86-NEXT:    movl $1, %esi
4355; X86-NEXT:    shll %cl, %esi
4356; X86-NEXT:    movl (%edx), %eax
4357; X86-NEXT:    .p2align 4
4358; X86-NEXT:  .LBB73_1: # %atomicrmw.start
4359; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4360; X86-NEXT:    movl %eax, %edi
4361; X86-NEXT:    orl %esi, %edi
4362; X86-NEXT:    lock cmpxchgl %edi, (%edx)
4363; X86-NEXT:    jne .LBB73_1
4364; X86-NEXT:  # %bb.2: # %atomicrmw.end
4365; X86-NEXT:    xorl %edx, %edx
4366; X86-NEXT:    btl %ecx, %eax
4367; X86-NEXT:    setb %dl
4368; X86-NEXT:    movl %edx, %eax
4369; X86-NEXT:    popl %esi
4370; X86-NEXT:    popl %edi
4371; X86-NEXT:    retl
4372;
4373; X64-LABEL: atomic_shl1_small_mask_or_32_gpr_valnz:
4374; X64:       # %bb.0: # %entry
4375; X64-NEXT:    movl %esi, %ecx
4376; X64-NEXT:    andl $15, %ecx
4377; X64-NEXT:    movl $1, %edx
4378; X64-NEXT:    shll %cl, %edx
4379; X64-NEXT:    movl (%rdi), %eax
4380; X64-NEXT:    .p2align 4
4381; X64-NEXT:  .LBB73_1: # %atomicrmw.start
4382; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4383; X64-NEXT:    movl %eax, %esi
4384; X64-NEXT:    orl %edx, %esi
4385; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
4386; X64-NEXT:    jne .LBB73_1
4387; X64-NEXT:  # %bb.2: # %atomicrmw.end
4388; X64-NEXT:    xorl %edx, %edx
4389; X64-NEXT:    btl %ecx, %eax
4390; X64-NEXT:    setb %dl
4391; X64-NEXT:    movl %edx, %eax
4392; X64-NEXT:    retq
4393entry:
4394  %0 = and i32 %c, 15
4395  %shl = shl nuw nsw i32 1, %0
4396  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4397  %2 = lshr i32 %1, %0
4398  %lnot.ext = and i32 %2, 1
4399  ret i32 %lnot.ext
4400}
4401
4402define i32 @atomic_shl1_mask0_or_32_gpr_valnz(ptr %v, i32 %c) nounwind {
4403; X86-LABEL: atomic_shl1_mask0_or_32_gpr_valnz:
4404; X86:       # %bb.0: # %entry
4405; X86-NEXT:    pushl %edi
4406; X86-NEXT:    pushl %esi
4407; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4408; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4409; X86-NEXT:    movl $1, %esi
4410; X86-NEXT:    shll %cl, %esi
4411; X86-NEXT:    movl (%edx), %eax
4412; X86-NEXT:    .p2align 4
4413; X86-NEXT:  .LBB74_1: # %atomicrmw.start
4414; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4415; X86-NEXT:    movl %eax, %edi
4416; X86-NEXT:    orl %esi, %edi
4417; X86-NEXT:    lock cmpxchgl %edi, (%edx)
4418; X86-NEXT:    jne .LBB74_1
4419; X86-NEXT:  # %bb.2: # %atomicrmw.end
4420; X86-NEXT:    xorl %edx, %edx
4421; X86-NEXT:    btl %ecx, %eax
4422; X86-NEXT:    setb %dl
4423; X86-NEXT:    movl %edx, %eax
4424; X86-NEXT:    popl %esi
4425; X86-NEXT:    popl %edi
4426; X86-NEXT:    retl
4427;
4428; X64-LABEL: atomic_shl1_mask0_or_32_gpr_valnz:
4429; X64:       # %bb.0: # %entry
4430; X64-NEXT:    movl %esi, %ecx
4431; X64-NEXT:    movl $1, %edx
4432; X64-NEXT:    shll %cl, %edx
4433; X64-NEXT:    movl (%rdi), %eax
4434; X64-NEXT:    .p2align 4
4435; X64-NEXT:  .LBB74_1: # %atomicrmw.start
4436; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4437; X64-NEXT:    movl %eax, %esi
4438; X64-NEXT:    orl %edx, %esi
4439; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
4440; X64-NEXT:    jne .LBB74_1
4441; X64-NEXT:  # %bb.2: # %atomicrmw.end
4442; X64-NEXT:    xorl %edx, %edx
4443; X64-NEXT:    btl %ecx, %eax
4444; X64-NEXT:    setb %dl
4445; X64-NEXT:    movl %edx, %eax
4446; X64-NEXT:    retq
4447entry:
4448  %0 = and i32 %c, 31
4449  %shl = shl nuw i32 1, %0
4450  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4451  %2 = lshr i32 %1, %c
4452  %lnot.ext = and i32 %2, 1
4453  ret i32 %lnot.ext
4454}
4455
4456define i32 @atomic_shl1_mask1_or_32_gpr_valnz(ptr %v, i32 %c) nounwind {
4457; X86-LABEL: atomic_shl1_mask1_or_32_gpr_valnz:
4458; X86:       # %bb.0: # %entry
4459; X86-NEXT:    pushl %edi
4460; X86-NEXT:    pushl %esi
4461; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4462; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4463; X86-NEXT:    movl $1, %esi
4464; X86-NEXT:    shll %cl, %esi
4465; X86-NEXT:    movl (%edx), %eax
4466; X86-NEXT:    .p2align 4
4467; X86-NEXT:  .LBB75_1: # %atomicrmw.start
4468; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4469; X86-NEXT:    movl %eax, %edi
4470; X86-NEXT:    orl %esi, %edi
4471; X86-NEXT:    lock cmpxchgl %edi, (%edx)
4472; X86-NEXT:    jne .LBB75_1
4473; X86-NEXT:  # %bb.2: # %atomicrmw.end
4474; X86-NEXT:    xorl %edx, %edx
4475; X86-NEXT:    btl %ecx, %eax
4476; X86-NEXT:    setb %dl
4477; X86-NEXT:    movl %edx, %eax
4478; X86-NEXT:    popl %esi
4479; X86-NEXT:    popl %edi
4480; X86-NEXT:    retl
4481;
4482; X64-LABEL: atomic_shl1_mask1_or_32_gpr_valnz:
4483; X64:       # %bb.0: # %entry
4484; X64-NEXT:    movl %esi, %ecx
4485; X64-NEXT:    movl $1, %edx
4486; X64-NEXT:    shll %cl, %edx
4487; X64-NEXT:    movl (%rdi), %eax
4488; X64-NEXT:    .p2align 4
4489; X64-NEXT:  .LBB75_1: # %atomicrmw.start
4490; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4491; X64-NEXT:    movl %eax, %esi
4492; X64-NEXT:    orl %edx, %esi
4493; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
4494; X64-NEXT:    jne .LBB75_1
4495; X64-NEXT:  # %bb.2: # %atomicrmw.end
4496; X64-NEXT:    xorl %edx, %edx
4497; X64-NEXT:    btl %ecx, %eax
4498; X64-NEXT:    setb %dl
4499; X64-NEXT:    movl %edx, %eax
4500; X64-NEXT:    retq
4501entry:
4502  %shl = shl nuw i32 1, %c
4503  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4504  %1 = and i32 %c, 31
4505  %2 = lshr i32 %0, %1
4506  %lnot.ext = and i32 %2, 1
4507  ret i32 %lnot.ext
4508}
4509
4510define i32 @atomic_shl1_mask01_or_32_gpr_valnz(ptr %v, i32 %c) nounwind {
4511; X86-LABEL: atomic_shl1_mask01_or_32_gpr_valnz:
4512; X86:       # %bb.0: # %entry
4513; X86-NEXT:    pushl %edi
4514; X86-NEXT:    pushl %esi
4515; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4516; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4517; X86-NEXT:    andl $31, %ecx
4518; X86-NEXT:    movl $1, %esi
4519; X86-NEXT:    shll %cl, %esi
4520; X86-NEXT:    movl (%edx), %eax
4521; X86-NEXT:    .p2align 4
4522; X86-NEXT:  .LBB76_1: # %atomicrmw.start
4523; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4524; X86-NEXT:    movl %eax, %edi
4525; X86-NEXT:    orl %esi, %edi
4526; X86-NEXT:    lock cmpxchgl %edi, (%edx)
4527; X86-NEXT:    jne .LBB76_1
4528; X86-NEXT:  # %bb.2: # %atomicrmw.end
4529; X86-NEXT:    xorl %edx, %edx
4530; X86-NEXT:    btl %ecx, %eax
4531; X86-NEXT:    setb %dl
4532; X86-NEXT:    movl %edx, %eax
4533; X86-NEXT:    popl %esi
4534; X86-NEXT:    popl %edi
4535; X86-NEXT:    retl
4536;
4537; X64-LABEL: atomic_shl1_mask01_or_32_gpr_valnz:
4538; X64:       # %bb.0: # %entry
4539; X64-NEXT:    movl %esi, %ecx
4540; X64-NEXT:    andl $31, %ecx
4541; X64-NEXT:    movl $1, %edx
4542; X64-NEXT:    shll %cl, %edx
4543; X64-NEXT:    movl (%rdi), %eax
4544; X64-NEXT:    .p2align 4
4545; X64-NEXT:  .LBB76_1: # %atomicrmw.start
4546; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4547; X64-NEXT:    movl %eax, %esi
4548; X64-NEXT:    orl %edx, %esi
4549; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
4550; X64-NEXT:    jne .LBB76_1
4551; X64-NEXT:  # %bb.2: # %atomicrmw.end
4552; X64-NEXT:    xorl %edx, %edx
4553; X64-NEXT:    btl %ecx, %eax
4554; X64-NEXT:    setb %dl
4555; X64-NEXT:    movl %edx, %eax
4556; X64-NEXT:    retq
4557entry:
4558  %0 = and i32 %c, 31
4559  %shl = shl nuw i32 1, %0
4560  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4561  %2 = lshr i32 %1, %0
4562  %lnot.ext = and i32 %2, 1
4563  ret i32 %lnot.ext
4564}
4565
4566define i32 @atomic_blsi_or_32_gpr_valnz(ptr %v, i32 %c) nounwind {
4567; X86-LABEL: atomic_blsi_or_32_gpr_valnz:
4568; X86:       # %bb.0: # %entry
4569; X86-NEXT:    pushl %esi
4570; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4571; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
4572; X86-NEXT:    movl %eax, %edx
4573; X86-NEXT:    negl %edx
4574; X86-NEXT:    andl %eax, %edx
4575; X86-NEXT:    movl (%ecx), %eax
4576; X86-NEXT:    .p2align 4
4577; X86-NEXT:  .LBB77_1: # %atomicrmw.start
4578; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4579; X86-NEXT:    movl %eax, %esi
4580; X86-NEXT:    orl %edx, %esi
4581; X86-NEXT:    lock cmpxchgl %esi, (%ecx)
4582; X86-NEXT:    jne .LBB77_1
4583; X86-NEXT:  # %bb.2: # %atomicrmw.end
4584; X86-NEXT:    xorl %ecx, %ecx
4585; X86-NEXT:    testl %edx, %eax
4586; X86-NEXT:    setne %cl
4587; X86-NEXT:    movl %ecx, %eax
4588; X86-NEXT:    popl %esi
4589; X86-NEXT:    retl
4590;
4591; X64-LABEL: atomic_blsi_or_32_gpr_valnz:
4592; X64:       # %bb.0: # %entry
4593; X64-NEXT:    movl %esi, %edx
4594; X64-NEXT:    negl %edx
4595; X64-NEXT:    andl %esi, %edx
4596; X64-NEXT:    movl (%rdi), %eax
4597; X64-NEXT:    .p2align 4
4598; X64-NEXT:  .LBB77_1: # %atomicrmw.start
4599; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4600; X64-NEXT:    movl %eax, %ecx
4601; X64-NEXT:    orl %edx, %ecx
4602; X64-NEXT:    lock cmpxchgl %ecx, (%rdi)
4603; X64-NEXT:    jne .LBB77_1
4604; X64-NEXT:  # %bb.2: # %atomicrmw.end
4605; X64-NEXT:    xorl %ecx, %ecx
4606; X64-NEXT:    testl %edx, %eax
4607; X64-NEXT:    setne %cl
4608; X64-NEXT:    movl %ecx, %eax
4609; X64-NEXT:    retq
4610entry:
4611  %sub = sub i32 0, %c
4612  %and = and i32 %sub, %c
4613  %0 = atomicrmw or ptr %v, i32 %and monotonic, align 4
4614  %and3 = and i32 %0, %and
4615  %tobool = icmp ne i32 %and3, 0
4616  %lnot.ext = zext i1 %tobool to i32
4617  ret i32 %lnot.ext
4618}
4619
4620define i32 @atomic_shl1_or_32_gpr_br(ptr %v, i32 %c) nounwind {
4621; X86-LABEL: atomic_shl1_or_32_gpr_br:
4622; X86:       # %bb.0: # %entry
4623; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
4624; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4625; X86-NEXT:    movl %eax, %edx
4626; X86-NEXT:    andl $31, %edx
4627; X86-NEXT:    lock btsl %edx, (%ecx)
4628; X86-NEXT:    jae .LBB78_1
4629; X86-NEXT:  # %bb.2: # %if.then
4630; X86-NEXT:    movl (%ecx,%eax,4), %eax
4631; X86-NEXT:    retl
4632; X86-NEXT:  .LBB78_1:
4633; X86-NEXT:    movl $123, %eax
4634; X86-NEXT:    retl
4635;
4636; X64-LABEL: atomic_shl1_or_32_gpr_br:
4637; X64:       # %bb.0: # %entry
4638; X64-NEXT:    movl %esi, %eax
4639; X64-NEXT:    andl $31, %eax
4640; X64-NEXT:    lock btsl %eax, (%rdi)
4641; X64-NEXT:    jae .LBB78_1
4642; X64-NEXT:  # %bb.2: # %if.then
4643; X64-NEXT:    movl %esi, %eax
4644; X64-NEXT:    movl (%rdi,%rax,4), %eax
4645; X64-NEXT:    retq
4646; X64-NEXT:  .LBB78_1:
4647; X64-NEXT:    movl $123, %eax
4648; X64-NEXT:    retq
4649entry:
4650  %shl = shl nuw i32 1, %c
4651  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4652  %and = and i32 %0, %shl
4653  %tobool.not = icmp eq i32 %and, 0
4654  br i1 %tobool.not, label %return, label %if.then
4655
4656if.then:                                          ; preds = %entry
4657  %idxprom = zext i32 %c to i64
4658  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %idxprom
4659  %1 = load i32, ptr %arrayidx, align 4
4660  br label %return
4661
4662return:                                           ; preds = %entry, %if.then
4663  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
4664  ret i32 %retval.0
4665}
4666
4667define i32 @atomic_shl1_small_mask_or_32_gpr_br(ptr %v, i32 %c) nounwind {
4668; X86-LABEL: atomic_shl1_small_mask_or_32_gpr_br:
4669; X86:       # %bb.0: # %entry
4670; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
4671; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4672; X86-NEXT:    andl $15, %ecx
4673; X86-NEXT:    lock btsl %ecx, (%eax)
4674; X86-NEXT:    jae .LBB79_1
4675; X86-NEXT:  # %bb.2: # %if.then
4676; X86-NEXT:    movl (%eax,%ecx,4), %eax
4677; X86-NEXT:    retl
4678; X86-NEXT:  .LBB79_1:
4679; X86-NEXT:    movl $123, %eax
4680; X86-NEXT:    retl
4681;
4682; X64-LABEL: atomic_shl1_small_mask_or_32_gpr_br:
4683; X64:       # %bb.0: # %entry
4684; X64-NEXT:    andl $15, %esi
4685; X64-NEXT:    lock btsl %esi, (%rdi)
4686; X64-NEXT:    jae .LBB79_1
4687; X64-NEXT:  # %bb.2: # %if.then
4688; X64-NEXT:    movl %esi, %eax
4689; X64-NEXT:    movl (%rdi,%rax,4), %eax
4690; X64-NEXT:    retq
4691; X64-NEXT:  .LBB79_1:
4692; X64-NEXT:    movl $123, %eax
4693; X64-NEXT:    retq
4694entry:
4695  %0 = and i32 %c, 15
4696  %shl = shl nuw nsw i32 1, %0
4697  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4698  %and = and i32 %shl, %1
4699  %tobool.not = icmp eq i32 %and, 0
4700  br i1 %tobool.not, label %return, label %if.then
4701
4702if.then:                                          ; preds = %entry
4703  %conv2 = zext i32 %0 to i64
4704  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv2
4705  %2 = load i32, ptr %arrayidx, align 4
4706  br label %return
4707
4708return:                                           ; preds = %entry, %if.then
4709  %retval.0 = phi i32 [ %2, %if.then ], [ 123, %entry ]
4710  ret i32 %retval.0
4711}
4712
4713define i32 @atomic_shl1_mask0_or_32_gpr_br(ptr %v, i32 %c) nounwind {
4714; X86-LABEL: atomic_shl1_mask0_or_32_gpr_br:
4715; X86:       # %bb.0: # %entry
4716; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
4717; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4718; X86-NEXT:    movl %eax, %edx
4719; X86-NEXT:    andl $31, %edx
4720; X86-NEXT:    lock btsl %edx, (%ecx)
4721; X86-NEXT:    jae .LBB80_1
4722; X86-NEXT:  # %bb.2: # %if.then
4723; X86-NEXT:    movl (%ecx,%eax,4), %eax
4724; X86-NEXT:    retl
4725; X86-NEXT:  .LBB80_1:
4726; X86-NEXT:    movl $123, %eax
4727; X86-NEXT:    retl
4728;
4729; X64-LABEL: atomic_shl1_mask0_or_32_gpr_br:
4730; X64:       # %bb.0: # %entry
4731; X64-NEXT:    movl %esi, %eax
4732; X64-NEXT:    andl $31, %eax
4733; X64-NEXT:    lock btsl %eax, (%rdi)
4734; X64-NEXT:    jae .LBB80_1
4735; X64-NEXT:  # %bb.2: # %if.then
4736; X64-NEXT:    movl %esi, %eax
4737; X64-NEXT:    movl (%rdi,%rax,4), %eax
4738; X64-NEXT:    retq
4739; X64-NEXT:  .LBB80_1:
4740; X64-NEXT:    movl $123, %eax
4741; X64-NEXT:    retq
4742entry:
4743  %rem = and i32 %c, 31
4744  %shl = shl nuw i32 1, %rem
4745  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4746  %shl1 = shl nuw i32 1, %c
4747  %and = and i32 %0, %shl1
4748  %tobool.not = icmp eq i32 %and, 0
4749  br i1 %tobool.not, label %return, label %if.then
4750
4751if.then:                                          ; preds = %entry
4752  %conv = zext i32 %c to i64
4753  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
4754  %1 = load i32, ptr %arrayidx, align 4
4755  br label %return
4756
4757return:                                           ; preds = %entry, %if.then
4758  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
4759  ret i32 %retval.0
4760}
4761
4762define i32 @atomic_shl1_mask1_or_32_gpr_br(ptr %v, i32 %c) nounwind {
4763; X86-LABEL: atomic_shl1_mask1_or_32_gpr_br:
4764; X86:       # %bb.0: # %entry
4765; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
4766; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4767; X86-NEXT:    movl %eax, %edx
4768; X86-NEXT:    andl $31, %edx
4769; X86-NEXT:    lock btsl %edx, (%ecx)
4770; X86-NEXT:    jae .LBB81_1
4771; X86-NEXT:  # %bb.2: # %if.then
4772; X86-NEXT:    movl (%ecx,%eax,4), %eax
4773; X86-NEXT:    retl
4774; X86-NEXT:  .LBB81_1:
4775; X86-NEXT:    movl $123, %eax
4776; X86-NEXT:    retl
4777;
4778; X64-LABEL: atomic_shl1_mask1_or_32_gpr_br:
4779; X64:       # %bb.0: # %entry
4780; X64-NEXT:    movl %esi, %eax
4781; X64-NEXT:    andl $31, %eax
4782; X64-NEXT:    lock btsl %eax, (%rdi)
4783; X64-NEXT:    jae .LBB81_1
4784; X64-NEXT:  # %bb.2: # %if.then
4785; X64-NEXT:    movl %esi, %eax
4786; X64-NEXT:    movl (%rdi,%rax,4), %eax
4787; X64-NEXT:    retq
4788; X64-NEXT:  .LBB81_1:
4789; X64-NEXT:    movl $123, %eax
4790; X64-NEXT:    retq
4791entry:
4792  %shl = shl nuw i32 1, %c
4793  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4794  %rem = and i32 %c, 31
4795  %shl1 = shl nuw i32 1, %rem
4796  %and = and i32 %0, %shl1
4797  %tobool.not = icmp eq i32 %and, 0
4798  br i1 %tobool.not, label %return, label %if.then
4799
4800if.then:                                          ; preds = %entry
4801  %conv = zext i32 %c to i64
4802  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
4803  %1 = load i32, ptr %arrayidx, align 4
4804  br label %return
4805
4806return:                                           ; preds = %entry, %if.then
4807  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
4808  ret i32 %retval.0
4809}
4810
4811define i32 @atomic_shl1_mask01_or_32_gpr_br(ptr %v, i32 %c) nounwind {
4812; X86-LABEL: atomic_shl1_mask01_or_32_gpr_br:
4813; X86:       # %bb.0: # %entry
4814; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
4815; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4816; X86-NEXT:    movl %eax, %edx
4817; X86-NEXT:    andl $31, %edx
4818; X86-NEXT:    lock btsl %edx, (%ecx)
4819; X86-NEXT:    jae .LBB82_1
4820; X86-NEXT:  # %bb.2: # %if.then
4821; X86-NEXT:    movl (%ecx,%eax,4), %eax
4822; X86-NEXT:    retl
4823; X86-NEXT:  .LBB82_1:
4824; X86-NEXT:    movl $123, %eax
4825; X86-NEXT:    retl
4826;
4827; X64-LABEL: atomic_shl1_mask01_or_32_gpr_br:
4828; X64:       # %bb.0: # %entry
4829; X64-NEXT:    movl %esi, %eax
4830; X64-NEXT:    andl $31, %eax
4831; X64-NEXT:    lock btsl %eax, (%rdi)
4832; X64-NEXT:    jae .LBB82_1
4833; X64-NEXT:  # %bb.2: # %if.then
4834; X64-NEXT:    movl %esi, %eax
4835; X64-NEXT:    movl (%rdi,%rax,4), %eax
4836; X64-NEXT:    retq
4837; X64-NEXT:  .LBB82_1:
4838; X64-NEXT:    movl $123, %eax
4839; X64-NEXT:    retq
4840entry:
4841  %rem = and i32 %c, 31
4842  %shl = shl nuw i32 1, %rem
4843  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4844  %and = and i32 %shl, %0
4845  %tobool.not = icmp eq i32 %and, 0
4846  br i1 %tobool.not, label %return, label %if.then
4847
4848if.then:                                          ; preds = %entry
4849  %conv = zext i32 %c to i64
4850  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
4851  %1 = load i32, ptr %arrayidx, align 4
4852  br label %return
4853
4854return:                                           ; preds = %entry, %if.then
4855  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
4856  ret i32 %retval.0
4857}
4858
4859define i32 @atomic_blsi_or_32_gpr_br(ptr %v, i32 %c) nounwind {
4860; X86-LABEL: atomic_blsi_or_32_gpr_br:
4861; X86:       # %bb.0: # %entry
4862; X86-NEXT:    pushl %edi
4863; X86-NEXT:    pushl %esi
4864; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4865; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4866; X86-NEXT:    movl %ecx, %esi
4867; X86-NEXT:    negl %esi
4868; X86-NEXT:    andl %ecx, %esi
4869; X86-NEXT:    movl (%edx), %eax
4870; X86-NEXT:    .p2align 4
4871; X86-NEXT:  .LBB83_1: # %atomicrmw.start
4872; X86-NEXT:    # =>This Inner Loop Header: Depth=1
4873; X86-NEXT:    movl %eax, %edi
4874; X86-NEXT:    orl %esi, %edi
4875; X86-NEXT:    lock cmpxchgl %edi, (%edx)
4876; X86-NEXT:    jne .LBB83_1
4877; X86-NEXT:  # %bb.2: # %atomicrmw.end
4878; X86-NEXT:    testl %esi, %eax
4879; X86-NEXT:    je .LBB83_3
4880; X86-NEXT:  # %bb.4: # %if.then
4881; X86-NEXT:    movl (%edx,%ecx,4), %eax
4882; X86-NEXT:    jmp .LBB83_5
4883; X86-NEXT:  .LBB83_3:
4884; X86-NEXT:    movl $123, %eax
4885; X86-NEXT:  .LBB83_5: # %return
4886; X86-NEXT:    popl %esi
4887; X86-NEXT:    popl %edi
4888; X86-NEXT:    retl
4889;
4890; X64-LABEL: atomic_blsi_or_32_gpr_br:
4891; X64:       # %bb.0: # %entry
4892; X64-NEXT:    movl %esi, %ecx
4893; X64-NEXT:    negl %ecx
4894; X64-NEXT:    andl %esi, %ecx
4895; X64-NEXT:    movl (%rdi), %eax
4896; X64-NEXT:    .p2align 4
4897; X64-NEXT:  .LBB83_1: # %atomicrmw.start
4898; X64-NEXT:    # =>This Inner Loop Header: Depth=1
4899; X64-NEXT:    movl %eax, %edx
4900; X64-NEXT:    orl %ecx, %edx
4901; X64-NEXT:    lock cmpxchgl %edx, (%rdi)
4902; X64-NEXT:    jne .LBB83_1
4903; X64-NEXT:  # %bb.2: # %atomicrmw.end
4904; X64-NEXT:    testl %ecx, %eax
4905; X64-NEXT:    je .LBB83_3
4906; X64-NEXT:  # %bb.4: # %if.then
4907; X64-NEXT:    movl %esi, %eax
4908; X64-NEXT:    movl (%rdi,%rax,4), %eax
4909; X64-NEXT:    retq
4910; X64-NEXT:  .LBB83_3:
4911; X64-NEXT:    movl $123, %eax
4912; X64-NEXT:    retq
4913entry:
4914  %sub = sub i32 0, %c
4915  %and = and i32 %sub, %c
4916  %0 = atomicrmw or ptr %v, i32 %and monotonic, align 4
4917  %and3 = and i32 %0, %and
4918  %tobool.not = icmp eq i32 %and3, 0
4919  br i1 %tobool.not, label %return, label %if.then
4920
4921if.then:                                          ; preds = %entry
4922  %idxprom = zext i32 %c to i64
4923  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %idxprom
4924  %1 = load i32, ptr %arrayidx, align 4
4925  br label %return
4926
4927return:                                           ; preds = %entry, %if.then
4928  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
4929  ret i32 %retval.0
4930}
4931
4932define i32 @atomic_shl1_or_32_gpr_brz(ptr %v, i32 %c) nounwind {
4933; X86-LABEL: atomic_shl1_or_32_gpr_brz:
4934; X86:       # %bb.0: # %entry
4935; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4936; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4937; X86-NEXT:    movl %ecx, %eax
4938; X86-NEXT:    andl $31, %eax
4939; X86-NEXT:    lock btsl %eax, (%edx)
4940; X86-NEXT:    movl $123, %eax
4941; X86-NEXT:    jae .LBB84_1
4942; X86-NEXT:  # %bb.2: # %return
4943; X86-NEXT:    retl
4944; X86-NEXT:  .LBB84_1: # %if.then
4945; X86-NEXT:    movl (%edx,%ecx,4), %eax
4946; X86-NEXT:    retl
4947;
4948; X64-LABEL: atomic_shl1_or_32_gpr_brz:
4949; X64:       # %bb.0: # %entry
4950; X64-NEXT:    movl %esi, %eax
4951; X64-NEXT:    andl $31, %eax
4952; X64-NEXT:    lock btsl %eax, (%rdi)
4953; X64-NEXT:    movl $123, %eax
4954; X64-NEXT:    jae .LBB84_1
4955; X64-NEXT:  # %bb.2: # %return
4956; X64-NEXT:    retq
4957; X64-NEXT:  .LBB84_1: # %if.then
4958; X64-NEXT:    movl %esi, %eax
4959; X64-NEXT:    movl (%rdi,%rax,4), %eax
4960; X64-NEXT:    retq
4961entry:
4962  %shl = shl nuw i32 1, %c
4963  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
4964  %and = and i32 %0, %shl
4965  %tobool.not = icmp eq i32 %and, 0
4966  br i1 %tobool.not, label %if.then, label %return
4967
4968if.then:                                          ; preds = %entry
4969  %idxprom = zext i32 %c to i64
4970  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %idxprom
4971  %1 = load i32, ptr %arrayidx, align 4
4972  br label %return
4973
4974return:                                           ; preds = %entry, %if.then
4975  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
4976  ret i32 %retval.0
4977}
4978
4979define i32 @atomic_shl1_small_mask_or_32_gpr_brz(ptr %v, i32 %c) nounwind {
4980; X86-LABEL: atomic_shl1_small_mask_or_32_gpr_brz:
4981; X86:       # %bb.0: # %entry
4982; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
4983; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
4984; X86-NEXT:    andl $15, %edx
4985; X86-NEXT:    lock btsl %edx, (%ecx)
4986; X86-NEXT:    movl $123, %eax
4987; X86-NEXT:    jae .LBB85_1
4988; X86-NEXT:  # %bb.2: # %return
4989; X86-NEXT:    retl
4990; X86-NEXT:  .LBB85_1: # %if.then
4991; X86-NEXT:    movl (%ecx,%edx,4), %eax
4992; X86-NEXT:    retl
4993;
4994; X64-LABEL: atomic_shl1_small_mask_or_32_gpr_brz:
4995; X64:       # %bb.0: # %entry
4996; X64-NEXT:    andl $15, %esi
4997; X64-NEXT:    lock btsl %esi, (%rdi)
4998; X64-NEXT:    movl $123, %eax
4999; X64-NEXT:    jae .LBB85_1
5000; X64-NEXT:  # %bb.2: # %return
5001; X64-NEXT:    retq
5002; X64-NEXT:  .LBB85_1: # %if.then
5003; X64-NEXT:    movl %esi, %eax
5004; X64-NEXT:    movl (%rdi,%rax,4), %eax
5005; X64-NEXT:    retq
5006entry:
5007  %0 = and i32 %c, 15
5008  %shl = shl nuw nsw i32 1, %0
5009  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
5010  %and = and i32 %shl, %1
5011  %tobool.not = icmp eq i32 %and, 0
5012  br i1 %tobool.not, label %if.then, label %return
5013
5014if.then:                                          ; preds = %entry
5015  %conv2 = zext i32 %0 to i64
5016  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv2
5017  %2 = load i32, ptr %arrayidx, align 4
5018  br label %return
5019
5020return:                                           ; preds = %entry, %if.then
5021  %retval.0 = phi i32 [ %2, %if.then ], [ 123, %entry ]
5022  ret i32 %retval.0
5023}
5024
5025define i32 @atomic_shl1_mask0_or_32_gpr_brz(ptr %v, i32 %c) nounwind {
5026; X86-LABEL: atomic_shl1_mask0_or_32_gpr_brz:
5027; X86:       # %bb.0: # %entry
5028; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5029; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5030; X86-NEXT:    movl %ecx, %eax
5031; X86-NEXT:    andl $31, %eax
5032; X86-NEXT:    lock btsl %eax, (%edx)
5033; X86-NEXT:    movl $123, %eax
5034; X86-NEXT:    jae .LBB86_1
5035; X86-NEXT:  # %bb.2: # %return
5036; X86-NEXT:    retl
5037; X86-NEXT:  .LBB86_1: # %if.then
5038; X86-NEXT:    movl (%edx,%ecx,4), %eax
5039; X86-NEXT:    retl
5040;
5041; X64-LABEL: atomic_shl1_mask0_or_32_gpr_brz:
5042; X64:       # %bb.0: # %entry
5043; X64-NEXT:    movl %esi, %eax
5044; X64-NEXT:    andl $31, %eax
5045; X64-NEXT:    lock btsl %eax, (%rdi)
5046; X64-NEXT:    movl $123, %eax
5047; X64-NEXT:    jae .LBB86_1
5048; X64-NEXT:  # %bb.2: # %return
5049; X64-NEXT:    retq
5050; X64-NEXT:  .LBB86_1: # %if.then
5051; X64-NEXT:    movl %esi, %eax
5052; X64-NEXT:    movl (%rdi,%rax,4), %eax
5053; X64-NEXT:    retq
5054entry:
5055  %rem = and i32 %c, 31
5056  %shl = shl nuw i32 1, %rem
5057  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
5058  %shl1 = shl nuw i32 1, %c
5059  %and = and i32 %0, %shl1
5060  %tobool.not = icmp eq i32 %and, 0
5061  br i1 %tobool.not, label %if.then, label %return
5062
5063if.then:                                          ; preds = %entry
5064  %conv = zext i32 %c to i64
5065  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
5066  %1 = load i32, ptr %arrayidx, align 4
5067  br label %return
5068
5069return:                                           ; preds = %entry, %if.then
5070  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
5071  ret i32 %retval.0
5072}
5073
5074define i32 @atomic_shl1_mask1_or_32_gpr_brz(ptr %v, i32 %c) nounwind {
5075; X86-LABEL: atomic_shl1_mask1_or_32_gpr_brz:
5076; X86:       # %bb.0: # %entry
5077; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5078; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5079; X86-NEXT:    movl %ecx, %eax
5080; X86-NEXT:    andl $31, %eax
5081; X86-NEXT:    lock btsl %eax, (%edx)
5082; X86-NEXT:    movl $123, %eax
5083; X86-NEXT:    jae .LBB87_1
5084; X86-NEXT:  # %bb.2: # %return
5085; X86-NEXT:    retl
5086; X86-NEXT:  .LBB87_1: # %if.then
5087; X86-NEXT:    movl (%edx,%ecx,4), %eax
5088; X86-NEXT:    retl
5089;
5090; X64-LABEL: atomic_shl1_mask1_or_32_gpr_brz:
5091; X64:       # %bb.0: # %entry
5092; X64-NEXT:    movl %esi, %eax
5093; X64-NEXT:    andl $31, %eax
5094; X64-NEXT:    lock btsl %eax, (%rdi)
5095; X64-NEXT:    movl $123, %eax
5096; X64-NEXT:    jae .LBB87_1
5097; X64-NEXT:  # %bb.2: # %return
5098; X64-NEXT:    retq
5099; X64-NEXT:  .LBB87_1: # %if.then
5100; X64-NEXT:    movl %esi, %eax
5101; X64-NEXT:    movl (%rdi,%rax,4), %eax
5102; X64-NEXT:    retq
5103entry:
5104  %shl = shl nuw i32 1, %c
5105  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
5106  %rem = and i32 %c, 31
5107  %shl1 = shl nuw i32 1, %rem
5108  %and = and i32 %shl1, %0
5109  %tobool.not = icmp eq i32 %and, 0
5110  br i1 %tobool.not, label %if.then, label %return
5111
5112if.then:                                          ; preds = %entry
5113  %conv = zext i32 %c to i64
5114  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
5115  %1 = load i32, ptr %arrayidx, align 4
5116  br label %return
5117
5118return:                                           ; preds = %entry, %if.then
5119  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
5120  ret i32 %retval.0
5121}
5122
5123define i32 @atomic_shl1_mask01_or_32_gpr_brz(ptr %v, i32 %c) nounwind {
5124; X86-LABEL: atomic_shl1_mask01_or_32_gpr_brz:
5125; X86:       # %bb.0: # %entry
5126; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5127; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5128; X86-NEXT:    movl %ecx, %eax
5129; X86-NEXT:    andl $31, %eax
5130; X86-NEXT:    lock btsl %eax, (%edx)
5131; X86-NEXT:    movl $123, %eax
5132; X86-NEXT:    jae .LBB88_1
5133; X86-NEXT:  # %bb.2: # %return
5134; X86-NEXT:    retl
5135; X86-NEXT:  .LBB88_1: # %if.then
5136; X86-NEXT:    movl (%edx,%ecx,4), %eax
5137; X86-NEXT:    retl
5138;
5139; X64-LABEL: atomic_shl1_mask01_or_32_gpr_brz:
5140; X64:       # %bb.0: # %entry
5141; X64-NEXT:    movl %esi, %eax
5142; X64-NEXT:    andl $31, %eax
5143; X64-NEXT:    lock btsl %eax, (%rdi)
5144; X64-NEXT:    movl $123, %eax
5145; X64-NEXT:    jae .LBB88_1
5146; X64-NEXT:  # %bb.2: # %return
5147; X64-NEXT:    retq
5148; X64-NEXT:  .LBB88_1: # %if.then
5149; X64-NEXT:    movl %esi, %eax
5150; X64-NEXT:    movl (%rdi,%rax,4), %eax
5151; X64-NEXT:    retq
5152entry:
5153  %rem = and i32 %c, 31
5154  %shl = shl nuw i32 1, %rem
5155  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
5156  %and = and i32 %0, %shl
5157  %tobool.not = icmp eq i32 %and, 0
5158  br i1 %tobool.not, label %if.then, label %return
5159
5160if.then:                                          ; preds = %entry
5161  %conv = zext i32 %c to i64
5162  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
5163  %1 = load i32, ptr %arrayidx, align 4
5164  br label %return
5165
5166return:                                           ; preds = %entry, %if.then
5167  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
5168  ret i32 %retval.0
5169}
5170
5171define i32 @atomic_blsi_or_32_gpr_brz(ptr %v, i32 %c) nounwind {
5172; X86-LABEL: atomic_blsi_or_32_gpr_brz:
5173; X86:       # %bb.0: # %entry
5174; X86-NEXT:    pushl %edi
5175; X86-NEXT:    pushl %esi
5176; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5177; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
5178; X86-NEXT:    movl %edx, %edi
5179; X86-NEXT:    negl %edi
5180; X86-NEXT:    andl %edx, %edi
5181; X86-NEXT:    movl (%esi), %eax
5182; X86-NEXT:    .p2align 4
5183; X86-NEXT:  .LBB89_1: # %atomicrmw.start
5184; X86-NEXT:    # =>This Inner Loop Header: Depth=1
5185; X86-NEXT:    movl %eax, %ecx
5186; X86-NEXT:    orl %edi, %ecx
5187; X86-NEXT:    lock cmpxchgl %ecx, (%esi)
5188; X86-NEXT:    jne .LBB89_1
5189; X86-NEXT:  # %bb.2: # %atomicrmw.end
5190; X86-NEXT:    movl $123, %ecx
5191; X86-NEXT:    testl %edi, %eax
5192; X86-NEXT:    jne .LBB89_4
5193; X86-NEXT:  # %bb.3: # %if.then
5194; X86-NEXT:    movl (%esi,%edx,4), %ecx
5195; X86-NEXT:  .LBB89_4: # %return
5196; X86-NEXT:    movl %ecx, %eax
5197; X86-NEXT:    popl %esi
5198; X86-NEXT:    popl %edi
5199; X86-NEXT:    retl
5200;
5201; X64-LABEL: atomic_blsi_or_32_gpr_brz:
5202; X64:       # %bb.0: # %entry
5203; X64-NEXT:    movl %esi, %edx
5204; X64-NEXT:    negl %edx
5205; X64-NEXT:    andl %esi, %edx
5206; X64-NEXT:    movl (%rdi), %eax
5207; X64-NEXT:    .p2align 4
5208; X64-NEXT:  .LBB89_1: # %atomicrmw.start
5209; X64-NEXT:    # =>This Inner Loop Header: Depth=1
5210; X64-NEXT:    movl %eax, %ecx
5211; X64-NEXT:    orl %edx, %ecx
5212; X64-NEXT:    lock cmpxchgl %ecx, (%rdi)
5213; X64-NEXT:    jne .LBB89_1
5214; X64-NEXT:  # %bb.2: # %atomicrmw.end
5215; X64-NEXT:    movl $123, %ecx
5216; X64-NEXT:    testl %edx, %eax
5217; X64-NEXT:    je .LBB89_3
5218; X64-NEXT:  # %bb.4: # %return
5219; X64-NEXT:    movl %ecx, %eax
5220; X64-NEXT:    retq
5221; X64-NEXT:  .LBB89_3: # %if.then
5222; X64-NEXT:    movl %esi, %eax
5223; X64-NEXT:    movl (%rdi,%rax,4), %ecx
5224; X64-NEXT:    movl %ecx, %eax
5225; X64-NEXT:    retq
5226entry:
5227  %sub = sub i32 0, %c
5228  %and = and i32 %sub, %c
5229  %0 = atomicrmw or ptr %v, i32 %and monotonic, align 4
5230  %and3 = and i32 %0, %and
5231  %tobool.not = icmp eq i32 %and3, 0
5232  br i1 %tobool.not, label %if.then, label %return
5233
5234if.then:                                          ; preds = %entry
5235  %idxprom = zext i32 %c to i64
5236  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %idxprom
5237  %1 = load i32, ptr %arrayidx, align 4
5238  br label %return
5239
5240return:                                           ; preds = %entry, %if.then
5241  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
5242  ret i32 %retval.0
5243}
5244
5245define i32 @atomic_shl1_or_32_gpr_brnz(ptr %v, i32 %c) nounwind {
5246; X86-LABEL: atomic_shl1_or_32_gpr_brnz:
5247; X86:       # %bb.0: # %entry
5248; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
5249; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5250; X86-NEXT:    movl %eax, %edx
5251; X86-NEXT:    andl $31, %edx
5252; X86-NEXT:    lock btsl %edx, (%ecx)
5253; X86-NEXT:    jae .LBB90_1
5254; X86-NEXT:  # %bb.2: # %if.then
5255; X86-NEXT:    movl (%ecx,%eax,4), %eax
5256; X86-NEXT:    retl
5257; X86-NEXT:  .LBB90_1:
5258; X86-NEXT:    movl $123, %eax
5259; X86-NEXT:    retl
5260;
5261; X64-LABEL: atomic_shl1_or_32_gpr_brnz:
5262; X64:       # %bb.0: # %entry
5263; X64-NEXT:    movl %esi, %eax
5264; X64-NEXT:    andl $31, %eax
5265; X64-NEXT:    lock btsl %eax, (%rdi)
5266; X64-NEXT:    jae .LBB90_1
5267; X64-NEXT:  # %bb.2: # %if.then
5268; X64-NEXT:    movl %esi, %eax
5269; X64-NEXT:    movl (%rdi,%rax,4), %eax
5270; X64-NEXT:    retq
5271; X64-NEXT:  .LBB90_1:
5272; X64-NEXT:    movl $123, %eax
5273; X64-NEXT:    retq
5274entry:
5275  %shl = shl nuw i32 1, %c
5276  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
5277  %and = and i32 %shl, %0
5278  %tobool.not = icmp eq i32 %and, 0
5279  br i1 %tobool.not, label %return, label %if.then
5280
5281if.then:                                          ; preds = %entry
5282  %idxprom = zext i32 %c to i64
5283  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %idxprom
5284  %1 = load i32, ptr %arrayidx, align 4
5285  br label %return
5286
5287return:                                           ; preds = %entry, %if.then
5288  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
5289  ret i32 %retval.0
5290}
5291
5292define i32 @atomic_shl1_small_mask_or_32_gpr_brnz(ptr %v, i32 %c) nounwind {
5293; X86-LABEL: atomic_shl1_small_mask_or_32_gpr_brnz:
5294; X86:       # %bb.0: # %entry
5295; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
5296; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5297; X86-NEXT:    andl $15, %ecx
5298; X86-NEXT:    lock btsl %ecx, (%eax)
5299; X86-NEXT:    jae .LBB91_1
5300; X86-NEXT:  # %bb.2: # %if.then
5301; X86-NEXT:    movl (%eax,%ecx,4), %eax
5302; X86-NEXT:    retl
5303; X86-NEXT:  .LBB91_1:
5304; X86-NEXT:    movl $123, %eax
5305; X86-NEXT:    retl
5306;
5307; X64-LABEL: atomic_shl1_small_mask_or_32_gpr_brnz:
5308; X64:       # %bb.0: # %entry
5309; X64-NEXT:    andl $15, %esi
5310; X64-NEXT:    lock btsl %esi, (%rdi)
5311; X64-NEXT:    jae .LBB91_1
5312; X64-NEXT:  # %bb.2: # %if.then
5313; X64-NEXT:    movl %esi, %eax
5314; X64-NEXT:    movl (%rdi,%rax,4), %eax
5315; X64-NEXT:    retq
5316; X64-NEXT:  .LBB91_1:
5317; X64-NEXT:    movl $123, %eax
5318; X64-NEXT:    retq
5319entry:
5320  %0 = and i32 %c, 15
5321  %shl = shl nuw nsw i32 1, %0
5322  %1 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
5323  %and = and i32 %1, %shl
5324  %tobool.not = icmp eq i32 %and, 0
5325  br i1 %tobool.not, label %return, label %if.then
5326
5327if.then:                                          ; preds = %entry
5328  %conv2 = zext i32 %0 to i64
5329  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv2
5330  %2 = load i32, ptr %arrayidx, align 4
5331  br label %return
5332
5333return:                                           ; preds = %entry, %if.then
5334  %retval.0 = phi i32 [ %2, %if.then ], [ 123, %entry ]
5335  ret i32 %retval.0
5336}
5337
5338define i32 @atomic_shl1_mask0_or_32_gpr_brnz(ptr %v, i32 %c) nounwind {
5339; X86-LABEL: atomic_shl1_mask0_or_32_gpr_brnz:
5340; X86:       # %bb.0: # %entry
5341; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
5342; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5343; X86-NEXT:    movl %eax, %edx
5344; X86-NEXT:    andl $31, %edx
5345; X86-NEXT:    lock btsl %edx, (%ecx)
5346; X86-NEXT:    jae .LBB92_1
5347; X86-NEXT:  # %bb.2: # %if.then
5348; X86-NEXT:    movl (%ecx,%eax,4), %eax
5349; X86-NEXT:    retl
5350; X86-NEXT:  .LBB92_1:
5351; X86-NEXT:    movl $123, %eax
5352; X86-NEXT:    retl
5353;
5354; X64-LABEL: atomic_shl1_mask0_or_32_gpr_brnz:
5355; X64:       # %bb.0: # %entry
5356; X64-NEXT:    movl %esi, %eax
5357; X64-NEXT:    andl $31, %eax
5358; X64-NEXT:    lock btsl %eax, (%rdi)
5359; X64-NEXT:    jae .LBB92_1
5360; X64-NEXT:  # %bb.2: # %if.then
5361; X64-NEXT:    movl %esi, %eax
5362; X64-NEXT:    movl (%rdi,%rax,4), %eax
5363; X64-NEXT:    retq
5364; X64-NEXT:  .LBB92_1:
5365; X64-NEXT:    movl $123, %eax
5366; X64-NEXT:    retq
5367entry:
5368  %rem = and i32 %c, 31
5369  %shl = shl nuw i32 1, %rem
5370  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
5371  %shl1 = shl nuw i32 1, %c
5372  %and = and i32 %0, %shl1
5373  %tobool.not = icmp eq i32 %and, 0
5374  br i1 %tobool.not, label %return, label %if.then
5375
5376if.then:                                          ; preds = %entry
5377  %conv = zext i32 %c to i64
5378  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
5379  %1 = load i32, ptr %arrayidx, align 4
5380  br label %return
5381
5382return:                                           ; preds = %entry, %if.then
5383  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
5384  ret i32 %retval.0
5385}
5386
5387define i32 @atomic_shl1_mask1_or_32_gpr_brnz(ptr %v, i32 %c) nounwind {
5388; X86-LABEL: atomic_shl1_mask1_or_32_gpr_brnz:
5389; X86:       # %bb.0: # %entry
5390; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
5391; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5392; X86-NEXT:    movl %eax, %edx
5393; X86-NEXT:    andl $31, %edx
5394; X86-NEXT:    lock btsl %edx, (%ecx)
5395; X86-NEXT:    jae .LBB93_1
5396; X86-NEXT:  # %bb.2: # %if.then
5397; X86-NEXT:    movl (%ecx,%eax,4), %eax
5398; X86-NEXT:    retl
5399; X86-NEXT:  .LBB93_1:
5400; X86-NEXT:    movl $123, %eax
5401; X86-NEXT:    retl
5402;
5403; X64-LABEL: atomic_shl1_mask1_or_32_gpr_brnz:
5404; X64:       # %bb.0: # %entry
5405; X64-NEXT:    movl %esi, %eax
5406; X64-NEXT:    andl $31, %eax
5407; X64-NEXT:    lock btsl %eax, (%rdi)
5408; X64-NEXT:    jae .LBB93_1
5409; X64-NEXT:  # %bb.2: # %if.then
5410; X64-NEXT:    movl %esi, %eax
5411; X64-NEXT:    movl (%rdi,%rax,4), %eax
5412; X64-NEXT:    retq
5413; X64-NEXT:  .LBB93_1:
5414; X64-NEXT:    movl $123, %eax
5415; X64-NEXT:    retq
5416entry:
5417  %shl = shl nuw i32 1, %c
5418  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
5419  %rem = and i32 %c, 31
5420  %shl1 = shl nuw i32 1, %rem
5421  %and = and i32 %0, %shl1
5422  %tobool.not = icmp eq i32 %and, 0
5423  br i1 %tobool.not, label %return, label %if.then
5424
5425if.then:                                          ; preds = %entry
5426  %conv = zext i32 %c to i64
5427  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
5428  %1 = load i32, ptr %arrayidx, align 4
5429  br label %return
5430
5431return:                                           ; preds = %entry, %if.then
5432  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
5433  ret i32 %retval.0
5434}
5435
5436define i32 @atomic_shl1_mask01_or_32_gpr_brnz(ptr %v, i32 %c) nounwind {
5437; X86-LABEL: atomic_shl1_mask01_or_32_gpr_brnz:
5438; X86:       # %bb.0: # %entry
5439; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
5440; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5441; X86-NEXT:    movl %eax, %edx
5442; X86-NEXT:    andl $31, %edx
5443; X86-NEXT:    lock btsl %edx, (%ecx)
5444; X86-NEXT:    jae .LBB94_1
5445; X86-NEXT:  # %bb.2: # %if.then
5446; X86-NEXT:    movl (%ecx,%eax,4), %eax
5447; X86-NEXT:    retl
5448; X86-NEXT:  .LBB94_1:
5449; X86-NEXT:    movl $123, %eax
5450; X86-NEXT:    retl
5451;
5452; X64-LABEL: atomic_shl1_mask01_or_32_gpr_brnz:
5453; X64:       # %bb.0: # %entry
5454; X64-NEXT:    movl %esi, %eax
5455; X64-NEXT:    andl $31, %eax
5456; X64-NEXT:    lock btsl %eax, (%rdi)
5457; X64-NEXT:    jae .LBB94_1
5458; X64-NEXT:  # %bb.2: # %if.then
5459; X64-NEXT:    movl %esi, %eax
5460; X64-NEXT:    movl (%rdi,%rax,4), %eax
5461; X64-NEXT:    retq
5462; X64-NEXT:  .LBB94_1:
5463; X64-NEXT:    movl $123, %eax
5464; X64-NEXT:    retq
5465entry:
5466  %rem = and i32 %c, 31
5467  %shl = shl nuw i32 1, %rem
5468  %0 = atomicrmw or ptr %v, i32 %shl monotonic, align 4
5469  %and = and i32 %shl, %0
5470  %tobool.not = icmp eq i32 %and, 0
5471  br i1 %tobool.not, label %return, label %if.then
5472
5473if.then:                                          ; preds = %entry
5474  %conv = zext i32 %c to i64
5475  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
5476  %1 = load i32, ptr %arrayidx, align 4
5477  br label %return
5478
5479return:                                           ; preds = %entry, %if.then
5480  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
5481  ret i32 %retval.0
5482}
5483
5484define i32 @atomic_blsi_or_32_gpr_brnz(ptr %v, i32 %c) nounwind {
5485; X86-LABEL: atomic_blsi_or_32_gpr_brnz:
5486; X86:       # %bb.0: # %entry
5487; X86-NEXT:    pushl %edi
5488; X86-NEXT:    pushl %esi
5489; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5490; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5491; X86-NEXT:    movl %ecx, %esi
5492; X86-NEXT:    negl %esi
5493; X86-NEXT:    andl %ecx, %esi
5494; X86-NEXT:    movl (%edx), %eax
5495; X86-NEXT:    .p2align 4
5496; X86-NEXT:  .LBB95_1: # %atomicrmw.start
5497; X86-NEXT:    # =>This Inner Loop Header: Depth=1
5498; X86-NEXT:    movl %eax, %edi
5499; X86-NEXT:    orl %esi, %edi
5500; X86-NEXT:    lock cmpxchgl %edi, (%edx)
5501; X86-NEXT:    jne .LBB95_1
5502; X86-NEXT:  # %bb.2: # %atomicrmw.end
5503; X86-NEXT:    testl %esi, %eax
5504; X86-NEXT:    je .LBB95_3
5505; X86-NEXT:  # %bb.4: # %if.then
5506; X86-NEXT:    movl (%edx,%ecx,4), %eax
5507; X86-NEXT:    jmp .LBB95_5
5508; X86-NEXT:  .LBB95_3:
5509; X86-NEXT:    movl $123, %eax
5510; X86-NEXT:  .LBB95_5: # %return
5511; X86-NEXT:    popl %esi
5512; X86-NEXT:    popl %edi
5513; X86-NEXT:    retl
5514;
5515; X64-LABEL: atomic_blsi_or_32_gpr_brnz:
5516; X64:       # %bb.0: # %entry
5517; X64-NEXT:    movl %esi, %ecx
5518; X64-NEXT:    negl %ecx
5519; X64-NEXT:    andl %esi, %ecx
5520; X64-NEXT:    movl (%rdi), %eax
5521; X64-NEXT:    .p2align 4
5522; X64-NEXT:  .LBB95_1: # %atomicrmw.start
5523; X64-NEXT:    # =>This Inner Loop Header: Depth=1
5524; X64-NEXT:    movl %eax, %edx
5525; X64-NEXT:    orl %ecx, %edx
5526; X64-NEXT:    lock cmpxchgl %edx, (%rdi)
5527; X64-NEXT:    jne .LBB95_1
5528; X64-NEXT:  # %bb.2: # %atomicrmw.end
5529; X64-NEXT:    testl %ecx, %eax
5530; X64-NEXT:    je .LBB95_3
5531; X64-NEXT:  # %bb.4: # %if.then
5532; X64-NEXT:    movl %esi, %eax
5533; X64-NEXT:    movl (%rdi,%rax,4), %eax
5534; X64-NEXT:    retq
5535; X64-NEXT:  .LBB95_3:
5536; X64-NEXT:    movl $123, %eax
5537; X64-NEXT:    retq
5538entry:
5539  %sub = sub i32 0, %c
5540  %and = and i32 %sub, %c
5541  %0 = atomicrmw or ptr %v, i32 %and monotonic, align 4
5542  %and3 = and i32 %0, %and
5543  %tobool.not = icmp eq i32 %and3, 0
5544  br i1 %tobool.not, label %return, label %if.then
5545
5546if.then:                                          ; preds = %entry
5547  %idxprom = zext i32 %c to i64
5548  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %idxprom
5549  %1 = load i32, ptr %arrayidx, align 4
5550  br label %return
5551
5552return:                                           ; preds = %entry, %if.then
5553  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
5554  ret i32 %retval.0
5555}
5556
5557define i32 @atomic_shl1_and_32_gpr_valz(ptr %v, i32 %c) nounwind {
5558; X86-LABEL: atomic_shl1_and_32_gpr_valz:
5559; X86:       # %bb.0: # %entry
5560; X86-NEXT:    pushl %edi
5561; X86-NEXT:    pushl %esi
5562; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5563; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5564; X86-NEXT:    movl $1, %esi
5565; X86-NEXT:    shll %cl, %esi
5566; X86-NEXT:    movl (%edx), %eax
5567; X86-NEXT:    .p2align 4
5568; X86-NEXT:  .LBB96_1: # %atomicrmw.start
5569; X86-NEXT:    # =>This Inner Loop Header: Depth=1
5570; X86-NEXT:    movl %eax, %edi
5571; X86-NEXT:    andl %esi, %edi
5572; X86-NEXT:    lock cmpxchgl %edi, (%edx)
5573; X86-NEXT:    jne .LBB96_1
5574; X86-NEXT:  # %bb.2: # %atomicrmw.end
5575; X86-NEXT:    xorl %edx, %edx
5576; X86-NEXT:    btl %ecx, %eax
5577; X86-NEXT:    setae %dl
5578; X86-NEXT:    movl %edx, %eax
5579; X86-NEXT:    popl %esi
5580; X86-NEXT:    popl %edi
5581; X86-NEXT:    retl
5582;
5583; X64-LABEL: atomic_shl1_and_32_gpr_valz:
5584; X64:       # %bb.0: # %entry
5585; X64-NEXT:    movl %esi, %ecx
5586; X64-NEXT:    movl $1, %edx
5587; X64-NEXT:    shll %cl, %edx
5588; X64-NEXT:    movl (%rdi), %eax
5589; X64-NEXT:    .p2align 4
5590; X64-NEXT:  .LBB96_1: # %atomicrmw.start
5591; X64-NEXT:    # =>This Inner Loop Header: Depth=1
5592; X64-NEXT:    movl %eax, %esi
5593; X64-NEXT:    andl %edx, %esi
5594; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
5595; X64-NEXT:    jne .LBB96_1
5596; X64-NEXT:  # %bb.2: # %atomicrmw.end
5597; X64-NEXT:    xorl %edx, %edx
5598; X64-NEXT:    btl %ecx, %eax
5599; X64-NEXT:    setae %dl
5600; X64-NEXT:    movl %edx, %eax
5601; X64-NEXT:    retq
5602entry:
5603  %shl = shl nuw i32 1, %c
5604  %0 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
5605  %1 = xor i32 %0, -1
5606  %2 = lshr i32 %1, %c
5607  %lnot.ext = and i32 %2, 1
5608  ret i32 %lnot.ext
5609}
5610
5611define i32 @atomic_shl1_small_mask_and_32_gpr_valz(ptr %v, i32 %c) nounwind {
5612; X86-LABEL: atomic_shl1_small_mask_and_32_gpr_valz:
5613; X86:       # %bb.0: # %entry
5614; X86-NEXT:    pushl %edi
5615; X86-NEXT:    pushl %esi
5616; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5617; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5618; X86-NEXT:    andl $15, %ecx
5619; X86-NEXT:    movl $1, %esi
5620; X86-NEXT:    shll %cl, %esi
5621; X86-NEXT:    movl (%edx), %eax
5622; X86-NEXT:    .p2align 4
5623; X86-NEXT:  .LBB97_1: # %atomicrmw.start
5624; X86-NEXT:    # =>This Inner Loop Header: Depth=1
5625; X86-NEXT:    movl %eax, %edi
5626; X86-NEXT:    andl %esi, %edi
5627; X86-NEXT:    lock cmpxchgl %edi, (%edx)
5628; X86-NEXT:    jne .LBB97_1
5629; X86-NEXT:  # %bb.2: # %atomicrmw.end
5630; X86-NEXT:    xorl %edx, %edx
5631; X86-NEXT:    btl %ecx, %eax
5632; X86-NEXT:    setae %dl
5633; X86-NEXT:    movl %edx, %eax
5634; X86-NEXT:    popl %esi
5635; X86-NEXT:    popl %edi
5636; X86-NEXT:    retl
5637;
5638; X64-LABEL: atomic_shl1_small_mask_and_32_gpr_valz:
5639; X64:       # %bb.0: # %entry
5640; X64-NEXT:    movl %esi, %ecx
5641; X64-NEXT:    andl $15, %ecx
5642; X64-NEXT:    movl $1, %edx
5643; X64-NEXT:    shll %cl, %edx
5644; X64-NEXT:    movl (%rdi), %eax
5645; X64-NEXT:    .p2align 4
5646; X64-NEXT:  .LBB97_1: # %atomicrmw.start
5647; X64-NEXT:    # =>This Inner Loop Header: Depth=1
5648; X64-NEXT:    movl %eax, %esi
5649; X64-NEXT:    andl %edx, %esi
5650; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
5651; X64-NEXT:    jne .LBB97_1
5652; X64-NEXT:  # %bb.2: # %atomicrmw.end
5653; X64-NEXT:    xorl %edx, %edx
5654; X64-NEXT:    btl %ecx, %eax
5655; X64-NEXT:    setae %dl
5656; X64-NEXT:    movl %edx, %eax
5657; X64-NEXT:    retq
5658entry:
5659  %0 = and i32 %c, 15
5660  %shl = shl nuw nsw i32 1, %0
5661  %1 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
5662  %2 = xor i32 %1, -1
5663  %3 = lshr i32 %2, %0
5664  %lnot.ext = and i32 %3, 1
5665  ret i32 %lnot.ext
5666}
5667
5668define i32 @atomic_shl1_mask0_and_32_gpr_valz(ptr %v, i32 %c) nounwind {
5669; X86-LABEL: atomic_shl1_mask0_and_32_gpr_valz:
5670; X86:       # %bb.0: # %entry
5671; X86-NEXT:    pushl %edi
5672; X86-NEXT:    pushl %esi
5673; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5674; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5675; X86-NEXT:    movl $1, %esi
5676; X86-NEXT:    shll %cl, %esi
5677; X86-NEXT:    movl (%edx), %eax
5678; X86-NEXT:    .p2align 4
5679; X86-NEXT:  .LBB98_1: # %atomicrmw.start
5680; X86-NEXT:    # =>This Inner Loop Header: Depth=1
5681; X86-NEXT:    movl %eax, %edi
5682; X86-NEXT:    andl %esi, %edi
5683; X86-NEXT:    lock cmpxchgl %edi, (%edx)
5684; X86-NEXT:    jne .LBB98_1
5685; X86-NEXT:  # %bb.2: # %atomicrmw.end
5686; X86-NEXT:    xorl %edx, %edx
5687; X86-NEXT:    btl %ecx, %eax
5688; X86-NEXT:    setae %dl
5689; X86-NEXT:    movl %edx, %eax
5690; X86-NEXT:    popl %esi
5691; X86-NEXT:    popl %edi
5692; X86-NEXT:    retl
5693;
5694; X64-LABEL: atomic_shl1_mask0_and_32_gpr_valz:
5695; X64:       # %bb.0: # %entry
5696; X64-NEXT:    movl %esi, %ecx
5697; X64-NEXT:    movl $1, %edx
5698; X64-NEXT:    shll %cl, %edx
5699; X64-NEXT:    movl (%rdi), %eax
5700; X64-NEXT:    .p2align 4
5701; X64-NEXT:  .LBB98_1: # %atomicrmw.start
5702; X64-NEXT:    # =>This Inner Loop Header: Depth=1
5703; X64-NEXT:    movl %eax, %esi
5704; X64-NEXT:    andl %edx, %esi
5705; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
5706; X64-NEXT:    jne .LBB98_1
5707; X64-NEXT:  # %bb.2: # %atomicrmw.end
5708; X64-NEXT:    xorl %edx, %edx
5709; X64-NEXT:    btl %ecx, %eax
5710; X64-NEXT:    setae %dl
5711; X64-NEXT:    movl %edx, %eax
5712; X64-NEXT:    retq
5713entry:
5714  %0 = and i32 %c, 31
5715  %shl = shl nuw i32 1, %0
5716  %1 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
5717  %2 = xor i32 %1, -1
5718  %3 = lshr i32 %2, %c
5719  %lnot.ext = and i32 %3, 1
5720  ret i32 %lnot.ext
5721}
5722
5723define i32 @atomic_shl1_mask1_and_32_gpr_valz(ptr %v, i32 %c) nounwind {
5724; X86-LABEL: atomic_shl1_mask1_and_32_gpr_valz:
5725; X86:       # %bb.0: # %entry
5726; X86-NEXT:    pushl %edi
5727; X86-NEXT:    pushl %esi
5728; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5729; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5730; X86-NEXT:    movl $1, %esi
5731; X86-NEXT:    shll %cl, %esi
5732; X86-NEXT:    movl (%edx), %eax
5733; X86-NEXT:    .p2align 4
5734; X86-NEXT:  .LBB99_1: # %atomicrmw.start
5735; X86-NEXT:    # =>This Inner Loop Header: Depth=1
5736; X86-NEXT:    movl %eax, %edi
5737; X86-NEXT:    andl %esi, %edi
5738; X86-NEXT:    lock cmpxchgl %edi, (%edx)
5739; X86-NEXT:    jne .LBB99_1
5740; X86-NEXT:  # %bb.2: # %atomicrmw.end
5741; X86-NEXT:    xorl %edx, %edx
5742; X86-NEXT:    btl %ecx, %eax
5743; X86-NEXT:    setae %dl
5744; X86-NEXT:    movl %edx, %eax
5745; X86-NEXT:    popl %esi
5746; X86-NEXT:    popl %edi
5747; X86-NEXT:    retl
5748;
5749; X64-LABEL: atomic_shl1_mask1_and_32_gpr_valz:
5750; X64:       # %bb.0: # %entry
5751; X64-NEXT:    movl %esi, %ecx
5752; X64-NEXT:    movl $1, %edx
5753; X64-NEXT:    shll %cl, %edx
5754; X64-NEXT:    movl (%rdi), %eax
5755; X64-NEXT:    .p2align 4
5756; X64-NEXT:  .LBB99_1: # %atomicrmw.start
5757; X64-NEXT:    # =>This Inner Loop Header: Depth=1
5758; X64-NEXT:    movl %eax, %esi
5759; X64-NEXT:    andl %edx, %esi
5760; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
5761; X64-NEXT:    jne .LBB99_1
5762; X64-NEXT:  # %bb.2: # %atomicrmw.end
5763; X64-NEXT:    xorl %edx, %edx
5764; X64-NEXT:    btl %ecx, %eax
5765; X64-NEXT:    setae %dl
5766; X64-NEXT:    movl %edx, %eax
5767; X64-NEXT:    retq
5768entry:
5769  %shl = shl nuw i32 1, %c
5770  %0 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
5771  %1 = and i32 %c, 31
5772  %2 = xor i32 -1, %0
5773  %3 = lshr i32 %2, %1
5774  %lnot.ext = and i32 %3, 1
5775  ret i32 %lnot.ext
5776}
5777
5778define i32 @atomic_shl1_mask01_and_32_gpr_valz(ptr %v, i32 %c) nounwind {
5779; X86-LABEL: atomic_shl1_mask01_and_32_gpr_valz:
5780; X86:       # %bb.0: # %entry
5781; X86-NEXT:    pushl %edi
5782; X86-NEXT:    pushl %esi
5783; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5784; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5785; X86-NEXT:    andl $31, %ecx
5786; X86-NEXT:    movl $1, %esi
5787; X86-NEXT:    shll %cl, %esi
5788; X86-NEXT:    movl (%edx), %eax
5789; X86-NEXT:    .p2align 4
5790; X86-NEXT:  .LBB100_1: # %atomicrmw.start
5791; X86-NEXT:    # =>This Inner Loop Header: Depth=1
5792; X86-NEXT:    movl %eax, %edi
5793; X86-NEXT:    andl %esi, %edi
5794; X86-NEXT:    lock cmpxchgl %edi, (%edx)
5795; X86-NEXT:    jne .LBB100_1
5796; X86-NEXT:  # %bb.2: # %atomicrmw.end
5797; X86-NEXT:    xorl %edx, %edx
5798; X86-NEXT:    btl %ecx, %eax
5799; X86-NEXT:    setae %dl
5800; X86-NEXT:    movl %edx, %eax
5801; X86-NEXT:    popl %esi
5802; X86-NEXT:    popl %edi
5803; X86-NEXT:    retl
5804;
5805; X64-LABEL: atomic_shl1_mask01_and_32_gpr_valz:
5806; X64:       # %bb.0: # %entry
5807; X64-NEXT:    movl %esi, %ecx
5808; X64-NEXT:    andl $31, %ecx
5809; X64-NEXT:    movl $1, %edx
5810; X64-NEXT:    shll %cl, %edx
5811; X64-NEXT:    movl (%rdi), %eax
5812; X64-NEXT:    .p2align 4
5813; X64-NEXT:  .LBB100_1: # %atomicrmw.start
5814; X64-NEXT:    # =>This Inner Loop Header: Depth=1
5815; X64-NEXT:    movl %eax, %esi
5816; X64-NEXT:    andl %edx, %esi
5817; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
5818; X64-NEXT:    jne .LBB100_1
5819; X64-NEXT:  # %bb.2: # %atomicrmw.end
5820; X64-NEXT:    xorl %edx, %edx
5821; X64-NEXT:    btl %ecx, %eax
5822; X64-NEXT:    setae %dl
5823; X64-NEXT:    movl %edx, %eax
5824; X64-NEXT:    retq
5825entry:
5826  %0 = and i32 %c, 31
5827  %shl = shl nuw i32 1, %0
5828  %1 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
5829  %2 = xor i32 %1, -1
5830  %3 = lshr i32 %2, %0
5831  %lnot.ext = and i32 %3, 1
5832  ret i32 %lnot.ext
5833}
5834
5835define i32 @atomic_blsi_and_32_gpr_valz(ptr %v, i32 %c) nounwind {
5836; X86-LABEL: atomic_blsi_and_32_gpr_valz:
5837; X86:       # %bb.0: # %entry
5838; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5839; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
5840; X86-NEXT:    movl %eax, %edx
5841; X86-NEXT:    negl %edx
5842; X86-NEXT:    andl %eax, %edx
5843; X86-NEXT:    xorl %eax, %eax
5844; X86-NEXT:    lock andl %edx, (%ecx)
5845; X86-NEXT:    sete %al
5846; X86-NEXT:    retl
5847;
5848; X64-LABEL: atomic_blsi_and_32_gpr_valz:
5849; X64:       # %bb.0: # %entry
5850; X64-NEXT:    movl %esi, %ecx
5851; X64-NEXT:    negl %ecx
5852; X64-NEXT:    andl %esi, %ecx
5853; X64-NEXT:    xorl %eax, %eax
5854; X64-NEXT:    lock andl %ecx, (%rdi)
5855; X64-NEXT:    sete %al
5856; X64-NEXT:    retq
5857entry:
5858  %sub = sub i32 0, %c
5859  %and = and i32 %sub, %c
5860  %0 = atomicrmw and ptr %v, i32 %and monotonic, align 4
5861  %and3 = and i32 %0, %and
5862  %tobool.not = icmp eq i32 %and3, 0
5863  %lnot.ext = zext i1 %tobool.not to i32
5864  ret i32 %lnot.ext
5865}
5866
5867define i32 @atomic_shl1_and_32_gpr_br(ptr %v, i32 %c) nounwind {
5868; X86-LABEL: atomic_shl1_and_32_gpr_br:
5869; X86:       # %bb.0: # %entry
5870; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5871; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5872; X86-NEXT:    movl $1, %eax
5873; X86-NEXT:    shll %cl, %eax
5874; X86-NEXT:    lock andl %eax, (%edx)
5875; X86-NEXT:    movl $123, %eax
5876; X86-NEXT:    je .LBB102_2
5877; X86-NEXT:  # %bb.1: # %if.then
5878; X86-NEXT:    movl (%edx,%ecx,4), %eax
5879; X86-NEXT:  .LBB102_2: # %return
5880; X86-NEXT:    retl
5881;
5882; X64-LABEL: atomic_shl1_and_32_gpr_br:
5883; X64:       # %bb.0: # %entry
5884; X64-NEXT:    movl %esi, %ecx
5885; X64-NEXT:    movl $1, %eax
5886; X64-NEXT:    shll %cl, %eax
5887; X64-NEXT:    lock andl %eax, (%rdi)
5888; X64-NEXT:    movl $123, %eax
5889; X64-NEXT:    je .LBB102_2
5890; X64-NEXT:  # %bb.1: # %if.then
5891; X64-NEXT:    movl %ecx, %eax
5892; X64-NEXT:    movl (%rdi,%rax,4), %eax
5893; X64-NEXT:  .LBB102_2: # %return
5894; X64-NEXT:    retq
5895entry:
5896  %shl = shl nuw i32 1, %c
5897  %0 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
5898  %and = and i32 %0, %shl
5899  %tobool.not = icmp eq i32 %and, 0
5900  br i1 %tobool.not, label %return, label %if.then
5901
5902if.then:                                          ; preds = %entry
5903  %idxprom = zext i32 %c to i64
5904  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %idxprom
5905  %1 = load i32, ptr %arrayidx, align 4
5906  br label %return
5907
5908return:                                           ; preds = %entry, %if.then
5909  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
5910  ret i32 %retval.0
5911}
5912
5913define i32 @atomic_shl1_small_mask_and_32_gpr_br(ptr %v, i32 %c) nounwind {
5914; X86-LABEL: atomic_shl1_small_mask_and_32_gpr_br:
5915; X86:       # %bb.0: # %entry
5916; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5917; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5918; X86-NEXT:    andl $15, %ecx
5919; X86-NEXT:    movl $1, %eax
5920; X86-NEXT:    shll %cl, %eax
5921; X86-NEXT:    lock andl %eax, (%edx)
5922; X86-NEXT:    movl $123, %eax
5923; X86-NEXT:    je .LBB103_2
5924; X86-NEXT:  # %bb.1: # %if.then
5925; X86-NEXT:    movl (%edx,%ecx,4), %eax
5926; X86-NEXT:  .LBB103_2: # %return
5927; X86-NEXT:    retl
5928;
5929; X64-LABEL: atomic_shl1_small_mask_and_32_gpr_br:
5930; X64:       # %bb.0: # %entry
5931; X64-NEXT:    movl %esi, %ecx
5932; X64-NEXT:    andl $15, %ecx
5933; X64-NEXT:    movl $1, %eax
5934; X64-NEXT:    shll %cl, %eax
5935; X64-NEXT:    lock andl %eax, (%rdi)
5936; X64-NEXT:    movl $123, %eax
5937; X64-NEXT:    je .LBB103_2
5938; X64-NEXT:  # %bb.1: # %if.then
5939; X64-NEXT:    movl %ecx, %eax
5940; X64-NEXT:    movl (%rdi,%rax,4), %eax
5941; X64-NEXT:  .LBB103_2: # %return
5942; X64-NEXT:    retq
5943entry:
5944  %0 = and i32 %c, 15
5945  %shl = shl nuw nsw i32 1, %0
5946  %1 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
5947  %and = and i32 %1, %shl
5948  %tobool.not = icmp eq i32 %and, 0
5949  br i1 %tobool.not, label %return, label %if.then
5950
5951if.then:                                          ; preds = %entry
5952  %conv2 = zext i32 %0 to i64
5953  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv2
5954  %2 = load i32, ptr %arrayidx, align 4
5955  br label %return
5956
5957return:                                           ; preds = %entry, %if.then
5958  %retval.0 = phi i32 [ %2, %if.then ], [ 123, %entry ]
5959  ret i32 %retval.0
5960}
5961
5962define i32 @atomic_shl1_mask0_and_32_gpr_br(ptr %v, i32 %c) nounwind {
5963; X86-LABEL: atomic_shl1_mask0_and_32_gpr_br:
5964; X86:       # %bb.0: # %entry
5965; X86-NEXT:    pushl %edi
5966; X86-NEXT:    pushl %esi
5967; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
5968; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
5969; X86-NEXT:    movl $1, %esi
5970; X86-NEXT:    shll %cl, %esi
5971; X86-NEXT:    movl (%edx), %eax
5972; X86-NEXT:    .p2align 4
5973; X86-NEXT:  .LBB104_1: # %atomicrmw.start
5974; X86-NEXT:    # =>This Inner Loop Header: Depth=1
5975; X86-NEXT:    movl %eax, %edi
5976; X86-NEXT:    andl %esi, %edi
5977; X86-NEXT:    lock cmpxchgl %edi, (%edx)
5978; X86-NEXT:    jne .LBB104_1
5979; X86-NEXT:  # %bb.2: # %atomicrmw.end
5980; X86-NEXT:    btl %ecx, %eax
5981; X86-NEXT:    jae .LBB104_3
5982; X86-NEXT:  # %bb.4: # %if.then
5983; X86-NEXT:    movl (%edx,%ecx,4), %eax
5984; X86-NEXT:    jmp .LBB104_5
5985; X86-NEXT:  .LBB104_3:
5986; X86-NEXT:    movl $123, %eax
5987; X86-NEXT:  .LBB104_5: # %return
5988; X86-NEXT:    popl %esi
5989; X86-NEXT:    popl %edi
5990; X86-NEXT:    retl
5991;
5992; X64-LABEL: atomic_shl1_mask0_and_32_gpr_br:
5993; X64:       # %bb.0: # %entry
5994; X64-NEXT:    movl %esi, %ecx
5995; X64-NEXT:    movl $1, %edx
5996; X64-NEXT:    shll %cl, %edx
5997; X64-NEXT:    movl (%rdi), %eax
5998; X64-NEXT:    .p2align 4
5999; X64-NEXT:  .LBB104_1: # %atomicrmw.start
6000; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6001; X64-NEXT:    movl %eax, %esi
6002; X64-NEXT:    andl %edx, %esi
6003; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
6004; X64-NEXT:    jne .LBB104_1
6005; X64-NEXT:  # %bb.2: # %atomicrmw.end
6006; X64-NEXT:    btl %ecx, %eax
6007; X64-NEXT:    jae .LBB104_3
6008; X64-NEXT:  # %bb.4: # %if.then
6009; X64-NEXT:    movl %ecx, %eax
6010; X64-NEXT:    movl (%rdi,%rax,4), %eax
6011; X64-NEXT:    retq
6012; X64-NEXT:  .LBB104_3:
6013; X64-NEXT:    movl $123, %eax
6014; X64-NEXT:    retq
6015entry:
6016  %rem = and i32 %c, 31
6017  %shl = shl nuw i32 1, %rem
6018  %0 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
6019  %shl1 = shl nuw i32 1, %c
6020  %and = and i32 %shl1, %0
6021  %tobool.not = icmp eq i32 %and, 0
6022  br i1 %tobool.not, label %return, label %if.then
6023
6024if.then:                                          ; preds = %entry
6025  %conv = zext i32 %c to i64
6026  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
6027  %1 = load i32, ptr %arrayidx, align 4
6028  br label %return
6029
6030return:                                           ; preds = %entry, %if.then
6031  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6032  ret i32 %retval.0
6033}
6034
6035define i32 @atomic_shl1_mask1_and_32_gpr_br(ptr %v, i32 %c) nounwind {
6036; X86-LABEL: atomic_shl1_mask1_and_32_gpr_br:
6037; X86:       # %bb.0: # %entry
6038; X86-NEXT:    pushl %edi
6039; X86-NEXT:    pushl %esi
6040; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6041; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
6042; X86-NEXT:    movl $1, %esi
6043; X86-NEXT:    shll %cl, %esi
6044; X86-NEXT:    movl (%edx), %eax
6045; X86-NEXT:    .p2align 4
6046; X86-NEXT:  .LBB105_1: # %atomicrmw.start
6047; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6048; X86-NEXT:    movl %eax, %edi
6049; X86-NEXT:    andl %esi, %edi
6050; X86-NEXT:    lock cmpxchgl %edi, (%edx)
6051; X86-NEXT:    jne .LBB105_1
6052; X86-NEXT:  # %bb.2: # %atomicrmw.end
6053; X86-NEXT:    btl %ecx, %eax
6054; X86-NEXT:    jae .LBB105_3
6055; X86-NEXT:  # %bb.4: # %if.then
6056; X86-NEXT:    movl (%edx,%ecx,4), %eax
6057; X86-NEXT:    jmp .LBB105_5
6058; X86-NEXT:  .LBB105_3:
6059; X86-NEXT:    movl $123, %eax
6060; X86-NEXT:  .LBB105_5: # %return
6061; X86-NEXT:    popl %esi
6062; X86-NEXT:    popl %edi
6063; X86-NEXT:    retl
6064;
6065; X64-LABEL: atomic_shl1_mask1_and_32_gpr_br:
6066; X64:       # %bb.0: # %entry
6067; X64-NEXT:    movl %esi, %ecx
6068; X64-NEXT:    movl $1, %edx
6069; X64-NEXT:    shll %cl, %edx
6070; X64-NEXT:    movl (%rdi), %eax
6071; X64-NEXT:    .p2align 4
6072; X64-NEXT:  .LBB105_1: # %atomicrmw.start
6073; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6074; X64-NEXT:    movl %eax, %esi
6075; X64-NEXT:    andl %edx, %esi
6076; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
6077; X64-NEXT:    jne .LBB105_1
6078; X64-NEXT:  # %bb.2: # %atomicrmw.end
6079; X64-NEXT:    btl %ecx, %eax
6080; X64-NEXT:    jae .LBB105_3
6081; X64-NEXT:  # %bb.4: # %if.then
6082; X64-NEXT:    movl %ecx, %eax
6083; X64-NEXT:    movl (%rdi,%rax,4), %eax
6084; X64-NEXT:    retq
6085; X64-NEXT:  .LBB105_3:
6086; X64-NEXT:    movl $123, %eax
6087; X64-NEXT:    retq
6088entry:
6089  %shl = shl nuw i32 1, %c
6090  %0 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
6091  %rem = and i32 %c, 31
6092  %shl1 = shl nuw i32 1, %rem
6093  %and = and i32 %0, %shl1
6094  %tobool.not = icmp eq i32 %and, 0
6095  br i1 %tobool.not, label %return, label %if.then
6096
6097if.then:                                          ; preds = %entry
6098  %conv = zext i32 %c to i64
6099  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
6100  %1 = load i32, ptr %arrayidx, align 4
6101  br label %return
6102
6103return:                                           ; preds = %entry, %if.then
6104  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6105  ret i32 %retval.0
6106}
6107
6108define i32 @atomic_shl1_mask01_and_32_gpr_br(ptr %v, i32 %c) nounwind {
6109; X86-LABEL: atomic_shl1_mask01_and_32_gpr_br:
6110; X86:       # %bb.0: # %entry
6111; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6112; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
6113; X86-NEXT:    movl $1, %eax
6114; X86-NEXT:    shll %cl, %eax
6115; X86-NEXT:    lock andl %eax, (%edx)
6116; X86-NEXT:    movl $123, %eax
6117; X86-NEXT:    je .LBB106_2
6118; X86-NEXT:  # %bb.1: # %if.then
6119; X86-NEXT:    movl (%edx,%ecx,4), %eax
6120; X86-NEXT:  .LBB106_2: # %return
6121; X86-NEXT:    retl
6122;
6123; X64-LABEL: atomic_shl1_mask01_and_32_gpr_br:
6124; X64:       # %bb.0: # %entry
6125; X64-NEXT:    movl %esi, %ecx
6126; X64-NEXT:    movl $1, %eax
6127; X64-NEXT:    shll %cl, %eax
6128; X64-NEXT:    lock andl %eax, (%rdi)
6129; X64-NEXT:    movl $123, %eax
6130; X64-NEXT:    je .LBB106_2
6131; X64-NEXT:  # %bb.1: # %if.then
6132; X64-NEXT:    movl %ecx, %eax
6133; X64-NEXT:    movl (%rdi,%rax,4), %eax
6134; X64-NEXT:  .LBB106_2: # %return
6135; X64-NEXT:    retq
6136entry:
6137  %rem = and i32 %c, 31
6138  %shl = shl nuw i32 1, %rem
6139  %0 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
6140  %and = and i32 %0, %shl
6141  %tobool.not = icmp eq i32 %and, 0
6142  br i1 %tobool.not, label %return, label %if.then
6143
6144if.then:                                          ; preds = %entry
6145  %conv = zext i32 %c to i64
6146  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
6147  %1 = load i32, ptr %arrayidx, align 4
6148  br label %return
6149
6150return:                                           ; preds = %entry, %if.then
6151  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6152  ret i32 %retval.0
6153}
6154
6155define i32 @atomic_blsi_and_32_gpr_br(ptr %v, i32 %c) nounwind {
6156; X86-LABEL: atomic_blsi_and_32_gpr_br:
6157; X86:       # %bb.0: # %entry
6158; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6159; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
6160; X86-NEXT:    movl %ecx, %eax
6161; X86-NEXT:    negl %eax
6162; X86-NEXT:    andl %ecx, %eax
6163; X86-NEXT:    lock andl %eax, (%edx)
6164; X86-NEXT:    movl $123, %eax
6165; X86-NEXT:    je .LBB107_2
6166; X86-NEXT:  # %bb.1: # %if.then
6167; X86-NEXT:    movl (%edx,%ecx,4), %eax
6168; X86-NEXT:  .LBB107_2: # %return
6169; X86-NEXT:    retl
6170;
6171; X64-LABEL: atomic_blsi_and_32_gpr_br:
6172; X64:       # %bb.0: # %entry
6173; X64-NEXT:    movl %esi, %eax
6174; X64-NEXT:    negl %eax
6175; X64-NEXT:    andl %esi, %eax
6176; X64-NEXT:    lock andl %eax, (%rdi)
6177; X64-NEXT:    movl $123, %eax
6178; X64-NEXT:    je .LBB107_2
6179; X64-NEXT:  # %bb.1: # %if.then
6180; X64-NEXT:    movl %esi, %eax
6181; X64-NEXT:    movl (%rdi,%rax,4), %eax
6182; X64-NEXT:  .LBB107_2: # %return
6183; X64-NEXT:    retq
6184entry:
6185  %sub = sub i32 0, %c
6186  %and = and i32 %sub, %c
6187  %0 = atomicrmw and ptr %v, i32 %and monotonic, align 4
6188  %and3 = and i32 %and, %0
6189  %tobool.not = icmp eq i32 %and3, 0
6190  br i1 %tobool.not, label %return, label %if.then
6191
6192if.then:                                          ; preds = %entry
6193  %idxprom = zext i32 %c to i64
6194  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %idxprom
6195  %1 = load i32, ptr %arrayidx, align 4
6196  br label %return
6197
6198return:                                           ; preds = %entry, %if.then
6199  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6200  ret i32 %retval.0
6201}
6202
6203define i32 @atomic_shl1_and_32_gpr_brz(ptr %v, i32 %c) nounwind {
6204; X86-LABEL: atomic_shl1_and_32_gpr_brz:
6205; X86:       # %bb.0: # %entry
6206; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6207; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
6208; X86-NEXT:    movl $1, %eax
6209; X86-NEXT:    shll %cl, %eax
6210; X86-NEXT:    lock andl %eax, (%edx)
6211; X86-NEXT:    movl $123, %eax
6212; X86-NEXT:    jne .LBB108_2
6213; X86-NEXT:  # %bb.1: # %if.then
6214; X86-NEXT:    movl (%edx,%ecx,4), %eax
6215; X86-NEXT:  .LBB108_2: # %return
6216; X86-NEXT:    retl
6217;
6218; X64-LABEL: atomic_shl1_and_32_gpr_brz:
6219; X64:       # %bb.0: # %entry
6220; X64-NEXT:    movl %esi, %ecx
6221; X64-NEXT:    movl $1, %eax
6222; X64-NEXT:    shll %cl, %eax
6223; X64-NEXT:    lock andl %eax, (%rdi)
6224; X64-NEXT:    movl $123, %eax
6225; X64-NEXT:    jne .LBB108_2
6226; X64-NEXT:  # %bb.1: # %if.then
6227; X64-NEXT:    movl %ecx, %eax
6228; X64-NEXT:    movl (%rdi,%rax,4), %eax
6229; X64-NEXT:  .LBB108_2: # %return
6230; X64-NEXT:    retq
6231entry:
6232  %shl = shl nuw i32 1, %c
6233  %0 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
6234  %and = and i32 %0, %shl
6235  %tobool.not = icmp eq i32 %and, 0
6236  br i1 %tobool.not, label %if.then, label %return
6237
6238if.then:                                          ; preds = %entry
6239  %idxprom = zext i32 %c to i64
6240  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %idxprom
6241  %1 = load i32, ptr %arrayidx, align 4
6242  br label %return
6243
6244return:                                           ; preds = %entry, %if.then
6245  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6246  ret i32 %retval.0
6247}
6248
6249define i32 @atomic_shl1_small_mask_and_32_gpr_brz(ptr %v, i32 %c) nounwind {
6250; X86-LABEL: atomic_shl1_small_mask_and_32_gpr_brz:
6251; X86:       # %bb.0: # %entry
6252; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
6253; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6254; X86-NEXT:    andl $15, %ecx
6255; X86-NEXT:    movl $1, %eax
6256; X86-NEXT:    shll %cl, %eax
6257; X86-NEXT:    lock andl %eax, (%edx)
6258; X86-NEXT:    movl $123, %eax
6259; X86-NEXT:    jne .LBB109_2
6260; X86-NEXT:  # %bb.1: # %if.then
6261; X86-NEXT:    movl (%edx,%ecx,4), %eax
6262; X86-NEXT:  .LBB109_2: # %return
6263; X86-NEXT:    retl
6264;
6265; X64-LABEL: atomic_shl1_small_mask_and_32_gpr_brz:
6266; X64:       # %bb.0: # %entry
6267; X64-NEXT:    movl %esi, %ecx
6268; X64-NEXT:    andl $15, %ecx
6269; X64-NEXT:    movl $1, %eax
6270; X64-NEXT:    shll %cl, %eax
6271; X64-NEXT:    lock andl %eax, (%rdi)
6272; X64-NEXT:    movl $123, %eax
6273; X64-NEXT:    jne .LBB109_2
6274; X64-NEXT:  # %bb.1: # %if.then
6275; X64-NEXT:    movl %ecx, %eax
6276; X64-NEXT:    movl (%rdi,%rax,4), %eax
6277; X64-NEXT:  .LBB109_2: # %return
6278; X64-NEXT:    retq
6279entry:
6280  %0 = and i32 %c, 15
6281  %shl = shl nuw nsw i32 1, %0
6282  %1 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
6283  %and = and i32 %shl, %1
6284  %tobool.not = icmp eq i32 %and, 0
6285  br i1 %tobool.not, label %if.then, label %return
6286
6287if.then:                                          ; preds = %entry
6288  %conv2 = zext i32 %0 to i64
6289  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv2
6290  %2 = load i32, ptr %arrayidx, align 4
6291  br label %return
6292
6293return:                                           ; preds = %entry, %if.then
6294  %retval.0 = phi i32 [ %2, %if.then ], [ 123, %entry ]
6295  ret i32 %retval.0
6296}
6297
6298define i32 @atomic_shl1_mask0_and_32_gpr_brz(ptr %v, i32 %c) nounwind {
6299; X86-LABEL: atomic_shl1_mask0_and_32_gpr_brz:
6300; X86:       # %bb.0: # %entry
6301; X86-NEXT:    pushl %edi
6302; X86-NEXT:    pushl %esi
6303; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6304; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
6305; X86-NEXT:    movl $1, %edx
6306; X86-NEXT:    shll %cl, %edx
6307; X86-NEXT:    movl (%esi), %eax
6308; X86-NEXT:    .p2align 4
6309; X86-NEXT:  .LBB110_1: # %atomicrmw.start
6310; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6311; X86-NEXT:    movl %eax, %edi
6312; X86-NEXT:    andl %edx, %edi
6313; X86-NEXT:    lock cmpxchgl %edi, (%esi)
6314; X86-NEXT:    jne .LBB110_1
6315; X86-NEXT:  # %bb.2: # %atomicrmw.end
6316; X86-NEXT:    movl $123, %edx
6317; X86-NEXT:    btl %ecx, %eax
6318; X86-NEXT:    jb .LBB110_4
6319; X86-NEXT:  # %bb.3: # %if.then
6320; X86-NEXT:    movl (%esi,%ecx,4), %edx
6321; X86-NEXT:  .LBB110_4: # %return
6322; X86-NEXT:    movl %edx, %eax
6323; X86-NEXT:    popl %esi
6324; X86-NEXT:    popl %edi
6325; X86-NEXT:    retl
6326;
6327; X64-LABEL: atomic_shl1_mask0_and_32_gpr_brz:
6328; X64:       # %bb.0: # %entry
6329; X64-NEXT:    movl %esi, %ecx
6330; X64-NEXT:    movl $1, %edx
6331; X64-NEXT:    shll %cl, %edx
6332; X64-NEXT:    movl (%rdi), %eax
6333; X64-NEXT:    .p2align 4
6334; X64-NEXT:  .LBB110_1: # %atomicrmw.start
6335; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6336; X64-NEXT:    movl %eax, %esi
6337; X64-NEXT:    andl %edx, %esi
6338; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
6339; X64-NEXT:    jne .LBB110_1
6340; X64-NEXT:  # %bb.2: # %atomicrmw.end
6341; X64-NEXT:    movl $123, %edx
6342; X64-NEXT:    btl %ecx, %eax
6343; X64-NEXT:    jae .LBB110_3
6344; X64-NEXT:  # %bb.4: # %return
6345; X64-NEXT:    movl %edx, %eax
6346; X64-NEXT:    retq
6347; X64-NEXT:  .LBB110_3: # %if.then
6348; X64-NEXT:    movl %ecx, %eax
6349; X64-NEXT:    movl (%rdi,%rax,4), %edx
6350; X64-NEXT:    movl %edx, %eax
6351; X64-NEXT:    retq
6352entry:
6353  %rem = and i32 %c, 31
6354  %shl = shl nuw i32 1, %rem
6355  %0 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
6356  %shl1 = shl nuw i32 1, %c
6357  %and = and i32 %0, %shl1
6358  %tobool.not = icmp eq i32 %and, 0
6359  br i1 %tobool.not, label %if.then, label %return
6360
6361if.then:                                          ; preds = %entry
6362  %conv = zext i32 %c to i64
6363  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
6364  %1 = load i32, ptr %arrayidx, align 4
6365  br label %return
6366
6367return:                                           ; preds = %entry, %if.then
6368  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6369  ret i32 %retval.0
6370}
6371
6372define i32 @atomic_shl1_mask1_and_32_gpr_brz(ptr %v, i32 %c) nounwind {
6373; X86-LABEL: atomic_shl1_mask1_and_32_gpr_brz:
6374; X86:       # %bb.0: # %entry
6375; X86-NEXT:    pushl %edi
6376; X86-NEXT:    pushl %esi
6377; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6378; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
6379; X86-NEXT:    movl $1, %edx
6380; X86-NEXT:    shll %cl, %edx
6381; X86-NEXT:    movl (%esi), %eax
6382; X86-NEXT:    .p2align 4
6383; X86-NEXT:  .LBB111_1: # %atomicrmw.start
6384; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6385; X86-NEXT:    movl %eax, %edi
6386; X86-NEXT:    andl %edx, %edi
6387; X86-NEXT:    lock cmpxchgl %edi, (%esi)
6388; X86-NEXT:    jne .LBB111_1
6389; X86-NEXT:  # %bb.2: # %atomicrmw.end
6390; X86-NEXT:    movl $123, %edx
6391; X86-NEXT:    btl %ecx, %eax
6392; X86-NEXT:    jb .LBB111_4
6393; X86-NEXT:  # %bb.3: # %if.then
6394; X86-NEXT:    movl (%esi,%ecx,4), %edx
6395; X86-NEXT:  .LBB111_4: # %return
6396; X86-NEXT:    movl %edx, %eax
6397; X86-NEXT:    popl %esi
6398; X86-NEXT:    popl %edi
6399; X86-NEXT:    retl
6400;
6401; X64-LABEL: atomic_shl1_mask1_and_32_gpr_brz:
6402; X64:       # %bb.0: # %entry
6403; X64-NEXT:    movl %esi, %ecx
6404; X64-NEXT:    movl $1, %edx
6405; X64-NEXT:    shll %cl, %edx
6406; X64-NEXT:    movl (%rdi), %eax
6407; X64-NEXT:    .p2align 4
6408; X64-NEXT:  .LBB111_1: # %atomicrmw.start
6409; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6410; X64-NEXT:    movl %eax, %esi
6411; X64-NEXT:    andl %edx, %esi
6412; X64-NEXT:    lock cmpxchgl %esi, (%rdi)
6413; X64-NEXT:    jne .LBB111_1
6414; X64-NEXT:  # %bb.2: # %atomicrmw.end
6415; X64-NEXT:    movl $123, %edx
6416; X64-NEXT:    btl %ecx, %eax
6417; X64-NEXT:    jae .LBB111_3
6418; X64-NEXT:  # %bb.4: # %return
6419; X64-NEXT:    movl %edx, %eax
6420; X64-NEXT:    retq
6421; X64-NEXT:  .LBB111_3: # %if.then
6422; X64-NEXT:    movl %ecx, %eax
6423; X64-NEXT:    movl (%rdi,%rax,4), %edx
6424; X64-NEXT:    movl %edx, %eax
6425; X64-NEXT:    retq
6426entry:
6427  %shl = shl nuw i32 1, %c
6428  %0 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
6429  %rem = and i32 %c, 31
6430  %shl1 = shl nuw i32 1, %rem
6431  %and = and i32 %0, %shl1
6432  %tobool.not = icmp eq i32 %and, 0
6433  br i1 %tobool.not, label %if.then, label %return
6434
6435if.then:                                          ; preds = %entry
6436  %conv = zext i32 %c to i64
6437  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
6438  %1 = load i32, ptr %arrayidx, align 4
6439  br label %return
6440
6441return:                                           ; preds = %entry, %if.then
6442  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6443  ret i32 %retval.0
6444}
6445
6446define i32 @atomic_shl1_mask01_and_32_gpr_brz(ptr %v, i32 %c) nounwind {
6447; X86-LABEL: atomic_shl1_mask01_and_32_gpr_brz:
6448; X86:       # %bb.0: # %entry
6449; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6450; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
6451; X86-NEXT:    movl $1, %eax
6452; X86-NEXT:    shll %cl, %eax
6453; X86-NEXT:    lock andl %eax, (%edx)
6454; X86-NEXT:    movl $123, %eax
6455; X86-NEXT:    jne .LBB112_2
6456; X86-NEXT:  # %bb.1: # %if.then
6457; X86-NEXT:    movl (%edx,%ecx,4), %eax
6458; X86-NEXT:  .LBB112_2: # %return
6459; X86-NEXT:    retl
6460;
6461; X64-LABEL: atomic_shl1_mask01_and_32_gpr_brz:
6462; X64:       # %bb.0: # %entry
6463; X64-NEXT:    movl %esi, %ecx
6464; X64-NEXT:    movl $1, %eax
6465; X64-NEXT:    shll %cl, %eax
6466; X64-NEXT:    lock andl %eax, (%rdi)
6467; X64-NEXT:    movl $123, %eax
6468; X64-NEXT:    jne .LBB112_2
6469; X64-NEXT:  # %bb.1: # %if.then
6470; X64-NEXT:    movl %ecx, %eax
6471; X64-NEXT:    movl (%rdi,%rax,4), %eax
6472; X64-NEXT:  .LBB112_2: # %return
6473; X64-NEXT:    retq
6474entry:
6475  %rem = and i32 %c, 31
6476  %shl = shl nuw i32 1, %rem
6477  %0 = atomicrmw and ptr %v, i32 %shl monotonic, align 4
6478  %and = and i32 %0, %shl
6479  %tobool.not = icmp eq i32 %and, 0
6480  br i1 %tobool.not, label %if.then, label %return
6481
6482if.then:                                          ; preds = %entry
6483  %conv = zext i32 %c to i64
6484  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %conv
6485  %1 = load i32, ptr %arrayidx, align 4
6486  br label %return
6487
6488return:                                           ; preds = %entry, %if.then
6489  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6490  ret i32 %retval.0
6491}
6492
6493define i32 @atomic_blsi_and_32_gpr_brz(ptr %v, i32 %c) nounwind {
6494; X86-LABEL: atomic_blsi_and_32_gpr_brz:
6495; X86:       # %bb.0: # %entry
6496; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6497; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
6498; X86-NEXT:    movl %ecx, %eax
6499; X86-NEXT:    negl %eax
6500; X86-NEXT:    andl %ecx, %eax
6501; X86-NEXT:    lock andl %eax, (%edx)
6502; X86-NEXT:    movl $123, %eax
6503; X86-NEXT:    jne .LBB113_2
6504; X86-NEXT:  # %bb.1: # %if.then
6505; X86-NEXT:    movl (%edx,%ecx,4), %eax
6506; X86-NEXT:  .LBB113_2: # %return
6507; X86-NEXT:    retl
6508;
6509; X64-LABEL: atomic_blsi_and_32_gpr_brz:
6510; X64:       # %bb.0: # %entry
6511; X64-NEXT:    movl %esi, %eax
6512; X64-NEXT:    negl %eax
6513; X64-NEXT:    andl %esi, %eax
6514; X64-NEXT:    lock andl %eax, (%rdi)
6515; X64-NEXT:    movl $123, %eax
6516; X64-NEXT:    jne .LBB113_2
6517; X64-NEXT:  # %bb.1: # %if.then
6518; X64-NEXT:    movl %esi, %eax
6519; X64-NEXT:    movl (%rdi,%rax,4), %eax
6520; X64-NEXT:  .LBB113_2: # %return
6521; X64-NEXT:    retq
6522entry:
6523  %sub = sub i32 0, %c
6524  %and = and i32 %sub, %c
6525  %0 = atomicrmw and ptr %v, i32 %and monotonic, align 4
6526  %and3 = and i32 %0, %and
6527  %tobool.not = icmp eq i32 %and3, 0
6528  br i1 %tobool.not, label %if.then, label %return
6529
6530if.then:                                          ; preds = %entry
6531  %idxprom = zext i32 %c to i64
6532  %arrayidx = getelementptr inbounds i32, ptr %v, i64 %idxprom
6533  %1 = load i32, ptr %arrayidx, align 4
6534  br label %return
6535
6536return:                                           ; preds = %entry, %if.then
6537  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6538  ret i32 %retval.0
6539}
6540
6541define i32 @atomic_shl1_xor_32_const_val(ptr %v) nounwind {
6542; X86-LABEL: atomic_shl1_xor_32_const_val:
6543; X86:       # %bb.0: # %entry
6544; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6545; X86-NEXT:    xorl %eax, %eax
6546; X86-NEXT:    lock btcl $4, (%ecx)
6547; X86-NEXT:    setb %al
6548; X86-NEXT:    shll $4, %eax
6549; X86-NEXT:    retl
6550;
6551; X64-LABEL: atomic_shl1_xor_32_const_val:
6552; X64:       # %bb.0: # %entry
6553; X64-NEXT:    xorl %eax, %eax
6554; X64-NEXT:    lock btcl $4, (%rdi)
6555; X64-NEXT:    setb %al
6556; X64-NEXT:    shll $4, %eax
6557; X64-NEXT:    retq
6558entry:
6559  %0 = atomicrmw xor ptr %v, i32 16 monotonic, align 4
6560  %and = and i32 16, %0
6561  ret i32 %and
6562}
6563
6564define i32 @atomic_shl1_xor_32_const_valz(ptr %v) nounwind {
6565; X86-LABEL: atomic_shl1_xor_32_const_valz:
6566; X86:       # %bb.0: # %entry
6567; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6568; X86-NEXT:    movl (%ecx), %eax
6569; X86-NEXT:    .p2align 4
6570; X86-NEXT:  .LBB115_1: # %atomicrmw.start
6571; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6572; X86-NEXT:    movl %eax, %edx
6573; X86-NEXT:    xorl $16, %edx
6574; X86-NEXT:    lock cmpxchgl %edx, (%ecx)
6575; X86-NEXT:    jne .LBB115_1
6576; X86-NEXT:  # %bb.2: # %atomicrmw.end
6577; X86-NEXT:    xorl %ecx, %ecx
6578; X86-NEXT:    testb $16, %al
6579; X86-NEXT:    sete %cl
6580; X86-NEXT:    movl %ecx, %eax
6581; X86-NEXT:    retl
6582;
6583; X64-LABEL: atomic_shl1_xor_32_const_valz:
6584; X64:       # %bb.0: # %entry
6585; X64-NEXT:    movl (%rdi), %eax
6586; X64-NEXT:    .p2align 4
6587; X64-NEXT:  .LBB115_1: # %atomicrmw.start
6588; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6589; X64-NEXT:    movl %eax, %ecx
6590; X64-NEXT:    xorl $16, %ecx
6591; X64-NEXT:    lock cmpxchgl %ecx, (%rdi)
6592; X64-NEXT:    jne .LBB115_1
6593; X64-NEXT:  # %bb.2: # %atomicrmw.end
6594; X64-NEXT:    xorl %ecx, %ecx
6595; X64-NEXT:    testb $16, %al
6596; X64-NEXT:    sete %cl
6597; X64-NEXT:    movl %ecx, %eax
6598; X64-NEXT:    retq
6599entry:
6600  %0 = atomicrmw xor ptr %v, i32 16 monotonic, align 4
6601  %and = lshr i32 %0, 4
6602  %and.lobit = and i32 %and, 1
6603  %lnot.ext = xor i32 %and.lobit, 1
6604  ret i32 %lnot.ext
6605}
6606
6607define i32 @atomic_shl1_xor_32_const_valnz(ptr %v) nounwind {
6608; X86-LABEL: atomic_shl1_xor_32_const_valnz:
6609; X86:       # %bb.0: # %entry
6610; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6611; X86-NEXT:    movl (%ecx), %eax
6612; X86-NEXT:    .p2align 4
6613; X86-NEXT:  .LBB116_1: # %atomicrmw.start
6614; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6615; X86-NEXT:    movl %eax, %edx
6616; X86-NEXT:    xorl $16, %edx
6617; X86-NEXT:    lock cmpxchgl %edx, (%ecx)
6618; X86-NEXT:    jne .LBB116_1
6619; X86-NEXT:  # %bb.2: # %atomicrmw.end
6620; X86-NEXT:    shrl $4, %eax
6621; X86-NEXT:    andl $1, %eax
6622; X86-NEXT:    retl
6623;
6624; X64-LABEL: atomic_shl1_xor_32_const_valnz:
6625; X64:       # %bb.0: # %entry
6626; X64-NEXT:    movl (%rdi), %eax
6627; X64-NEXT:    .p2align 4
6628; X64-NEXT:  .LBB116_1: # %atomicrmw.start
6629; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6630; X64-NEXT:    movl %eax, %ecx
6631; X64-NEXT:    xorl $16, %ecx
6632; X64-NEXT:    lock cmpxchgl %ecx, (%rdi)
6633; X64-NEXT:    jne .LBB116_1
6634; X64-NEXT:  # %bb.2: # %atomicrmw.end
6635; X64-NEXT:    shrl $4, %eax
6636; X64-NEXT:    andl $1, %eax
6637; X64-NEXT:    retq
6638entry:
6639  %0 = atomicrmw xor ptr %v, i32 16 monotonic, align 4
6640  %and = lshr i32 %0, 4
6641  %and.lobit = and i32 %and, 1
6642  ret i32 %and.lobit
6643}
6644
6645define i32 @atomic_shl1_and_32_const_val(ptr %v) nounwind {
6646; X86-LABEL: atomic_shl1_and_32_const_val:
6647; X86:       # %bb.0: # %entry
6648; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6649; X86-NEXT:    xorl %eax, %eax
6650; X86-NEXT:    lock btrl $4, (%ecx)
6651; X86-NEXT:    setb %al
6652; X86-NEXT:    shll $4, %eax
6653; X86-NEXT:    retl
6654;
6655; X64-LABEL: atomic_shl1_and_32_const_val:
6656; X64:       # %bb.0: # %entry
6657; X64-NEXT:    xorl %eax, %eax
6658; X64-NEXT:    lock btrl $4, (%rdi)
6659; X64-NEXT:    setb %al
6660; X64-NEXT:    shll $4, %eax
6661; X64-NEXT:    retq
6662entry:
6663  %0 = atomicrmw and ptr %v, i32 -17 monotonic, align 4
6664  %and = and i32 %0, 16
6665  ret i32 %and
6666}
6667
6668define i32 @atomic_shl1_and_32_const_valz(ptr %v) nounwind {
6669; X86-LABEL: atomic_shl1_and_32_const_valz:
6670; X86:       # %bb.0: # %entry
6671; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6672; X86-NEXT:    movl (%ecx), %eax
6673; X86-NEXT:    .p2align 4
6674; X86-NEXT:  .LBB118_1: # %atomicrmw.start
6675; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6676; X86-NEXT:    movl %eax, %edx
6677; X86-NEXT:    andl $-17, %edx
6678; X86-NEXT:    lock cmpxchgl %edx, (%ecx)
6679; X86-NEXT:    jne .LBB118_1
6680; X86-NEXT:  # %bb.2: # %atomicrmw.end
6681; X86-NEXT:    xorl %ecx, %ecx
6682; X86-NEXT:    testb $16, %al
6683; X86-NEXT:    sete %cl
6684; X86-NEXT:    movl %ecx, %eax
6685; X86-NEXT:    retl
6686;
6687; X64-LABEL: atomic_shl1_and_32_const_valz:
6688; X64:       # %bb.0: # %entry
6689; X64-NEXT:    movl (%rdi), %eax
6690; X64-NEXT:    .p2align 4
6691; X64-NEXT:  .LBB118_1: # %atomicrmw.start
6692; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6693; X64-NEXT:    movl %eax, %ecx
6694; X64-NEXT:    andl $-17, %ecx
6695; X64-NEXT:    lock cmpxchgl %ecx, (%rdi)
6696; X64-NEXT:    jne .LBB118_1
6697; X64-NEXT:  # %bb.2: # %atomicrmw.end
6698; X64-NEXT:    xorl %ecx, %ecx
6699; X64-NEXT:    testb $16, %al
6700; X64-NEXT:    sete %cl
6701; X64-NEXT:    movl %ecx, %eax
6702; X64-NEXT:    retq
6703entry:
6704  %0 = atomicrmw and ptr %v, i32 -17 monotonic, align 4
6705  %and = lshr i32 %0, 4
6706  %and.lobit = and i32 %and, 1
6707  %lnot.ext = xor i32 %and.lobit, 1
6708  ret i32 %lnot.ext
6709}
6710
6711define i32 @atomic_shl1_and_32_const_valnz(ptr %v) nounwind {
6712; X86-LABEL: atomic_shl1_and_32_const_valnz:
6713; X86:       # %bb.0: # %entry
6714; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6715; X86-NEXT:    movl (%ecx), %eax
6716; X86-NEXT:    .p2align 4
6717; X86-NEXT:  .LBB119_1: # %atomicrmw.start
6718; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6719; X86-NEXT:    movl %eax, %edx
6720; X86-NEXT:    andl $-17, %edx
6721; X86-NEXT:    lock cmpxchgl %edx, (%ecx)
6722; X86-NEXT:    jne .LBB119_1
6723; X86-NEXT:  # %bb.2: # %atomicrmw.end
6724; X86-NEXT:    shrl $4, %eax
6725; X86-NEXT:    andl $1, %eax
6726; X86-NEXT:    retl
6727;
6728; X64-LABEL: atomic_shl1_and_32_const_valnz:
6729; X64:       # %bb.0: # %entry
6730; X64-NEXT:    movl (%rdi), %eax
6731; X64-NEXT:    .p2align 4
6732; X64-NEXT:  .LBB119_1: # %atomicrmw.start
6733; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6734; X64-NEXT:    movl %eax, %ecx
6735; X64-NEXT:    andl $-17, %ecx
6736; X64-NEXT:    lock cmpxchgl %ecx, (%rdi)
6737; X64-NEXT:    jne .LBB119_1
6738; X64-NEXT:  # %bb.2: # %atomicrmw.end
6739; X64-NEXT:    shrl $4, %eax
6740; X64-NEXT:    andl $1, %eax
6741; X64-NEXT:    retq
6742entry:
6743  %0 = atomicrmw and ptr %v, i32 -17 monotonic, align 4
6744  %and = lshr i32 %0, 4
6745  %and.lobit = and i32 %and, 1
6746  ret i32 %and.lobit
6747}
6748
6749define i32 @atomic_shl1_and_32_const_br(ptr %v) nounwind {
6750; X86-LABEL: atomic_shl1_and_32_const_br:
6751; X86:       # %bb.0: # %entry
6752; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
6753; X86-NEXT:    lock btrl $4, (%eax)
6754; X86-NEXT:    jae .LBB120_1
6755; X86-NEXT:  # %bb.2: # %if.then
6756; X86-NEXT:    movl 16(%eax), %eax
6757; X86-NEXT:    retl
6758; X86-NEXT:  .LBB120_1:
6759; X86-NEXT:    movl $123, %eax
6760; X86-NEXT:    retl
6761;
6762; X64-LABEL: atomic_shl1_and_32_const_br:
6763; X64:       # %bb.0: # %entry
6764; X64-NEXT:    lock btrl $4, (%rdi)
6765; X64-NEXT:    jae .LBB120_1
6766; X64-NEXT:  # %bb.2: # %if.then
6767; X64-NEXT:    movl 16(%rdi), %eax
6768; X64-NEXT:    retq
6769; X64-NEXT:  .LBB120_1:
6770; X64-NEXT:    movl $123, %eax
6771; X64-NEXT:    retq
6772entry:
6773  %0 = atomicrmw and ptr %v, i32 -17 monotonic, align 4
6774  %and = and i32 16, %0
6775  %tobool.not = icmp eq i32 %and, 0
6776  br i1 %tobool.not, label %return, label %if.then
6777
6778if.then:                                          ; preds = %entry
6779  %arrayidx = getelementptr inbounds i32, ptr %v, i64 4
6780  %1 = load i32, ptr %arrayidx, align 4
6781  br label %return
6782
6783return:                                           ; preds = %entry, %if.then
6784  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6785  ret i32 %retval.0
6786}
6787
6788define i32 @atomic_shl1_and_32_const_brz(ptr %v) nounwind {
6789; X86-LABEL: atomic_shl1_and_32_const_brz:
6790; X86:       # %bb.0: # %entry
6791; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6792; X86-NEXT:    lock btrl $4, (%ecx)
6793; X86-NEXT:    movl $123, %eax
6794; X86-NEXT:    jae .LBB121_1
6795; X86-NEXT:  # %bb.2: # %return
6796; X86-NEXT:    retl
6797; X86-NEXT:  .LBB121_1: # %if.then
6798; X86-NEXT:    movl 16(%ecx), %eax
6799; X86-NEXT:    retl
6800;
6801; X64-LABEL: atomic_shl1_and_32_const_brz:
6802; X64:       # %bb.0: # %entry
6803; X64-NEXT:    lock btrl $4, (%rdi)
6804; X64-NEXT:    movl $123, %eax
6805; X64-NEXT:    jae .LBB121_1
6806; X64-NEXT:  # %bb.2: # %return
6807; X64-NEXT:    retq
6808; X64-NEXT:  .LBB121_1: # %if.then
6809; X64-NEXT:    movl 16(%rdi), %eax
6810; X64-NEXT:    retq
6811entry:
6812  %0 = atomicrmw and ptr %v, i32 -17 monotonic, align 4
6813  %and = and i32 %0, 16
6814  %tobool.not = icmp eq i32 %and, 0
6815  br i1 %tobool.not, label %if.then, label %return
6816
6817if.then:                                          ; preds = %entry
6818  %arrayidx = getelementptr inbounds i32, ptr %v, i64 4
6819  %1 = load i32, ptr %arrayidx, align 4
6820  br label %return
6821
6822return:                                           ; preds = %entry, %if.then
6823  %retval.0 = phi i32 [ %1, %if.then ], [ 123, %entry ]
6824  ret i32 %retval.0
6825}
6826
6827; This IR isn't really ever expected. This test is just make sure we don't crash.
6828define i32 @atomic_xor_dead_and(ptr %v, i32 %c) nounwind {
6829; X86-LABEL: atomic_xor_dead_and:
6830; X86:       # %bb.0: # %entry
6831; X86-NEXT:    pushl %esi
6832; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
6833; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
6834; X86-NEXT:    andb $7, %cl
6835; X86-NEXT:    movl $1, %esi
6836; X86-NEXT:    shll %cl, %esi
6837; X86-NEXT:    movl (%edx), %eax
6838; X86-NEXT:    .p2align 4
6839; X86-NEXT:  .LBB122_1: # %atomicrmw.start
6840; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6841; X86-NEXT:    movl %eax, %ecx
6842; X86-NEXT:    xorl %esi, %ecx
6843; X86-NEXT:    lock cmpxchgl %ecx, (%edx)
6844; X86-NEXT:    jne .LBB122_1
6845; X86-NEXT:  # %bb.2: # %atomicrmw.end
6846; X86-NEXT:    andl %esi, %eax
6847; X86-NEXT:    popl %esi
6848; X86-NEXT:    retl
6849;
6850; X64-LABEL: atomic_xor_dead_and:
6851; X64:       # %bb.0: # %entry
6852; X64-NEXT:    movl %esi, %ecx
6853; X64-NEXT:    andb $7, %cl
6854; X64-NEXT:    movl $1, %edx
6855; X64-NEXT:    # kill: def $cl killed $cl killed $ecx
6856; X64-NEXT:    shll %cl, %edx
6857; X64-NEXT:    movl (%rdi), %eax
6858; X64-NEXT:    .p2align 4
6859; X64-NEXT:  .LBB122_1: # %atomicrmw.start
6860; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6861; X64-NEXT:    movl %eax, %ecx
6862; X64-NEXT:    xorl %edx, %ecx
6863; X64-NEXT:    lock cmpxchgl %ecx, (%rdi)
6864; X64-NEXT:    jne .LBB122_1
6865; X64-NEXT:  # %bb.2: # %atomicrmw.end
6866; X64-NEXT:    andl %edx, %eax
6867; X64-NEXT:    retq
6868entry:
6869  %0 = and i32 %c, 7
6870  %shl = shl nuw nsw i32 1, %0
6871  %1 = atomicrmw xor ptr %v, i32 %shl monotonic, align 4
6872  %and = and i32 %1, %1
6873  %and1 = and i32 %and, %shl
6874  ret i32 %and1
6875}
6876
6877define i32 @atomic_xor_with_not_arg(ptr %v, i32 %c) nounwind {
6878; X86-LABEL: atomic_xor_with_not_arg:
6879; X86:       # %bb.0: # %entry
6880; X86-NEXT:    pushl %esi
6881; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6882; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
6883; X86-NEXT:    notl %edx
6884; X86-NEXT:    movl (%ecx), %eax
6885; X86-NEXT:    .p2align 4
6886; X86-NEXT:  .LBB123_1: # %atomicrmw.start
6887; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6888; X86-NEXT:    movl %eax, %esi
6889; X86-NEXT:    xorl %edx, %esi
6890; X86-NEXT:    lock cmpxchgl %esi, (%ecx)
6891; X86-NEXT:    jne .LBB123_1
6892; X86-NEXT:  # %bb.2: # %atomicrmw.end
6893; X86-NEXT:    popl %esi
6894; X86-NEXT:    retl
6895;
6896; X64-LABEL: atomic_xor_with_not_arg:
6897; X64:       # %bb.0: # %entry
6898; X64-NEXT:    notl %esi
6899; X64-NEXT:    movl (%rdi), %eax
6900; X64-NEXT:    .p2align 4
6901; X64-NEXT:  .LBB123_1: # %atomicrmw.start
6902; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6903; X64-NEXT:    movl %eax, %ecx
6904; X64-NEXT:    xorl %esi, %ecx
6905; X64-NEXT:    lock cmpxchgl %ecx, (%rdi)
6906; X64-NEXT:    jne .LBB123_1
6907; X64-NEXT:  # %bb.2: # %atomicrmw.end
6908; X64-NEXT:    retq
6909entry:
6910  %0 = xor i32 %c, -1
6911  %1 = atomicrmw xor ptr %v, i32 %0 monotonic, align 4
6912  ret i32 %1
6913}
6914
6915define i16 @atomic_or_with_not_arg(ptr %v, i16 %c) nounwind {
6916; X86-LABEL: atomic_or_with_not_arg:
6917; X86:       # %bb.0: # %entry
6918; X86-NEXT:    pushl %esi
6919; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6920; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
6921; X86-NEXT:    notl %edx
6922; X86-NEXT:    movzwl (%ecx), %eax
6923; X86-NEXT:    .p2align 4
6924; X86-NEXT:  .LBB124_1: # %atomicrmw.start
6925; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6926; X86-NEXT:    movl %eax, %esi
6927; X86-NEXT:    orl %edx, %esi
6928; X86-NEXT:    # kill: def $ax killed $ax killed $eax
6929; X86-NEXT:    lock cmpxchgw %si, (%ecx)
6930; X86-NEXT:    # kill: def $ax killed $ax def $eax
6931; X86-NEXT:    jne .LBB124_1
6932; X86-NEXT:  # %bb.2: # %atomicrmw.end
6933; X86-NEXT:    # kill: def $ax killed $ax killed $eax
6934; X86-NEXT:    popl %esi
6935; X86-NEXT:    retl
6936;
6937; X64-LABEL: atomic_or_with_not_arg:
6938; X64:       # %bb.0: # %entry
6939; X64-NEXT:    notl %esi
6940; X64-NEXT:    movzwl (%rdi), %eax
6941; X64-NEXT:    .p2align 4
6942; X64-NEXT:  .LBB124_1: # %atomicrmw.start
6943; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6944; X64-NEXT:    movl %eax, %ecx
6945; X64-NEXT:    orl %esi, %ecx
6946; X64-NEXT:    # kill: def $ax killed $ax killed $eax
6947; X64-NEXT:    lock cmpxchgw %cx, (%rdi)
6948; X64-NEXT:    # kill: def $ax killed $ax def $eax
6949; X64-NEXT:    jne .LBB124_1
6950; X64-NEXT:  # %bb.2: # %atomicrmw.end
6951; X64-NEXT:    # kill: def $ax killed $ax killed $eax
6952; X64-NEXT:    retq
6953entry:
6954  %0 = xor i16 %c, -1
6955  %1 = atomicrmw or ptr %v, i16 %0 monotonic, align 2
6956  ret i16 %1
6957}
6958
6959define i8 @atomic_and_with_not_arg(ptr %v, i8 %c) nounwind {
6960; X86-LABEL: atomic_and_with_not_arg:
6961; X86:       # %bb.0: # %entry
6962; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
6963; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
6964; X86-NEXT:    notb %dl
6965; X86-NEXT:    movzbl (%ecx), %eax
6966; X86-NEXT:    .p2align 4
6967; X86-NEXT:  .LBB125_1: # %atomicrmw.start
6968; X86-NEXT:    # =>This Inner Loop Header: Depth=1
6969; X86-NEXT:    movb %al, %ah
6970; X86-NEXT:    orb %dl, %ah
6971; X86-NEXT:    lock cmpxchgb %ah, (%ecx)
6972; X86-NEXT:    jne .LBB125_1
6973; X86-NEXT:  # %bb.2: # %atomicrmw.end
6974; X86-NEXT:    retl
6975;
6976; X64-LABEL: atomic_and_with_not_arg:
6977; X64:       # %bb.0: # %entry
6978; X64-NEXT:    notb %sil
6979; X64-NEXT:    movzbl (%rdi), %eax
6980; X64-NEXT:    .p2align 4
6981; X64-NEXT:  .LBB125_1: # %atomicrmw.start
6982; X64-NEXT:    # =>This Inner Loop Header: Depth=1
6983; X64-NEXT:    movl %eax, %ecx
6984; X64-NEXT:    orb %sil, %cl
6985; X64-NEXT:    lock cmpxchgb %cl, (%rdi)
6986; X64-NEXT:    jne .LBB125_1
6987; X64-NEXT:  # %bb.2: # %atomicrmw.end
6988; X64-NEXT:    retq
6989entry:
6990  %0 = xor i8 %c, -1
6991  %1 = atomicrmw or ptr %v, i8 %0 monotonic, align 1
6992  ret i8 %1
6993}
6994
6995define weak_odr void @atomic_and_with_not_const() nounwind {
6996; X86-LABEL: atomic_and_with_not_const:
6997; X86:       # %bb.0: # %entry
6998; X86-NEXT:    retl
6999;
7000; X64-LABEL: atomic_and_with_not_const:
7001; X64:       # %bb.0: # %entry
7002; X64-NEXT:    retq
7003  entry:
7004  br label %if.end19
7005cont11:  ; No predecessors!
7006  %not = xor i32 0, -1
7007  %0 = atomicrmw and ptr null, i32 %not monotonic, align 4
7008  %and13 = and i32 %0, 0
7009  br label %if.end19
7010if.end19:  ; preds = %cont11, %entry
7011  ret void
7012}
7013