1 ; RUN: llc < %s -asm-verbose=false -mtriple=x86_64-unknown-linux | FileCheck %s --check-prefix=CHECK --check-prefix=CMOV
2 ; RUN: llc < %s -asm-verbose=false -mtriple=i686-unknown-linux | FileCheck %s --check-prefix=CHECK --check-prefix=NOCMOV
4 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
6 ; Test 2xCMOV patterns exposed after legalization.
7 ; One way to do that is with (select (fcmp une/oeq)), which gets
8 ; legalized to setp/setne.
10 ; CHECK-LABEL: test_select_fcmp_oeq_i32:
12 ; CMOV-NEXT: ucomiss %xmm1, %xmm0
13 ; CMOV-NEXT: cmovnel %esi, %edi
14 ; CMOV-NEXT: cmovpl %esi, %edi
15 ; CMOV-NEXT: movl %edi, %eax
18 ; NOCMOV-NEXT: flds 8(%esp)
19 ; NOCMOV-NEXT: flds 4(%esp)
20 ; NOCMOV-NEXT: fucompp
21 ; NOCMOV-NEXT: fnstsw %ax
23 ; NOCMOV-NEXT: leal 16(%esp), %eax
24 ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
25 ; NOCMOV-NEXT: jp [[TBB]]
26 ; NOCMOV-NEXT: leal 12(%esp), %eax
27 ; NOCMOV-NEXT:[[TBB]]:
28 ; NOCMOV-NEXT: movl (%eax), %eax
30 define i32 @test_select_fcmp_oeq_i32(float %a, float %b, i32 %c, i32 %d) #0 {
32 %cmp = fcmp oeq float %a, %b
33 %r = select i1 %cmp, i32 %c, i32 %d
37 ; CHECK-LABEL: test_select_fcmp_oeq_i64:
39 ; CMOV-NEXT: ucomiss %xmm1, %xmm0
40 ; CMOV-NEXT: cmovneq %rsi, %rdi
41 ; CMOV-NEXT: cmovpq %rsi, %rdi
42 ; CMOV-NEXT: movq %rdi, %rax
45 ; NOCMOV-NEXT: flds 8(%esp)
46 ; NOCMOV-NEXT: flds 4(%esp)
47 ; NOCMOV-NEXT: fucompp
48 ; NOCMOV-NEXT: fnstsw %ax
50 ; NOCMOV-NEXT: leal 20(%esp), %ecx
51 ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
52 ; NOCMOV-NEXT: jp [[TBB]]
53 ; NOCMOV-NEXT: leal 12(%esp), %ecx
54 ; NOCMOV-NEXT: [[TBB]]:
55 ; NOCMOV-NEXT: movl (%ecx), %eax
56 ; NOCMOV-NEXT: orl $4, %ecx
57 ; NOCMOV-NEXT: movl (%ecx), %edx
59 define i64 @test_select_fcmp_oeq_i64(float %a, float %b, i64 %c, i64 %d) #0 {
61 %cmp = fcmp oeq float %a, %b
62 %r = select i1 %cmp, i64 %c, i64 %d
66 ; CHECK-LABEL: test_select_fcmp_une_i64:
68 ; CMOV-NEXT: ucomiss %xmm1, %xmm0
69 ; CMOV-NEXT: cmovneq %rdi, %rsi
70 ; CMOV-NEXT: cmovpq %rdi, %rsi
71 ; CMOV-NEXT: movq %rsi, %rax
74 ; NOCMOV-NEXT: flds 8(%esp)
75 ; NOCMOV-NEXT: flds 4(%esp)
76 ; NOCMOV-NEXT: fucompp
77 ; NOCMOV-NEXT: fnstsw %ax
79 ; NOCMOV-NEXT: leal 12(%esp), %ecx
80 ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
81 ; NOCMOV-NEXT: jp [[TBB]]
82 ; NOCMOV-NEXT: leal 20(%esp), %ecx
83 ; NOCMOV-NEXT: [[TBB]]:
84 ; NOCMOV-NEXT: movl (%ecx), %eax
85 ; NOCMOV-NEXT: orl $4, %ecx
86 ; NOCMOV-NEXT: movl (%ecx), %edx
88 define i64 @test_select_fcmp_une_i64(float %a, float %b, i64 %c, i64 %d) #0 {
90 %cmp = fcmp une float %a, %b
91 %r = select i1 %cmp, i64 %c, i64 %d
95 ; CHECK-LABEL: test_select_fcmp_oeq_f64:
97 ; CMOV-NEXT: ucomiss %xmm1, %xmm0
98 ; CMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
99 ; CMOV-NEXT: jp [[TBB]]
100 ; CMOV-NEXT: movaps %xmm2, %xmm3
101 ; CMOV-NEXT: [[TBB]]:
102 ; CMOV-NEXT: movaps %xmm3, %xmm0
105 ; NOCMOV-NEXT: flds 8(%esp)
106 ; NOCMOV-NEXT: flds 4(%esp)
107 ; NOCMOV-NEXT: fucompp
108 ; NOCMOV-NEXT: fnstsw %ax
110 ; NOCMOV-NEXT: leal 20(%esp), %eax
111 ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
112 ; NOCMOV-NEXT: jp [[TBB]]
113 ; NOCMOV-NEXT: leal 12(%esp), %eax
114 ; NOCMOV-NEXT: [[TBB]]:
115 ; NOCMOV-NEXT: fldl (%eax)
117 define double @test_select_fcmp_oeq_f64(float %a, float %b, double %c, double %d) #0 {
119 %cmp = fcmp oeq float %a, %b
120 %r = select i1 %cmp, double %c, double %d
124 ; CHECK-LABEL: test_select_fcmp_oeq_v4i32:
126 ; CMOV-NEXT: ucomiss %xmm1, %xmm0
127 ; CMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
128 ; CMOV-NEXT: jp [[TBB]]
129 ; CMOV-NEXT: movaps %xmm2, %xmm3
130 ; CMOV-NEXT: [[TBB]]:
131 ; CMOV-NEXT: movaps %xmm3, %xmm0
134 ; NOCMOV-NEXT: pushl %edi
135 ; NOCMOV-NEXT: pushl %esi
136 ; NOCMOV-NEXT: flds 20(%esp)
137 ; NOCMOV-NEXT: flds 16(%esp)
138 ; NOCMOV-NEXT: fucompp
139 ; NOCMOV-NEXT: fnstsw %ax
141 ; NOCMOV-NEXT: leal 40(%esp), %eax
142 ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
143 ; NOCMOV-NEXT: jp [[TBB]]
144 ; NOCMOV-NEXT: leal 24(%esp), %eax
145 ; NOCMOV-NEXT: [[TBB]]:
146 ; NOCMOV-NEXT: movl (%eax), %ecx
147 ; NOCMOV-NEXT: leal 44(%esp), %edx
148 ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
149 ; NOCMOV-NEXT: jp [[TBB]]
150 ; NOCMOV-NEXT: leal 28(%esp), %edx
151 ; NOCMOV-NEXT: [[TBB]]:
152 ; NOCMOV-NEXT: movl 12(%esp), %eax
153 ; NOCMOV-NEXT: movl (%edx), %edx
154 ; NOCMOV-NEXT: leal 48(%esp), %esi
155 ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
156 ; NOCMOV-NEXT: jp [[TBB]]
157 ; NOCMOV-NEXT: leal 32(%esp), %esi
158 ; NOCMOV-NEXT: [[TBB]]:
159 ; NOCMOV-NEXT: movl (%esi), %esi
160 ; NOCMOV-NEXT: leal 52(%esp), %edi
161 ; NOCMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
162 ; NOCMOV-NEXT: jp [[TBB]]
163 ; NOCMOV-NEXT: leal 36(%esp), %edi
164 ; NOCMOV-NEXT: [[TBB]]:
165 ; NOCMOV-NEXT: movl (%edi), %edi
166 ; NOCMOV-NEXT: movl %edi, 12(%eax)
167 ; NOCMOV-NEXT: movl %esi, 8(%eax)
168 ; NOCMOV-NEXT: movl %edx, 4(%eax)
169 ; NOCMOV-NEXT: movl %ecx, (%eax)
170 ; NOCMOV-NEXT: popl %esi
171 ; NOCMOV-NEXT: popl %edi
172 ; NOCMOV-NEXT: retl $4
173 define <4 x i32> @test_select_fcmp_oeq_v4i32(float %a, float %b, <4 x i32> %c, <4 x i32> %d) #0 {
175 %cmp = fcmp oeq float %a, %b
176 %r = select i1 %cmp, <4 x i32> %c, <4 x i32> %d
180 ; Also make sure we catch the original code-sequence of interest:
182 ; CMOV: [[ONE_F32_LCPI:.LCPI.*]]:
183 ; CMOV-NEXT: .long 1065353216
185 ; CHECK-LABEL: test_zext_fcmp_une:
186 ; CMOV-NEXT: ucomiss %xmm1, %xmm0
187 ; CMOV-NEXT: movss [[ONE_F32_LCPI]](%rip), %xmm0
188 ; CMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
189 ; CMOV-NEXT: jp [[TBB]]
190 ; CMOV-NEXT: xorps %xmm0, %xmm0
191 ; CMOV-NEXT: [[TBB]]:
196 define float @test_zext_fcmp_une(float %a, float %b) #0 {
198 %cmp = fcmp une float %a, %b
199 %conv1 = zext i1 %cmp to i32
200 %conv2 = sitofp i32 %conv1 to float
204 ; CMOV: [[ONE_F32_LCPI:.LCPI.*]]:
205 ; CMOV-NEXT: .long 1065353216
207 ; CHECK-LABEL: test_zext_fcmp_oeq:
208 ; CMOV-NEXT: ucomiss %xmm1, %xmm0
209 ; CMOV-NEXT: xorps %xmm0, %xmm0
210 ; CMOV-NEXT: jne [[TBB:.LBB[0-9_]+]]
211 ; CMOV-NEXT: jp [[TBB]]
212 ; CMOV-NEXT: movss [[ONE_F32_LCPI]](%rip), %xmm0
213 ; CMOV-NEXT: [[TBB]]:
218 define float @test_zext_fcmp_oeq(float %a, float %b) #0 {
220 %cmp = fcmp oeq float %a, %b
221 %conv1 = zext i1 %cmp to i32
222 %conv2 = sitofp i32 %conv1 to float
226 attributes #0 = { nounwind }