[Reland][Runtimes] Merge 'compile_commands.json' files from runtimes build (#116303)
[llvm-project.git] / llvm / test / CodeGen / X86 / xor-lea.ll
blob10e9525a2706a3b570b88babbcdcc68dcacfd41b
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X86
3 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=X64
4 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+bmi | FileCheck %s --check-prefixes=X64
6 ; PR52267
7 ; InstCombine transforms an 'add' with min-signed-value into an 'xor'.
8 ; LEA instruction selection should be able to see through that
9 ; transform and reduce add/shift/xor instruction counts and moves.
12 ; XOR(X,MIN_SIGNED_VALUE)
15 define i8 @xor_sminval_i8(i8 %x) {
16 ; X86-LABEL: xor_sminval_i8:
17 ; X86:       # %bb.0:
18 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
19 ; X86-NEXT:    addb $-128, %al
20 ; X86-NEXT:    retl
22 ; X64-LABEL: xor_sminval_i8:
23 ; X64:       # %bb.0:
24 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
25 ; X64-NEXT:    leal -128(%rdi), %eax
26 ; X64-NEXT:    # kill: def $al killed $al killed $eax
27 ; X64-NEXT:    retq
28   %r = xor i8 %x, 128
29   ret i8 %r
32 ; negative test
33 define i8 @xor_notsminval_i8(i8 %x) {
34 ; X86-LABEL: xor_notsminval_i8:
35 ; X86:       # %bb.0:
36 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
37 ; X86-NEXT:    xorb $127, %al
38 ; X86-NEXT:    retl
40 ; X64-LABEL: xor_notsminval_i8:
41 ; X64:       # %bb.0:
42 ; X64-NEXT:    movl %edi, %eax
43 ; X64-NEXT:    xorb $127, %al
44 ; X64-NEXT:    # kill: def $al killed $al killed $eax
45 ; X64-NEXT:    retq
46   %r = xor i8 %x, 127
47   ret i8 %r
50 define i16 @xor_sminval_i16(i16 %x) {
51 ; X86-LABEL: xor_sminval_i16:
52 ; X86:       # %bb.0:
53 ; X86-NEXT:    movl $32768, %eax # imm = 0x8000
54 ; X86-NEXT:    xorl {{[0-9]+}}(%esp), %eax
55 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
56 ; X86-NEXT:    retl
58 ; X64-LABEL: xor_sminval_i16:
59 ; X64:       # %bb.0:
60 ; X64-NEXT:    movl %edi, %eax
61 ; X64-NEXT:    xorl $32768, %eax # imm = 0x8000
62 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
63 ; X64-NEXT:    retq
64   %r = xor i16 %x, 32768
65   ret i16 %r
68 define i32 @xor_sminval_i32(i32 %x) {
69 ; X86-LABEL: xor_sminval_i32:
70 ; X86:       # %bb.0:
71 ; X86-NEXT:    movl $-2147483648, %eax # imm = 0x80000000
72 ; X86-NEXT:    xorl {{[0-9]+}}(%esp), %eax
73 ; X86-NEXT:    retl
75 ; X64-LABEL: xor_sminval_i32:
76 ; X64:       # %bb.0:
77 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
78 ; X64-NEXT:    leal -2147483648(%rdi), %eax
79 ; X64-NEXT:    retq
80   %r = xor i32 %x, 2147483648
81   ret i32 %r
84 ; negative test
85 define i32 @xor_notsminval_i32(i32 %x) {
86 ; X86-LABEL: xor_notsminval_i32:
87 ; X86:       # %bb.0:
88 ; X86-NEXT:    movl $32768, %eax # imm = 0x8000
89 ; X86-NEXT:    xorl {{[0-9]+}}(%esp), %eax
90 ; X86-NEXT:    retl
92 ; X64-LABEL: xor_notsminval_i32:
93 ; X64:       # %bb.0:
94 ; X64-NEXT:    movl %edi, %eax
95 ; X64-NEXT:    xorl $32768, %eax # imm = 0x8000
96 ; X64-NEXT:    retq
97   %r = xor i32 %x, 32768
98   ret i32 %r
101 define i64 @xor_sminval_i64(i64 %x) {
102 ; X86-LABEL: xor_sminval_i64:
103 ; X86:       # %bb.0:
104 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
105 ; X86-NEXT:    movl $-2147483648, %edx # imm = 0x80000000
106 ; X86-NEXT:    xorl {{[0-9]+}}(%esp), %edx
107 ; X86-NEXT:    retl
109 ; X64-LABEL: xor_sminval_i64:
110 ; X64:       # %bb.0:
111 ; X64-NEXT:    movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
112 ; X64-NEXT:    xorq %rdi, %rax
113 ; X64-NEXT:    retq
114   %r = xor i64 %x, -9223372036854775808
115   ret i64 %r
119 ; XOR(ADD/SUB(X,C),MIN_SIGNED_VALUE)
122 define i8 @xor_add_sminval_i8(i8 %x, i8 %y) {
123 ; X86-LABEL: xor_add_sminval_i8:
124 ; X86:       # %bb.0:
125 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
126 ; X86-NEXT:    addb {{[0-9]+}}(%esp), %al
127 ; X86-NEXT:    addb $-128, %al
128 ; X86-NEXT:    retl
130 ; X64-LABEL: xor_add_sminval_i8:
131 ; X64:       # %bb.0:
132 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
133 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
134 ; X64-NEXT:    leal (%rdi,%rsi), %eax
135 ; X64-NEXT:    addb $-128, %al
136 ; X64-NEXT:    # kill: def $al killed $al killed $eax
137 ; X64-NEXT:    retq
138   %s = add i8 %x, %y
139   %r = xor i8 %s, 128
140   ret i8 %r
143 define i16 @xor_sub_sminval_i16(i16 %x) {
144 ; X86-LABEL: xor_sub_sminval_i16:
145 ; X86:       # %bb.0:
146 ; X86-NEXT:    movl $32766, %eax # imm = 0x7FFE
147 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
148 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
149 ; X86-NEXT:    retl
151 ; X64-LABEL: xor_sub_sminval_i16:
152 ; X64:       # %bb.0:
153 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
154 ; X64-NEXT:    leal 32766(%rdi), %eax
155 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
156 ; X64-NEXT:    retq
157   %s = sub i16 %x, 2
158   %r = xor i16 %s, 32768
159   ret i16 %r
162 define i32 @xor_add_sminval_i32(i32 %x) {
163 ; X86-LABEL: xor_add_sminval_i32:
164 ; X86:       # %bb.0:
165 ; X86-NEXT:    movl $-2147483136, %eax # imm = 0x80000200
166 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
167 ; X86-NEXT:    retl
169 ; X64-LABEL: xor_add_sminval_i32:
170 ; X64:       # %bb.0:
171 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
172 ; X64-NEXT:    leal -2147483136(%rdi), %eax
173 ; X64-NEXT:    retq
174   %s = add i32 %x, 512
175   %r = xor i32 %s, 2147483648
176   ret i32 %r
179 define i64 @xor_add_sminval_i64(i64 %x, i64 %y) {
180 ; X86-LABEL: xor_add_sminval_i64:
181 ; X86:       # %bb.0:
182 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
183 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
184 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
185 ; X86-NEXT:    adcl {{[0-9]+}}(%esp), %edx
186 ; X86-NEXT:    addl $-2147483648, %edx # imm = 0x80000000
187 ; X86-NEXT:    retl
189 ; X64-LABEL: xor_add_sminval_i64:
190 ; X64:       # %bb.0:
191 ; X64-NEXT:    leaq (%rdi,%rsi), %rcx
192 ; X64-NEXT:    movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
193 ; X64-NEXT:    xorq %rcx, %rax
194 ; X64-NEXT:    retq
195   %s = add i64 %x, %y
196   %r = xor i64 %s, -9223372036854775808
197   ret i64 %r
201 ; ADD/SUB(XOR(X,MIN_SIGNED_VALUE),C)
204 define i8 @sub_xor_sminval_i8(i8 %x, i8 %y) {
205 ; X86-LABEL: sub_xor_sminval_i8:
206 ; X86:       # %bb.0:
207 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
208 ; X86-NEXT:    addb $-128, %al
209 ; X86-NEXT:    subb {{[0-9]+}}(%esp), %al
210 ; X86-NEXT:    retl
212 ; X64-LABEL: sub_xor_sminval_i8:
213 ; X64:       # %bb.0:
214 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
215 ; X64-NEXT:    leal -128(%rdi), %eax
216 ; X64-NEXT:    subb %sil, %al
217 ; X64-NEXT:    # kill: def $al killed $al killed $eax
218 ; X64-NEXT:    retq
219   %r = xor i8 %x, 128
220   %s = sub i8 %r, %y
221   ret i8 %s
224 define i16 @add_xor_sminval_i16(i16 %x) {
225 ; X86-LABEL: add_xor_sminval_i16:
226 ; X86:       # %bb.0:
227 ; X86-NEXT:    movl $-32766, %eax # imm = 0x8002
228 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
229 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
230 ; X86-NEXT:    retl
232 ; X64-LABEL: add_xor_sminval_i16:
233 ; X64:       # %bb.0:
234 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
235 ; X64-NEXT:    leal -32766(%rdi), %eax
236 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
237 ; X64-NEXT:    retq
238   %r = xor i16 %x, 32768
239   %s = add i16 %r, 2
240   ret i16 %s
243 define i32 @sub_xor_sminval_i32(i32 %x) {
244 ; X86-LABEL: sub_xor_sminval_i32:
245 ; X86:       # %bb.0:
246 ; X86-NEXT:    movl $2147483136, %eax # imm = 0x7FFFFE00
247 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
248 ; X86-NEXT:    retl
250 ; X64-LABEL: sub_xor_sminval_i32:
251 ; X64:       # %bb.0:
252 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
253 ; X64-NEXT:    leal 2147483136(%rdi), %eax
254 ; X64-NEXT:    retq
255   %r = xor i32 %x, 2147483648
256   %s = sub i32 %r, 512
257   ret i32 %s
260 define i64 @add_xor_sminval_i64(i64 %x, i64 %y) {
261 ; X86-LABEL: add_xor_sminval_i64:
262 ; X86:       # %bb.0:
263 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
264 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
265 ; X86-NEXT:    addl {{[0-9]+}}(%esp), %eax
266 ; X86-NEXT:    adcl {{[0-9]+}}(%esp), %edx
267 ; X86-NEXT:    addl $-2147483648, %edx # imm = 0x80000000
268 ; X86-NEXT:    retl
270 ; X64-LABEL: add_xor_sminval_i64:
271 ; X64:       # %bb.0:
272 ; X64-NEXT:    movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
273 ; X64-NEXT:    addq %rdi, %rax
274 ; X64-NEXT:    addq %rsi, %rax
275 ; X64-NEXT:    retq
276   %r = xor i64 %x, -9223372036854775808
277   %s = add i64 %y, %r
278   ret i64 %s
282 ; XOR(SHL(X,C),MIN_SIGNED_VALUE)
285 define i8 @xor_shl_sminval_i8(i8 %x) {
286 ; X86-LABEL: xor_shl_sminval_i8:
287 ; X86:       # %bb.0:
288 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
289 ; X86-NEXT:    addb %al, %al
290 ; X86-NEXT:    addb $-128, %al
291 ; X86-NEXT:    retl
293 ; X64-LABEL: xor_shl_sminval_i8:
294 ; X64:       # %bb.0:
295 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
296 ; X64-NEXT:    leal (%rdi,%rdi), %eax
297 ; X64-NEXT:    addb $-128, %al
298 ; X64-NEXT:    # kill: def $al killed $al killed $eax
299 ; X64-NEXT:    retq
300   %s = shl i8 %x, 1
301   %r = xor i8 %s, 128
302   ret i8 %r
305 define i16 @xor_shl_sminval_i16(i16 %x) {
306 ; X86-LABEL: xor_shl_sminval_i16:
307 ; X86:       # %bb.0:
308 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
309 ; X86-NEXT:    shll $2, %eax
310 ; X86-NEXT:    xorl $32768, %eax # imm = 0x8000
311 ; X86-NEXT:    # kill: def $ax killed $ax killed $eax
312 ; X86-NEXT:    retl
314 ; X64-LABEL: xor_shl_sminval_i16:
315 ; X64:       # %bb.0:
316 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
317 ; X64-NEXT:    leal (,%rdi,4), %eax
318 ; X64-NEXT:    xorl $32768, %eax # imm = 0x8000
319 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
320 ; X64-NEXT:    retq
321   %s = shl i16 %x, 2
322   %r = xor i16 %s, 32768
323   ret i16 %r
326 define i32 @xor_shl_sminval_i32(i32 %x) {
327 ; X86-LABEL: xor_shl_sminval_i32:
328 ; X86:       # %bb.0:
329 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
330 ; X86-NEXT:    leal -2147483648(,%eax,8), %eax
331 ; X86-NEXT:    retl
333 ; X64-LABEL: xor_shl_sminval_i32:
334 ; X64:       # %bb.0:
335 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
336 ; X64-NEXT:    leal -2147483648(,%rdi,8), %eax
337 ; X64-NEXT:    retq
338   %s = shl i32 %x, 3
339   %r = xor i32 %s, 2147483648
340   ret i32 %r
343 ; negative test
344 define i32 @xor_bigshl_sminval_i32(i32 %x) {
345 ; X86-LABEL: xor_bigshl_sminval_i32:
346 ; X86:       # %bb.0:
347 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
348 ; X86-NEXT:    shll $8, %eax
349 ; X86-NEXT:    addl $-2147483648, %eax # imm = 0x80000000
350 ; X86-NEXT:    retl
352 ; X64-LABEL: xor_bigshl_sminval_i32:
353 ; X64:       # %bb.0:
354 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
355 ; X64-NEXT:    shll $8, %edi
356 ; X64-NEXT:    leal -2147483648(%rdi), %eax
357 ; X64-NEXT:    retq
358   %s = shl i32 %x, 8
359   %r = xor i32 %s, 2147483648
360   ret i32 %r
363 define i64 @xor_shl_sminval_i64(i64 %x) {
364 ; X86-LABEL: xor_shl_sminval_i64:
365 ; X86:       # %bb.0:
366 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
367 ; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
368 ; X86-NEXT:    shldl $2, %eax, %edx
369 ; X86-NEXT:    shll $2, %eax
370 ; X86-NEXT:    addl $-2147483648, %edx # imm = 0x80000000
371 ; X86-NEXT:    retl
373 ; X64-LABEL: xor_shl_sminval_i64:
374 ; X64:       # %bb.0:
375 ; X64-NEXT:    movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
376 ; X64-NEXT:    leaq (%rax,%rdi,4), %rax
377 ; X64-NEXT:    retq
378   %s = shl i64 %x, 2
379   %r = xor i64 %s, -9223372036854775808
380   ret i64 %r