[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / llvm / test / CodeGen / X86 / combine-or.ll
blob4060355495eb3b5d1eb6a374188f6fbdd2c97630
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 | FileCheck %s -check-prefixes=CHECK,SSE
3 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -early-live-intervals | FileCheck %s -check-prefixes=CHECK,SSE
4 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7-avx | FileCheck %s -check-prefixes=CHECK,AVX,AVX1
5 ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=x86-64-v3 | FileCheck %s -check-prefixes=CHECK,AVX,AVX2
7 define i32 @or_self(i32 %x) {
8 ; CHECK-LABEL: or_self:
9 ; CHECK:       # %bb.0:
10 ; CHECK-NEXT:    movl %edi, %eax
11 ; CHECK-NEXT:    retq
12   %or = or i32 %x, %x
13   ret i32 %or
16 define <4 x i32> @or_self_vec(<4 x i32> %x) {
17 ; CHECK-LABEL: or_self_vec:
18 ; CHECK:       # %bb.0:
19 ; CHECK-NEXT:    retq
20   %or = or <4 x i32> %x, %x
21   ret <4 x i32> %or
24 ; fold (or x, c) -> c iff (x & ~c) == 0
26 define <2 x i64> @or_zext_v2i32(<2 x i32> %a0) {
27 ; SSE-LABEL: or_zext_v2i32:
28 ; SSE:       # %bb.0:
29 ; SSE-NEXT:    movaps {{.*#+}} xmm0 = [4294967295,4294967295]
30 ; SSE-NEXT:    retq
32 ; AVX-LABEL: or_zext_v2i32:
33 ; AVX:       # %bb.0:
34 ; AVX-NEXT:    vmovddup {{.*#+}} xmm0 = [4294967295,4294967295]
35 ; AVX-NEXT:    # xmm0 = mem[0,0]
36 ; AVX-NEXT:    retq
37   %1 = zext <2 x i32> %a0 to <2 x i64>
38   %2 = or <2 x i64> %1, <i64 4294967295, i64 4294967295>
39   ret <2 x i64> %2
42 define <4 x i32> @or_zext_v4i16(<4 x i16> %a0) {
43 ; SSE-LABEL: or_zext_v4i16:
44 ; SSE:       # %bb.0:
45 ; SSE-NEXT:    movaps {{.*#+}} xmm0 = [65535,65535,65535,65535]
46 ; SSE-NEXT:    retq
48 ; AVX-LABEL: or_zext_v4i16:
49 ; AVX:       # %bb.0:
50 ; AVX-NEXT:    vbroadcastss {{.*#+}} xmm0 = [65535,65535,65535,65535]
51 ; AVX-NEXT:    retq
52   %1 = zext <4 x i16> %a0 to <4 x i32>
53   %2 = or <4 x i32> %1, <i32 65535, i32 65535, i32 65535, i32 65535>
54   ret <4 x i32> %2
57 ; fold (or (and X, C1), (and (or X, Y), C2)) -> (or (and X, C1|C2), (and Y, C2))
59 define i32 @or_and_and_i32(i32 %x, i32 %y) {
60 ; CHECK-LABEL: or_and_and_i32:
61 ; CHECK:       # %bb.0:
62 ; CHECK-NEXT:    movl %edi, %eax
63 ; CHECK-NEXT:    andl $-11, %esi
64 ; CHECK-NEXT:    andl $-3, %eax
65 ; CHECK-NEXT:    orl %esi, %eax
66 ; CHECK-NEXT:    retq
67   %xy = or i32 %x, %y
68   %mx = and i32 %x, 8
69   %mxy = and i32 %xy, -11
70   %r = or i32 %mx, %mxy
71   ret i32 %r
74 define i64 @or_and_and_commute_i64(i64 %x, i64 %y) {
75 ; CHECK-LABEL: or_and_and_commute_i64:
76 ; CHECK:       # %bb.0:
77 ; CHECK-NEXT:    movq %rdi, %rax
78 ; CHECK-NEXT:    orq %rsi, %rax
79 ; CHECK-NEXT:    andq $-3, %rax
80 ; CHECK-NEXT:    retq
81   %xy = or i64 %x, %y
82   %mx = and i64 %x, 8
83   %mxy = and i64 %xy, -3
84   %r = or i64 %mxy, %mx
85   ret i64 %r
88 define <4 x i32> @or_and_and_v4i32(<4 x i32> %x, <4 x i32> %y) {
89 ; SSE-LABEL: or_and_and_v4i32:
90 ; SSE:       # %bb.0:
91 ; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1
92 ; SSE-NEXT:    andps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
93 ; SSE-NEXT:    orps %xmm1, %xmm0
94 ; SSE-NEXT:    retq
96 ; AVX-LABEL: or_and_and_v4i32:
97 ; AVX:       # %bb.0:
98 ; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1, %xmm1
99 ; AVX-NEXT:    vandps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0, %xmm0
100 ; AVX-NEXT:    vorps %xmm1, %xmm0, %xmm0
101 ; AVX-NEXT:    retq
102   %xy = or <4 x i32> %x, %y
103   %mx = and <4 x i32> %x, <i32 2, i32 4, i32 8, i32 16>
104   %mxy = and <4 x i32> %xy, <i32 1, i32 -1, i32 -5, i32 -25>
105   %r = or <4 x i32> %mx, %mxy
106   ret <4 x i32> %r
109 define i32 @or_and_and_multiuse_i32(i32 %x, i32 %y) nounwind {
110 ; CHECK-LABEL: or_and_and_multiuse_i32:
111 ; CHECK:       # %bb.0:
112 ; CHECK-NEXT:    pushq %rbx
113 ; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
114 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
115 ; CHECK-NEXT:    orl %edi, %esi
116 ; CHECK-NEXT:    andl $8, %edi
117 ; CHECK-NEXT:    andl $-11, %esi
118 ; CHECK-NEXT:    leal (%rdi,%rsi), %ebx
119 ; CHECK-NEXT:    movl %esi, %edi
120 ; CHECK-NEXT:    callq use_i32@PLT
121 ; CHECK-NEXT:    movl %ebx, %eax
122 ; CHECK-NEXT:    popq %rbx
123 ; CHECK-NEXT:    retq
124   %xy = or i32 %x, %y
125   %mx = and i32 %x, 8
126   %mxy = and i32 %xy, -11
127   %r = or i32 %mx, %mxy
128   call void @use_i32(i32 %mxy)
129   ret i32 %r
132 define i32 @or_and_multiuse_and_i32(i32 %x, i32 %y) nounwind {
133 ; CHECK-LABEL: or_and_multiuse_and_i32:
134 ; CHECK:       # %bb.0:
135 ; CHECK-NEXT:    pushq %rbx
136 ; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
137 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
138 ; CHECK-NEXT:    orl %edi, %esi
139 ; CHECK-NEXT:    andl $8, %edi
140 ; CHECK-NEXT:    andl $-11, %esi
141 ; CHECK-NEXT:    leal (%rsi,%rdi), %ebx
142 ; CHECK-NEXT:    # kill: def $edi killed $edi killed $rdi
143 ; CHECK-NEXT:    callq use_i32@PLT
144 ; CHECK-NEXT:    movl %ebx, %eax
145 ; CHECK-NEXT:    popq %rbx
146 ; CHECK-NEXT:    retq
147   %xy = or i32 %x, %y
148   %mx = and i32 %x, 8
149   %mxy = and i32 %xy, -11
150   %r = or i32 %mx, %mxy
151   call void @use_i32(i32 %mx)
152   ret i32 %r
155 define i32 @or_and_multiuse_and_multiuse_i32(i32 %x, i32 %y) nounwind {
156 ; CHECK-LABEL: or_and_multiuse_and_multiuse_i32:
157 ; CHECK:       # %bb.0:
158 ; CHECK-NEXT:    pushq %rbp
159 ; CHECK-NEXT:    pushq %rbx
160 ; CHECK-NEXT:    pushq %rax
161 ; CHECK-NEXT:    movl %esi, %ebx
162 ; CHECK-NEXT:    # kill: def $edi killed $edi def $rdi
163 ; CHECK-NEXT:    orl %edi, %ebx
164 ; CHECK-NEXT:    andl $8, %edi
165 ; CHECK-NEXT:    andl $-11, %ebx
166 ; CHECK-NEXT:    leal (%rdi,%rbx), %ebp
167 ; CHECK-NEXT:    # kill: def $edi killed $edi killed $rdi
168 ; CHECK-NEXT:    callq use_i32@PLT
169 ; CHECK-NEXT:    movl %ebx, %edi
170 ; CHECK-NEXT:    callq use_i32@PLT
171 ; CHECK-NEXT:    movl %ebp, %eax
172 ; CHECK-NEXT:    addq $8, %rsp
173 ; CHECK-NEXT:    popq %rbx
174 ; CHECK-NEXT:    popq %rbp
175 ; CHECK-NEXT:    retq
176   %xy = or i32 %x, %y
177   %mx = and i32 %x, 8
178   %mxy = and i32 %xy, -11
179   %r = or i32 %mx, %mxy
180   call void @use_i32(i32 %mx)
181   call void @use_i32(i32 %mxy)
182   ret i32 %r
185 define i64 @or_build_pair_not(i32 %a0, i32 %a1) {
186 ; CHECK-LABEL: or_build_pair_not:
187 ; CHECK:       # %bb.0:
188 ; CHECK-NEXT:    # kill: def $esi killed $esi def $rsi
189 ; CHECK-NEXT:    shlq $32, %rsi
190 ; CHECK-NEXT:    movl %edi, %eax
191 ; CHECK-NEXT:    orq %rsi, %rax
192 ; CHECK-NEXT:    notq %rax
193 ; CHECK-NEXT:    retq
194   %n0 = xor i32 %a0, -1
195   %n1 = xor i32 %a1, -1
196   %x0 = zext i32 %n0 to i64
197   %x1 = zext i32 %n1 to i64
198   %hi = shl i64 %x1, 32
199   %r = or i64 %hi, %x0
200   ret i64 %r
203 define i64 @PR89533(<64 x i8> %a0) {
204 ; SSE-LABEL: PR89533:
205 ; SSE:       # %bb.0:
206 ; SSE-NEXT:    movdqa {{.*#+}} xmm4 = [95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95]
207 ; SSE-NEXT:    pcmpeqb %xmm4, %xmm0
208 ; SSE-NEXT:    pmovmskb %xmm0, %eax
209 ; SSE-NEXT:    xorl $65535, %eax # imm = 0xFFFF
210 ; SSE-NEXT:    pcmpeqb %xmm4, %xmm1
211 ; SSE-NEXT:    pmovmskb %xmm1, %ecx
212 ; SSE-NEXT:    notl %ecx
213 ; SSE-NEXT:    shll $16, %ecx
214 ; SSE-NEXT:    orl %eax, %ecx
215 ; SSE-NEXT:    pcmpeqb %xmm4, %xmm2
216 ; SSE-NEXT:    pmovmskb %xmm2, %eax
217 ; SSE-NEXT:    xorl $65535, %eax # imm = 0xFFFF
218 ; SSE-NEXT:    pcmpeqb %xmm4, %xmm3
219 ; SSE-NEXT:    pmovmskb %xmm3, %edx
220 ; SSE-NEXT:    notl %edx
221 ; SSE-NEXT:    shll $16, %edx
222 ; SSE-NEXT:    orl %eax, %edx
223 ; SSE-NEXT:    shlq $32, %rdx
224 ; SSE-NEXT:    orq %rcx, %rdx
225 ; SSE-NEXT:    bsfq %rdx, %rcx
226 ; SSE-NEXT:    movl $64, %eax
227 ; SSE-NEXT:    cmovneq %rcx, %rax
228 ; SSE-NEXT:    retq
230 ; AVX1-LABEL: PR89533:
231 ; AVX1:       # %bb.0:
232 ; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm2 = [95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95]
233 ; AVX1-NEXT:    vpcmpeqb %xmm2, %xmm0, %xmm3
234 ; AVX1-NEXT:    vpmovmskb %xmm3, %eax
235 ; AVX1-NEXT:    xorl $65535, %eax # imm = 0xFFFF
236 ; AVX1-NEXT:    vextractf128 $1, %ymm0, %xmm0
237 ; AVX1-NEXT:    vpcmpeqb %xmm2, %xmm0, %xmm0
238 ; AVX1-NEXT:    vpmovmskb %xmm0, %ecx
239 ; AVX1-NEXT:    notl %ecx
240 ; AVX1-NEXT:    shll $16, %ecx
241 ; AVX1-NEXT:    orl %eax, %ecx
242 ; AVX1-NEXT:    vpcmpeqb %xmm2, %xmm1, %xmm0
243 ; AVX1-NEXT:    vpmovmskb %xmm0, %eax
244 ; AVX1-NEXT:    xorl $65535, %eax # imm = 0xFFFF
245 ; AVX1-NEXT:    vextractf128 $1, %ymm1, %xmm0
246 ; AVX1-NEXT:    vpcmpeqb %xmm2, %xmm0, %xmm0
247 ; AVX1-NEXT:    vpmovmskb %xmm0, %edx
248 ; AVX1-NEXT:    notl %edx
249 ; AVX1-NEXT:    shll $16, %edx
250 ; AVX1-NEXT:    orl %eax, %edx
251 ; AVX1-NEXT:    shlq $32, %rdx
252 ; AVX1-NEXT:    orq %rcx, %rdx
253 ; AVX1-NEXT:    bsfq %rdx, %rcx
254 ; AVX1-NEXT:    movl $64, %eax
255 ; AVX1-NEXT:    cmovneq %rcx, %rax
256 ; AVX1-NEXT:    vzeroupper
257 ; AVX1-NEXT:    retq
259 ; AVX2-LABEL: PR89533:
260 ; AVX2:       # %bb.0:
261 ; AVX2-NEXT:    vpbroadcastb {{.*#+}} ymm2 = [95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95]
262 ; AVX2-NEXT:    vpcmpeqb %ymm2, %ymm0, %ymm0
263 ; AVX2-NEXT:    vpmovmskb %ymm0, %eax
264 ; AVX2-NEXT:    vpcmpeqb %ymm2, %ymm1, %ymm0
265 ; AVX2-NEXT:    vpmovmskb %ymm0, %ecx
266 ; AVX2-NEXT:    shlq $32, %rcx
267 ; AVX2-NEXT:    orq %rax, %rcx
268 ; AVX2-NEXT:    notq %rcx
269 ; AVX2-NEXT:    xorl %eax, %eax
270 ; AVX2-NEXT:    tzcntq %rcx, %rax
271 ; AVX2-NEXT:    vzeroupper
272 ; AVX2-NEXT:    retq
273   %cmp = icmp ne <64 x i8> %a0, <i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95, i8 95>
274   %mask = bitcast <64 x i1> %cmp to i64
275   %tz = tail call i64 @llvm.cttz.i64(i64 %mask, i1 false)
276   ret i64 %tz
279 declare void @use_i32(i32)