1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2   | FileCheck %s --check-prefixes=SSE,SSE2
3; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.2 | FileCheck %s --check-prefixes=SSE,SSE42
4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx    | FileCheck %s --check-prefix=AVX
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2   | FileCheck %s --check-prefix=AVX
6
7; PR28925
8
9define <4 x i32> @test1(<4 x i1> %cond, <4 x i32> %x) {
10; SSE-LABEL: test1:
11; SSE:       # %bb.0:
12; SSE-NEXT:    pslld $31, %xmm0
13; SSE-NEXT:    psrad $31, %xmm0
14; SSE-NEXT:    pandn %xmm1, %xmm0
15; SSE-NEXT:    retq
16;
17; AVX-LABEL: test1:
18; AVX:       # %bb.0:
19; AVX-NEXT:    vpslld $31, %xmm0, %xmm0
20; AVX-NEXT:    vpsrad $31, %xmm0, %xmm0
21; AVX-NEXT:    vpandn %xmm1, %xmm0, %xmm0
22; AVX-NEXT:    retq
23  %r = select <4 x i1> %cond, <4 x i32> zeroinitializer, <4 x i32> %x
24  ret <4 x i32> %r
25}
26
27define <4 x i32> @test2(<4 x float> %a, <4 x float> %b, <4 x i32> %x) {
28; SSE-LABEL: test2:
29; SSE:       # %bb.0:
30; SSE-NEXT:    cmpneqps %xmm1, %xmm0
31; SSE-NEXT:    andps %xmm2, %xmm0
32; SSE-NEXT:    retq
33;
34; AVX-LABEL: test2:
35; AVX:       # %bb.0:
36; AVX-NEXT:    vcmpneqps %xmm1, %xmm0, %xmm0
37; AVX-NEXT:    vandps %xmm2, %xmm0, %xmm0
38; AVX-NEXT:    retq
39  %cond = fcmp oeq <4 x float> %a, %b
40  %r = select <4 x i1> %cond, <4 x i32> zeroinitializer, <4 x i32> %x
41  ret <4 x i32> %r
42}
43
44define float @fsel_zero_false_val(float %a, float %b, float %x) {
45; SSE-LABEL: fsel_zero_false_val:
46; SSE:       # %bb.0:
47; SSE-NEXT:    cmpeqss %xmm1, %xmm0
48; SSE-NEXT:    andps %xmm2, %xmm0
49; SSE-NEXT:    retq
50;
51; AVX-LABEL: fsel_zero_false_val:
52; AVX:       # %bb.0:
53; AVX-NEXT:    vcmpeqss %xmm1, %xmm0, %xmm0
54; AVX-NEXT:    vandps %xmm2, %xmm0, %xmm0
55; AVX-NEXT:    retq
56  %cond = fcmp oeq float %a, %b
57  %r = select i1 %cond, float %x, float 0.0
58  ret float %r
59}
60
61define float @fsel_zero_true_val(float %a, float %b, float %x) {
62; SSE-LABEL: fsel_zero_true_val:
63; SSE:       # %bb.0:
64; SSE-NEXT:    cmpeqss %xmm1, %xmm0
65; SSE-NEXT:    andnps %xmm2, %xmm0
66; SSE-NEXT:    retq
67;
68; AVX-LABEL: fsel_zero_true_val:
69; AVX:       # %bb.0:
70; AVX-NEXT:    vcmpeqss %xmm1, %xmm0, %xmm0
71; AVX-NEXT:    vandnps %xmm2, %xmm0, %xmm0
72; AVX-NEXT:    retq
73  %cond = fcmp oeq float %a, %b
74  %r = select i1 %cond, float 0.0, float %x
75  ret float %r
76}
77
78define double @fsel_nonzero_false_val(double %x, double %y, double %z) {
79; SSE-LABEL: fsel_nonzero_false_val:
80; SSE:       # %bb.0:
81; SSE-NEXT:    cmpeqsd %xmm1, %xmm0
82; SSE-NEXT:    andpd %xmm0, %xmm2
83; SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
84; SSE-NEXT:    andnpd %xmm1, %xmm0
85; SSE-NEXT:    orpd %xmm2, %xmm0
86; SSE-NEXT:    retq
87;
88; AVX-LABEL: fsel_nonzero_false_val:
89; AVX:       # %bb.0:
90; AVX-NEXT:    vcmpeqsd %xmm1, %xmm0, %xmm0
91; AVX-NEXT:    vmovsd {{.*#+}} xmm1 = mem[0],zero
92; AVX-NEXT:    vblendvpd %xmm0, %xmm2, %xmm1, %xmm0
93; AVX-NEXT:    retq
94  %cond = fcmp oeq double %x, %y
95  %r = select i1 %cond, double %z, double 42.0
96  ret double %r
97}
98
99define double @fsel_nonzero_true_val(double %x, double %y, double %z) {
100; SSE-LABEL: fsel_nonzero_true_val:
101; SSE:       # %bb.0:
102; SSE-NEXT:    cmpeqsd %xmm1, %xmm0
103; SSE-NEXT:    movsd {{.*#+}} xmm1 = mem[0],zero
104; SSE-NEXT:    andpd %xmm0, %xmm1
105; SSE-NEXT:    andnpd %xmm2, %xmm0
106; SSE-NEXT:    orpd %xmm1, %xmm0
107; SSE-NEXT:    retq
108;
109; AVX-LABEL: fsel_nonzero_true_val:
110; AVX:       # %bb.0:
111; AVX-NEXT:    vcmpeqsd %xmm1, %xmm0, %xmm0
112; AVX-NEXT:    vmovsd {{.*#+}} xmm1 = mem[0],zero
113; AVX-NEXT:    vblendvpd %xmm0, %xmm1, %xmm2, %xmm0
114; AVX-NEXT:    retq
115  %cond = fcmp oeq double %x, %y
116  %r = select i1 %cond, double 42.0, double %z
117  ret double %r
118}
119
120define double @fsel_nonzero_constants(double %x, double %y) {
121; SSE-LABEL: fsel_nonzero_constants:
122; SSE:       # %bb.0:
123; SSE-NEXT:    cmpeqsd %xmm1, %xmm0
124; SSE-NEXT:    movq %xmm0, %rax
125; SSE-NEXT:    andl $1, %eax
126; SSE-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
127; SSE-NEXT:    retq
128;
129; AVX-LABEL: fsel_nonzero_constants:
130; AVX:       # %bb.0:
131; AVX-NEXT:    vcmpeqsd %xmm1, %xmm0, %xmm0
132; AVX-NEXT:    vmovsd {{.*#+}} xmm1 = mem[0],zero
133; AVX-NEXT:    vmovsd {{.*#+}} xmm2 = mem[0],zero
134; AVX-NEXT:    vblendvpd %xmm0, %xmm1, %xmm2, %xmm0
135; AVX-NEXT:    retq
136  %cond = fcmp oeq double %x, %y
137  %r = select i1 %cond, double 12.0, double 42.0
138  ret double %r
139}
140
141define <2 x double> @vsel_nonzero_constants(<2 x double> %x, <2 x double> %y) {
142; SSE2-LABEL: vsel_nonzero_constants:
143; SSE2:       # %bb.0:
144; SSE2-NEXT:    cmplepd %xmm0, %xmm1
145; SSE2-NEXT:    movsd {{.*#+}} xmm0 = mem[0],zero
146; SSE2-NEXT:    movapd %xmm1, %xmm2
147; SSE2-NEXT:    andnpd %xmm0, %xmm2
148; SSE2-NEXT:    andpd {{.*}}(%rip), %xmm1
149; SSE2-NEXT:    orpd %xmm2, %xmm1
150; SSE2-NEXT:    movapd %xmm1, %xmm0
151; SSE2-NEXT:    retq
152;
153; SSE42-LABEL: vsel_nonzero_constants:
154; SSE42:       # %bb.0:
155; SSE42-NEXT:    cmplepd %xmm0, %xmm1
156; SSE42-NEXT:    movsd {{.*#+}} xmm2 = mem[0],zero
157; SSE42-NEXT:    movapd %xmm1, %xmm0
158; SSE42-NEXT:    blendvpd %xmm0, {{.*}}(%rip), %xmm2
159; SSE42-NEXT:    movapd %xmm2, %xmm0
160; SSE42-NEXT:    retq
161;
162; AVX-LABEL: vsel_nonzero_constants:
163; AVX:       # %bb.0:
164; AVX-NEXT:    vcmplepd %xmm0, %xmm1, %xmm0
165; AVX-NEXT:    vmovsd {{.*#+}} xmm1 = mem[0],zero
166; AVX-NEXT:    vblendvpd %xmm0, {{.*}}(%rip), %xmm1, %xmm0
167; AVX-NEXT:    retq
168  %cond = fcmp oge <2 x double> %x, %y
169  %r = select <2 x i1> %cond, <2 x double> <double 12.0, double -1.0>, <2 x double> <double 42.0, double 0.0>
170  ret <2 x double> %r
171}
172
173