xref: /llvm-project/llvm/test/CodeGen/X86/add-cmov.ll (revision 2f448bf509432c1a19ec46ab8cbc7353c03c6280)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -verify-machineinstrs -mtriple=x86_64-- | FileCheck %s
3
4define i64 @select_consts_i64(i64 %offset, i32 %x) {
5; CHECK-LABEL: select_consts_i64:
6; CHECK:       # %bb.0:
7; CHECK-NEXT:    leaq 42(%rdi), %rax
8; CHECK-NEXT:    testl %esi, %esi
9; CHECK-NEXT:    cmovneq %rdi, %rax
10; CHECK-NEXT:    retq
11  %b = icmp eq i32 %x, 0
12  %s = select i1 %b, i64 42, i64 0
13  %r = add i64 %s, %offset
14  ret i64 %r
15}
16
17define i64 @select_consts_big_i64(i64 %offset, i32 %x) {
18; CHECK-LABEL: select_consts_big_i64:
19; CHECK:       # %bb.0:
20; CHECK-NEXT:    movabsq $42000000000, %rax # imm = 0x9C7652400
21; CHECK-NEXT:    addq %rdi, %rax
22; CHECK-NEXT:    testl %esi, %esi
23; CHECK-NEXT:    cmovneq %rdi, %rax
24; CHECK-NEXT:    retq
25  %b = icmp eq i32 %x, 0
26  %s = select i1 %b, i64 42000000000, i64 0
27  %r = add i64 %s, %offset
28  ret i64 %r
29}
30
31define i32 @select_consts_i32(i32 %offset, i64 %x) {
32; CHECK-LABEL: select_consts_i32:
33; CHECK:       # %bb.0:
34; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
35; CHECK-NEXT:    leal 43(%rdi), %eax
36; CHECK-NEXT:    cmpq $42, %rsi
37; CHECK-NEXT:    cmovgel %edi, %eax
38; CHECK-NEXT:    retq
39  %b = icmp sgt i64 %x, 41
40  %s = select i1 %b, i32 0, i32 43
41  %r = add i32 %offset, %s
42  ret i32 %r
43}
44
45define i16 @select_consts_i16(i16 %offset, i1 %b) {
46; CHECK-LABEL: select_consts_i16:
47; CHECK:       # %bb.0:
48; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
49; CHECK-NEXT:    leal 44(%rdi), %eax
50; CHECK-NEXT:    testb $1, %sil
51; CHECK-NEXT:    cmovel %edi, %eax
52; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
53; CHECK-NEXT:    retq
54  %s = select i1 %b, i16 44, i16 0
55  %r = add i16 %s, %offset
56  ret i16 %r
57}
58
59define i8 @select_consts_i8(i8 %offset, i1 %b) {
60; CHECK-LABEL: select_consts_i8:
61; CHECK:       # %bb.0:
62; CHECK-NEXT:    xorl %ecx, %ecx
63; CHECK-NEXT:    testb $1, %sil
64; CHECK-NEXT:    movl $45, %eax
65; CHECK-NEXT:    cmovnel %ecx, %eax
66; CHECK-NEXT:    addb %dil, %al
67; CHECK-NEXT:    # kill: def $al killed $al killed $eax
68; CHECK-NEXT:    retq
69  %s = select i1 %b, i8 0, i8 45
70  %r = add i8 %offset, %s
71  ret i8 %r
72}
73
74define i32 @select_consts_use_i32(i32 %offset, i64 %x, ptr %p) {
75; CHECK-LABEL: select_consts_use_i32:
76; CHECK:       # %bb.0:
77; CHECK-NEXT:    xorl %ecx, %ecx
78; CHECK-NEXT:    cmpq $42, %rsi
79; CHECK-NEXT:    movl $43, %eax
80; CHECK-NEXT:    cmovgel %ecx, %eax
81; CHECK-NEXT:    movl %eax, (%rdx)
82; CHECK-NEXT:    addl %edi, %eax
83; CHECK-NEXT:    retq
84  %b = icmp sgt i64 %x, 41
85  %s = select i1 %b, i32 0, i32 43
86  store i32 %s, ptr %p
87  %r = add i32 %offset, %s
88  ret i32 %r
89}
90
91; Special-case LEA hacks are done before we try to push the add into a CMOV.
92
93define i32 @select_40_43_i32(i32 %offset, i64 %x) {
94; CHECK-LABEL: select_40_43_i32:
95; CHECK:       # %bb.0:
96; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
97; CHECK-NEXT:    xorl %eax, %eax
98; CHECK-NEXT:    cmpq $42, %rsi
99; CHECK-NEXT:    setl %al
100; CHECK-NEXT:    leal (%rax,%rax,2), %eax
101; CHECK-NEXT:    leal 40(%rdi,%rax), %eax
102; CHECK-NEXT:    retq
103  %b = icmp sgt i64 %x, 41
104  %s = select i1 %b, i32 40, i32 43
105  %r = add i32 %offset, %s
106  ret i32 %r
107}
108
109define i32 @select_0_1_i32(i32 %offset, i64 %x) {
110; CHECK-LABEL: select_0_1_i32:
111; CHECK:       # %bb.0:
112; CHECK-NEXT:    movl %edi, %eax
113; CHECK-NEXT:    cmpq $42, %rsi
114; CHECK-NEXT:    adcl $0, %eax
115; CHECK-NEXT:    retq
116  %b = icmp ugt i64 %x, 41
117  %s = select i1 %b, i32 0, i32 1
118  %r = add i32 %offset, %s
119  ret i32 %r
120}
121
122define i32 @select_1_0_i32(i32 %offset, i64 %x) {
123; CHECK-LABEL: select_1_0_i32:
124; CHECK:       # %bb.0:
125; CHECK-NEXT:    movl %edi, %eax
126; CHECK-NEXT:    cmpq $42, %rsi
127; CHECK-NEXT:    sbbl $-1, %eax
128; CHECK-NEXT:    retq
129  %b = icmp ugt i64 %x, 41
130  %s = select i1 %b, i32 1, i32 0
131  %r = add i32 %offset, %s
132  ret i32 %r
133}
134
135define i64 @select_max32_2_i64(i64 %offset, i64 %x) {
136; CHECK-LABEL: select_max32_2_i64:
137; CHECK:       # %bb.0:
138; CHECK-NEXT:    leaq 2(%rdi), %rax
139; CHECK-NEXT:    leaq 2147483647(%rdi), %rcx
140; CHECK-NEXT:    cmpq $41, %rsi
141; CHECK-NEXT:    cmovneq %rcx, %rax
142; CHECK-NEXT:    retq
143  %b = icmp ne i64 %x, 41
144  %s = select i1 %b, i64 2147483647, i64 2
145  %r = add i64 %offset, %s
146  ret i64 %r
147}
148
149define i64 @select_42_min32_i64(i64 %offset, i1 %b) {
150; CHECK-LABEL: select_42_min32_i64:
151; CHECK:       # %bb.0:
152; CHECK-NEXT:    testb $1, %sil
153; CHECK-NEXT:    movl $42, %ecx
154; CHECK-NEXT:    movl $2147483648, %eax # imm = 0x80000000
155; CHECK-NEXT:    cmovneq %rcx, %rax
156; CHECK-NEXT:    addq %rdi, %rax
157; CHECK-NEXT:    retq
158  %s = select i1 %b, i64 42, i64 2147483648
159  %r = add i64 %offset, %s
160  ret i64 %r
161}
162
163define i64 @select_big_42_i64(i64 %offset, i64 %x) {
164; CHECK-LABEL: select_big_42_i64:
165; CHECK:       # %bb.0:
166; CHECK-NEXT:    cmpq $41, %rsi
167; CHECK-NEXT:    movl $2147483649, %ecx # imm = 0x80000001
168; CHECK-NEXT:    movl $42, %eax
169; CHECK-NEXT:    cmovneq %rcx, %rax
170; CHECK-NEXT:    addq %rdi, %rax
171; CHECK-NEXT:    retq
172  %b = icmp ne i64 %x, 41
173  %s = select i1 %b, i64 2147483649, i64 42
174  %r = add i64 %s, %offset
175  ret i64 %r
176}
177
178define i64 @select_n42_big_i64(i64 %offset, i64 %x) {
179; CHECK-LABEL: select_n42_big_i64:
180; CHECK:       # %bb.0:
181; CHECK-NEXT:    cmpq $41, %rsi
182; CHECK-NEXT:    movq $-42, %rcx
183; CHECK-NEXT:    movl $2147483649, %eax # imm = 0x80000001
184; CHECK-NEXT:    cmovneq %rcx, %rax
185; CHECK-NEXT:    addq %rdi, %rax
186; CHECK-NEXT:    retq
187  %b = icmp ne i64 %x, 41
188  %s = select i1 %b, i64 -42, i64 2147483649
189  %r = add i64 %s, %offset
190  ret i64 %r
191}
192
193define i64 @select_big_bigger_i64(i64 %offset, i64 %x) {
194; CHECK-LABEL: select_big_bigger_i64:
195; CHECK:       # %bb.0:
196; CHECK-NEXT:    cmpq $41, %rsi
197; CHECK-NEXT:    movl $2147483649, %ecx # imm = 0x80000001
198; CHECK-NEXT:    movabsq $42000000000, %rax # imm = 0x9C7652400
199; CHECK-NEXT:    cmovneq %rcx, %rax
200; CHECK-NEXT:    addq %rdi, %rax
201; CHECK-NEXT:    retq
202  %b = icmp ne i64 %x, 41
203  %s = select i1 %b, i64 2147483649, i64 42000000000
204  %r = add i64 %s, %offset
205  ret i64 %r
206}
207
208define i32 @select_20_43_i32(i32 %offset, i64 %x) {
209; CHECK-LABEL: select_20_43_i32:
210; CHECK:       # %bb.0:
211; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
212; CHECK-NEXT:    leal 43(%rdi), %ecx
213; CHECK-NEXT:    leal 20(%rdi), %eax
214; CHECK-NEXT:    cmpq $42, %rsi
215; CHECK-NEXT:    cmovll %ecx, %eax
216; CHECK-NEXT:    retq
217  %b = icmp sgt i64 %x, 41
218  %s = select i1 %b, i32 20, i32 43
219  %r = add i32 %offset, %s
220  ret i32 %r
221}
222
223define i16 @select_n2_17_i16(i16 %offset, i1 %b) {
224; CHECK-LABEL: select_n2_17_i16:
225; CHECK:       # %bb.0:
226; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
227; CHECK-NEXT:    leal 17(%rdi), %ecx
228; CHECK-NEXT:    leal 65534(%rdi), %eax
229; CHECK-NEXT:    testb $1, %sil
230; CHECK-NEXT:    cmovel %ecx, %eax
231; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
232; CHECK-NEXT:    retq
233  %s = select i1 %b, i16 -2, i16 17
234  %r = add i16 %offset, %s
235  ret i16 %r
236}
237
238%class.btAxis = type { %struct.btBroadphaseProxy.base, [3 x i16], [3 x i16], ptr }
239%struct.btBroadphaseProxy.base = type <{ ptr, i16, i16, [4 x i8], ptr, i32, [4 x float], [4 x float] }>
240%struct.btBroadphaseProxy = type <{ ptr, i16, i16, [4 x i8], ptr, i32, [4 x float], [4 x float], [4 x i8] }>
241
242define ptr @bullet(i1 %b, ptr readnone %ptr, i64 %idx) {
243; CHECK-LABEL: bullet:
244; CHECK:       # %bb.0:
245; CHECK-NEXT:    leaq (%rdx,%rdx,4), %rax
246; CHECK-NEXT:    shlq $4, %rax
247; CHECK-NEXT:    leaq 60(%rsi,%rax), %rcx
248; CHECK-NEXT:    leaq 66(%rsi,%rax), %rax
249; CHECK-NEXT:    testb $1, %dil
250; CHECK-NEXT:    cmovneq %rcx, %rax
251; CHECK-NEXT:    retq
252  %gep2 = getelementptr inbounds %class.btAxis, ptr %ptr, i64 %idx, i32 2, i64 0
253  %gep1 = getelementptr inbounds %class.btAxis, ptr %ptr, i64 %idx, i32 1, i64 0
254  %sel = select i1 %b, ptr %gep1, ptr %gep2
255  ret ptr %sel
256}
257
258define ptr @bullet_alt1(i1 %b, ptr readnone %ptr, i64 %idx) {
259; CHECK-LABEL: bullet_alt1:
260; CHECK:       # %bb.0:
261; CHECK-NEXT:    leaq 60(%rsi), %rax
262; CHECK-NEXT:    leaq 66(%rsi), %rcx
263; CHECK-NEXT:    testb $1, %dil
264; CHECK-NEXT:    cmovneq %rax, %rcx
265; CHECK-NEXT:    leaq (%rdx,%rdx,4), %rax
266; CHECK-NEXT:    shlq $4, %rax
267; CHECK-NEXT:    addq %rcx, %rax
268; CHECK-NEXT:    retq
269  %idx40 = mul i64 %idx, 40
270  %gep2 = getelementptr inbounds i16, ptr %ptr, i64 33
271  %gep1 = getelementptr inbounds i16, ptr %ptr, i64 30
272  %sel = select i1 %b, ptr %gep1, ptr %gep2
273  %gep3 = getelementptr inbounds i16, ptr %sel, i64 %idx40
274  ret ptr %gep3
275}
276
277define void @bullet_load_store(i32 %x, i64 %y, ptr %p) {
278; CHECK-LABEL: bullet_load_store:
279; CHECK:       # %bb.0:
280; CHECK-NEXT:    leaq (%rsi,%rsi,4), %rax
281; CHECK-NEXT:    shlq $4, %rax
282; CHECK-NEXT:    leaq 66(%rdx), %rcx
283; CHECK-NEXT:    addq $60, %rdx
284; CHECK-NEXT:    testb $1, %dil
285; CHECK-NEXT:    cmovneq %rcx, %rdx
286; CHECK-NEXT:    decw (%rdx,%rax)
287; CHECK-NEXT:    retq
288  %and = and i32 %x, 1
289  %b = icmp eq i32 %and, 0
290  %gep2 = getelementptr inbounds %class.btAxis, ptr %p, i64 %y, i32 2, i64 0
291  %gep1 = getelementptr inbounds %class.btAxis, ptr %p, i64 %y, i32 1, i64 0
292  %sel = select i1 %b, ptr %gep1, ptr %gep2
293  %ld = load i16, ptr %sel, align 4
294  %dec = add i16 %ld, -1
295  store i16 %dec, ptr %sel, align 4
296  ret void
297}
298
299define void @complex_lea_alt1(i1 %b, ptr readnone %ptr, i64 %idx) {
300; CHECK-LABEL: complex_lea_alt1:
301; CHECK:       # %bb.0:
302; CHECK-NEXT:    leaq 60(%rdx), %rax
303; CHECK-NEXT:    addq $66, %rdx
304; CHECK-NEXT:    testb $1, %dil
305; CHECK-NEXT:    cmovneq %rax, %rdx
306; CHECK-NEXT:    decw (%rdx,%rsi)
307; CHECK-NEXT:    retq
308  %i = ptrtoint ptr %ptr to i64
309  %sum = add i64 %idx, %i
310  %base = inttoptr i64 %sum to ptr
311  %gep2 = getelementptr inbounds i16, ptr %base, i64 33
312  %gep1 = getelementptr inbounds i16, ptr %base, i64 30
313  %sel = select i1 %b, ptr %gep1, ptr %gep2
314  %ld = load i16, ptr %sel, align 4
315  %dec = add i16 %ld, -1
316  store i16 %dec, ptr %sel, align 4
317  ret void
318}
319
320define void @complex_lea_alt2(i1 %b, ptr readnone %ptr, i64 %idx) {
321; CHECK-LABEL: complex_lea_alt2:
322; CHECK:       # %bb.0:
323; CHECK-NEXT:    leaq 60(%rsi), %rax
324; CHECK-NEXT:    addq $66, %rsi
325; CHECK-NEXT:    testb $1, %dil
326; CHECK-NEXT:    cmovneq %rax, %rsi
327; CHECK-NEXT:    decw (%rsi,%rdx)
328; CHECK-NEXT:    retq
329  %i = ptrtoint ptr %ptr to i64
330  %sum = add i64 %i, %idx
331  %base = inttoptr i64 %sum to ptr
332  %gep2 = getelementptr inbounds i16, ptr %base, i64 33
333  %gep1 = getelementptr inbounds i16, ptr %base, i64 30
334  %sel = select i1 %b, ptr %gep1, ptr %gep2
335  %ld = load i16, ptr %sel, align 4
336  %dec = add i16 %ld, -1
337  store i16 %dec, ptr %sel, align 4
338  ret void
339}
340
341define void @complex_lea_alt3(i1 %b, ptr readnone %ptr, i64 %idx) {
342; CHECK-LABEL: complex_lea_alt3:
343; CHECK:       # %bb.0:
344; CHECK-NEXT:    leaq 60(%rsi), %rax
345; CHECK-NEXT:    addq $66, %rsi
346; CHECK-NEXT:    testb $1, %dil
347; CHECK-NEXT:    cmovneq %rax, %rsi
348; CHECK-NEXT:    decw (%rsi,%rdx)
349; CHECK-NEXT:    retq
350  %i = ptrtoint ptr %ptr to i64
351  %i66 = add i64 %i, 66
352  %i60 = add i64 %i, 60
353  %o66 = add i64 %i66, %idx
354  %o60 = add i64 %i60, %idx
355  %p66 = inttoptr i64 %o66 to ptr
356  %p60 = inttoptr i64 %o60 to ptr
357  %sel = select i1 %b, ptr %p60, ptr %p66
358  %ld = load i16, ptr %sel, align 4
359  %dec = add i16 %ld, -1
360  store i16 %dec, ptr %sel, align 4
361  ret void
362}
363
364define void @complex_lea_alt4(i1 %b, ptr readnone %ptr, i64 %idx) {
365; CHECK-LABEL: complex_lea_alt4:
366; CHECK:       # %bb.0:
367; CHECK-NEXT:    leaq 60(%rsi), %rax
368; CHECK-NEXT:    addq $66, %rsi
369; CHECK-NEXT:    testb $1, %dil
370; CHECK-NEXT:    cmovneq %rax, %rsi
371; CHECK-NEXT:    decw (%rdx,%rsi)
372; CHECK-NEXT:    retq
373  %i = ptrtoint ptr %ptr to i64
374  %i66 = add i64 %i, 66
375  %i60 = add i64 %i, 60
376  %o66 = add i64 %idx, %i66
377  %o60 = add i64 %idx, %i60
378  %p66 = inttoptr i64 %o66 to ptr
379  %p60 = inttoptr i64 %o60 to ptr
380  %sel = select i1 %b, ptr %p60, ptr %p66
381  %ld = load i16, ptr %sel, align 4
382  %dec = add i16 %ld, -1
383  store i16 %dec, ptr %sel, align 4
384  ret void
385}
386
387define void @complex_lea_alt5(i1 %b, ptr readnone %ptr, i64 %idx) {
388; CHECK-LABEL: complex_lea_alt5:
389; CHECK:       # %bb.0:
390; CHECK-NEXT:    leaq 60(%rdx), %rax
391; CHECK-NEXT:    addq $66, %rdx
392; CHECK-NEXT:    testb $1, %dil
393; CHECK-NEXT:    cmovneq %rax, %rdx
394; CHECK-NEXT:    decw (%rdx,%rsi)
395; CHECK-NEXT:    retq
396  %i = ptrtoint ptr %ptr to i64
397  %i66 = add i64 %idx, 66
398  %i60 = add i64 %idx, 60
399  %o66 = add i64 %i66, %i
400  %o60 = add i64 %i60, %i
401  %p66 = inttoptr i64 %o66 to ptr
402  %p60 = inttoptr i64 %o60 to ptr
403  %sel = select i1 %b, ptr %p60, ptr %p66
404  %ld = load i16, ptr %sel, align 4
405  %dec = add i16 %ld, -1
406  store i16 %dec, ptr %sel, align 4
407  ret void
408}
409
410define void @complex_lea_alt6(i1 %b, ptr readnone %ptr, i64 %idx) {
411; CHECK-LABEL: complex_lea_alt6:
412; CHECK:       # %bb.0:
413; CHECK-NEXT:    leaq 60(%rdx), %rax
414; CHECK-NEXT:    addq $66, %rdx
415; CHECK-NEXT:    testb $1, %dil
416; CHECK-NEXT:    cmovneq %rax, %rdx
417; CHECK-NEXT:    decw (%rsi,%rdx)
418; CHECK-NEXT:    retq
419  %i = ptrtoint ptr %ptr to i64
420  %i66 = add i64 %idx, 66
421  %i60 = add i64 %idx, 60
422  %o66 = add i64 %i, %i66
423  %o60 = add i64 %i, %i60
424  %p66 = inttoptr i64 %o66 to ptr
425  %p60 = inttoptr i64 %o60 to ptr
426  %sel = select i1 %b, ptr %p60, ptr %p66
427  %ld = load i16, ptr %sel, align 4
428  %dec = add i16 %ld, -1
429  store i16 %dec, ptr %sel, align 4
430  ret void
431}
432
433define void @complex_lea_alt7(i1 %b, ptr readnone %ptr, i64 %idx) {
434; CHECK-LABEL: complex_lea_alt7:
435; CHECK:       # %bb.0:
436; CHECK-NEXT:    leaq 60(%rdx), %rax
437; CHECK-NEXT:    addq $66, %rdx
438; CHECK-NEXT:    testb $1, %dil
439; CHECK-NEXT:    cmovneq %rax, %rdx
440; CHECK-NEXT:    decw (%rdx,%rsi)
441; CHECK-NEXT:    retq
442  %i = ptrtoint ptr %ptr to i64
443  %o = add i64 %idx, %i
444  %o66 = add i64 %o, 66
445  %o60 = add i64 %o, 60
446  %p66 = inttoptr i64 %o66 to ptr
447  %p60 = inttoptr i64 %o60 to ptr
448  %sel = select i1 %b, ptr %p60, ptr %p66
449  %ld = load i16, ptr %sel, align 4
450  %dec = add i16 %ld, -1
451  store i16 %dec, ptr %sel, align 4
452  ret void
453}
454
455define void @complex_lea_alt8(i1 %b, ptr readnone %ptr, i64 %idx) {
456; CHECK-LABEL: complex_lea_alt8:
457; CHECK:       # %bb.0:
458; CHECK-NEXT:    leaq 60(%rsi), %rax
459; CHECK-NEXT:    addq $66, %rsi
460; CHECK-NEXT:    testb $1, %dil
461; CHECK-NEXT:    cmovneq %rax, %rsi
462; CHECK-NEXT:    decw (%rsi,%rdx)
463; CHECK-NEXT:    retq
464  %i = ptrtoint ptr %ptr to i64
465  %o = add i64 %i, %idx
466  %o66 = add i64 %o, 66
467  %o60 = add i64 %o, 60
468  %p66 = inttoptr i64 %o66 to ptr
469  %p60 = inttoptr i64 %o60 to ptr
470  %sel = select i1 %b, ptr %p60, ptr %p66
471  %ld = load i16, ptr %sel, align 4
472  %dec = add i16 %ld, -1
473  store i16 %dec, ptr %sel, align 4
474  ret void
475}
476
477define i32 @loadfold_select_const_arms(ptr %x, i1 %y) {
478; CHECK-LABEL: loadfold_select_const_arms:
479; CHECK:       # %bb.0:
480; CHECK-NEXT:    testb $1, %sil
481; CHECK-NEXT:    movl $10, %ecx
482; CHECK-NEXT:    movl $-10, %eax
483; CHECK-NEXT:    cmovnel %ecx, %eax
484; CHECK-NEXT:    addl (%rdi), %eax
485; CHECK-NEXT:    retq
486  %cond = select i1 %y, i32 10, i32 -10
487  %t0 = load i32, ptr %x, align 4
488  %add = add nsw i32 %t0, %cond
489  ret i32 %add
490}
491
492define void @rmw_add(ptr %x, i1 %y, i32 %z, i32 %w) {
493; CHECK-LABEL: rmw_add:
494; CHECK:       # %bb.0:
495; CHECK-NEXT:    testb $1, %sil
496; CHECK-NEXT:    cmovel %ecx, %edx
497; CHECK-NEXT:    addl %edx, (%rdi)
498; CHECK-NEXT:    retq
499  %cond = select i1 %y, i32 %z, i32 %w
500  %t0 = load i32, ptr %x, align 4
501  %add = add nsw i32 %t0, %cond
502  store i32 %add, ptr %x, align 4
503  ret void
504}
505
506define void @rmw_add_select_const_arm(ptr %x, i1 %y, i32 %z) {
507; CHECK-LABEL: rmw_add_select_const_arm:
508; CHECK:       # %bb.0:
509; CHECK-NEXT:    testb $1, %sil
510; CHECK-NEXT:    movl $-10, %eax
511; CHECK-NEXT:    cmovnel %edx, %eax
512; CHECK-NEXT:    addl %eax, (%rdi)
513; CHECK-NEXT:    retq
514  %cond = select i1 %y, i32 %z, i32 -10
515  %t0 = load i32, ptr %x, align 4
516  %add = add nsw i32 %t0, %cond
517  store i32 %add, ptr %x, align 4
518  ret void
519}
520
521define void @rmw_select_const_arms(ptr %x, i1 %y) {
522; CHECK-LABEL: rmw_select_const_arms:
523; CHECK:       # %bb.0:
524; CHECK-NEXT:    testb $1, %sil
525; CHECK-NEXT:    movl $10, %eax
526; CHECK-NEXT:    movl $-10, %ecx
527; CHECK-NEXT:    cmovnel %eax, %ecx
528; CHECK-NEXT:    addl %ecx, (%rdi)
529; CHECK-NEXT:    retq
530  %cond = select i1 %y, i32 10, i32 -10
531  %t0 = load i32, ptr %x, align 4
532  %add = add nsw i32 %t0, %cond
533  store i32 %add, ptr %x, align 4
534  ret void
535}
536
537define i32 @rmw_select_const_arms_extra_load_use(ptr %x, i1 %y) {
538; CHECK-LABEL: rmw_select_const_arms_extra_load_use:
539; CHECK:       # %bb.0:
540; CHECK-NEXT:    movl (%rdi), %eax
541; CHECK-NEXT:    leal -10(%rax), %ecx
542; CHECK-NEXT:    leal 10(%rax), %edx
543; CHECK-NEXT:    testb $1, %sil
544; CHECK-NEXT:    cmovel %ecx, %edx
545; CHECK-NEXT:    movl %edx, (%rdi)
546; CHECK-NEXT:    # kill: def $eax killed $eax killed $rax
547; CHECK-NEXT:    retq
548  %cond = select i1 %y, i32 10, i32 -10
549  %t0 = load i32, ptr %x, align 4
550  %add = add nsw i32 %t0, %cond
551  store i32 %add, ptr %x, align 4
552  ret i32 %t0
553}
554
555define i32 @rmw_select_const_arms_extra_add_use(ptr %x, i1 %y) {
556; CHECK-LABEL: rmw_select_const_arms_extra_add_use:
557; CHECK:       # %bb.0:
558; CHECK-NEXT:    testb $1, %sil
559; CHECK-NEXT:    movl $10, %ecx
560; CHECK-NEXT:    movl $-10, %eax
561; CHECK-NEXT:    cmovnel %ecx, %eax
562; CHECK-NEXT:    addl (%rdi), %eax
563; CHECK-NEXT:    movl %eax, (%rdi)
564; CHECK-NEXT:    retq
565  %cond = select i1 %y, i32 10, i32 -10
566  %t0 = load i32, ptr %x, align 4
567  %add = add nsw i32 %t0, %cond
568  store i32 %add, ptr %x, align 4
569  ret i32 %add
570}
571