xref: /llvm-project/llvm/test/CodeGen/X86/apx/cfcmov.ll (revision 943cc71a6cfc52a88a413ab093c2d1e3f12d55e0)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+cf -verify-machineinstrs | FileCheck %s
3; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+cf -x86-cmov-converter=false -verify-machineinstrs | FileCheck %s
4
5define i8 @cfcmov8rr(i8 %0) {
6; CHECK-LABEL: cfcmov8rr:
7; CHECK:       # %bb.0:
8; CHECK-NEXT:    cmpb $1, %dil
9; CHECK-NEXT:    cfcmovel %edi, %eax
10; CHECK-NEXT:    # kill: def $al killed $al killed $eax
11; CHECK-NEXT:    retq
12  %2 = icmp eq i8 %0, 1
13  %3 = select i1 %2, i8 %0, i8 0
14  ret i8 %3
15}
16
17define i16 @cfcmov16rr(i16 %0) {
18; CHECK-LABEL: cfcmov16rr:
19; CHECK:       # %bb.0:
20; CHECK-NEXT:    cmpw $1, %di
21; CHECK-NEXT:    cfcmovnel %edi, %eax
22; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
23; CHECK-NEXT:    retq
24  %2 = icmp ne i16 %0, 1
25  %3 = select i1 %2, i16 %0, i16 0
26  ret i16 %3
27}
28
29define i32 @cfcmov32rr(i32 %0) {
30; CHECK-LABEL: cfcmov32rr:
31; CHECK:       # %bb.0:
32; CHECK-NEXT:    cmpl $2, %edi
33; CHECK-NEXT:    cfcmovael %edi, %eax
34; CHECK-NEXT:    retq
35  %2 = icmp ugt i32 %0, 1
36  %3 = select i1 %2, i32 %0, i32 0
37  ret i32 %3
38}
39
40define i64 @cfcmov64rr(i64 %0) {
41; CHECK-LABEL: cfcmov64rr:
42; CHECK:       # %bb.0:
43; CHECK-NEXT:    testq %rdi, %rdi
44; CHECK-NEXT:    cfcmoveq %rdi, %rax
45; CHECK-NEXT:    retq
46  %2 = icmp ult i64 %0, 1
47  %3 = select i1 %2, i64 %0, i64 0
48  ret i64 %3
49}
50
51define i8 @cfcmov8rr_inv(i8 %0) {
52; CHECK-LABEL: cfcmov8rr_inv:
53; CHECK:       # %bb.0:
54; CHECK-NEXT:    cmpb $1, %dil
55; CHECK-NEXT:    cfcmovnel %edi, %eax
56; CHECK-NEXT:    # kill: def $al killed $al killed $eax
57; CHECK-NEXT:    retq
58  %2 = icmp eq i8 %0, 1
59  %3 = select i1 %2, i8 0, i8 %0
60  ret i8 %3
61}
62
63define i16 @cfcmov16rr_inv(i16 %0) {
64; CHECK-LABEL: cfcmov16rr_inv:
65; CHECK:       # %bb.0:
66; CHECK-NEXT:    cmpw $1, %di
67; CHECK-NEXT:    cfcmovel %edi, %eax
68; CHECK-NEXT:    # kill: def $ax killed $ax killed $eax
69; CHECK-NEXT:    retq
70  %2 = icmp ne i16 %0, 1
71  %3 = select i1 %2, i16 0, i16 %0
72  ret i16 %3
73}
74
75define i32 @cfcmov32rr_inv(i32 %0) {
76; CHECK-LABEL: cfcmov32rr_inv:
77; CHECK:       # %bb.0:
78; CHECK-NEXT:    cmpl $2, %edi
79; CHECK-NEXT:    cfcmovbl %edi, %eax
80; CHECK-NEXT:    retq
81  %2 = icmp ugt i32 %0, 1
82  %3 = select i1 %2, i32 0, i32 %0
83  ret i32 %3
84}
85
86define i64 @cfcmov64rr_inv(i64 %0) {
87; CHECK-LABEL: cfcmov64rr_inv:
88; CHECK:       # %bb.0:
89; CHECK-NEXT:    cmpq $2, %rdi
90; CHECK-NEXT:    cfcmovaeq %rdi, %rax
91; CHECK-NEXT:    retq
92  %2 = icmp ule i64 %0, 1
93  %3 = select i1 %2, i64 0, i64 %0
94  ret i64 %3
95}
96
97define void @cfcmov16mr(ptr %p, i16 %0) {
98; CHECK-LABEL: cfcmov16mr:
99; CHECK:       # %bb.0:
100; CHECK-NEXT:    movzwl (%rdi), %eax
101; CHECK-NEXT:    cmpw %ax, %si
102; CHECK-NEXT:    cfcmovlew %si, (%rdi)
103; CHECK-NEXT:    retq
104  %2 = load i16, ptr %p, align 2
105  %3 = icmp sgt i16 %0, %2
106  %4 = select i1 %3, i16 %2, i16 %0
107  store i16 %4, ptr %p, align 2
108  ret void
109}
110
111define void @cfcmov32mr(ptr %p, i32 %0) {
112; CHECK-LABEL: cfcmov32mr:
113; CHECK:       # %bb.0:
114; CHECK-NEXT:    cmpl (%rdi), %esi
115; CHECK-NEXT:    cfcmovgl %esi, (%rdi)
116; CHECK-NEXT:    retq
117  %2 = load i32, ptr %p, align 4
118  %3 = call i32 @llvm.smax.i32(i32 %0, i32 %2)
119  store i32 %3, ptr %p, align 4
120  ret void
121}
122
123define void @cfcmov64mr(ptr %p, i64 %0) {
124; CHECK-LABEL: cfcmov64mr:
125; CHECK:       # %bb.0:
126; CHECK-NEXT:    cmpq (%rdi), %rsi
127; CHECK-NEXT:    cfcmovgq %rsi, (%rdi)
128; CHECK-NEXT:    retq
129  %2 = load i64, ptr %p, align 8
130  %3 = icmp sgt i64 %0, %2
131  %4 = select i1 %3, i64 %0, i64 %2
132  store i64 %4, ptr %p, align 8
133  ret void
134}
135
136define void @volatileload(ptr %p, i32 %0) {
137; CHECK-LABEL: volatileload:
138; CHECK:       # %bb.0:
139; CHECK-NEXT:    movl (%rdi), %eax
140; CHECK-NEXT:    cmpl %eax, %esi
141; CHECK-NEXT:    cmovbl %esi, %eax
142; CHECK-NEXT:    movl %eax, (%rdi)
143; CHECK-NEXT:    retq
144  %2 = load volatile i32, ptr %p, align 4
145  %3 = call i32 @llvm.umin.i32(i32 %0, i32 %2)
146  store i32 %3, ptr %p, align 4
147  ret void
148}
149
150define void @atomicstore(ptr %p, i64 %0) {
151; CHECK-LABEL: atomicstore:
152; CHECK:       # %bb.0:
153; CHECK-NEXT:    movq (%rdi), %rax
154; CHECK-NEXT:    cmpq %rax, %rsi
155; CHECK-NEXT:    cmovaq %rsi, %rax
156; CHECK-NEXT:    movq %rax, (%rdi)
157; CHECK-NEXT:    retq
158  %2 = load i64, ptr %p, align 8
159  %3 = icmp ugt i64 %0, %2
160  %4 = select i1 %3, i64 %0, i64 %2
161  store atomic i64 %4, ptr %p unordered, align 8
162  ret void
163}
164
165define void @loadstorediffptr(ptr %p, i32 %0) {
166; CHECK-LABEL: loadstorediffptr:
167; CHECK:       # %bb.0:
168; CHECK-NEXT:    movl (%rdi), %eax
169; CHECK-NEXT:    cmpl %eax, %esi
170; CHECK-NEXT:    cmovbel %eax, %esi
171; CHECK-NEXT:    movl %esi, 4(%rdi)
172; CHECK-NEXT:    retq
173  %2 = getelementptr [2 x i32], ptr %p, i32 0, i32 0
174  %3 = load i32, ptr %2, align 4
175  %4 = icmp ule i32 %0, %3
176  %5 = select i1 %4, i32 %3, i32 %0
177  %6 = getelementptr [2 x i32], ptr %p, i32 0, i32 1
178  store i32 %5, ptr %6, align 4
179  ret void
180}
181
182declare i32 @llvm.smax.i32(i32, i32)
183declare i32 @llvm.umin.i32(i32, i32)
184