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
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:
18 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
19 ; X86-NEXT: addb $-128, %al
22 ; X64-LABEL: xor_sminval_i8:
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
33 define i8 @xor_notsminval_i8(i8 %x) {
34 ; X86-LABEL: xor_notsminval_i8:
36 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
37 ; X86-NEXT: xorb $127, %al
40 ; X64-LABEL: xor_notsminval_i8:
42 ; X64-NEXT: movl %edi, %eax
43 ; X64-NEXT: xorb $127, %al
44 ; X64-NEXT: # kill: def $al killed $al killed $eax
50 define i16 @xor_sminval_i16(i16 %x) {
51 ; X86-LABEL: xor_sminval_i16:
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
58 ; X64-LABEL: xor_sminval_i16:
60 ; X64-NEXT: movl %edi, %eax
61 ; X64-NEXT: xorl $32768, %eax # imm = 0x8000
62 ; X64-NEXT: # kill: def $ax killed $ax killed $eax
64 %r = xor i16 %x, 32768
68 define i32 @xor_sminval_i32(i32 %x) {
69 ; X86-LABEL: xor_sminval_i32:
71 ; X86-NEXT: movl $-2147483648, %eax # imm = 0x80000000
72 ; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax
75 ; X64-LABEL: xor_sminval_i32:
77 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
78 ; X64-NEXT: leal -2147483648(%rdi), %eax
80 %r = xor i32 %x, 2147483648
85 define i32 @xor_notsminval_i32(i32 %x) {
86 ; X86-LABEL: xor_notsminval_i32:
88 ; X86-NEXT: movl $32768, %eax # imm = 0x8000
89 ; X86-NEXT: xorl {{[0-9]+}}(%esp), %eax
92 ; X64-LABEL: xor_notsminval_i32:
94 ; X64-NEXT: movl %edi, %eax
95 ; X64-NEXT: xorl $32768, %eax # imm = 0x8000
97 %r = xor i32 %x, 32768
101 define i64 @xor_sminval_i64(i64 %x) {
102 ; X86-LABEL: xor_sminval_i64:
104 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
105 ; X86-NEXT: movl $-2147483648, %edx # imm = 0x80000000
106 ; X86-NEXT: xorl {{[0-9]+}}(%esp), %edx
109 ; X64-LABEL: xor_sminval_i64:
111 ; X64-NEXT: movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
112 ; X64-NEXT: xorq %rdi, %rax
114 %r = xor i64 %x, -9223372036854775808
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:
125 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
126 ; X86-NEXT: addb {{[0-9]+}}(%esp), %al
127 ; X86-NEXT: addb $-128, %al
130 ; X64-LABEL: xor_add_sminval_i8:
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
143 define i16 @xor_sub_sminval_i16(i16 %x) {
144 ; X86-LABEL: xor_sub_sminval_i16:
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
151 ; X64-LABEL: xor_sub_sminval_i16:
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
158 %r = xor i16 %s, 32768
162 define i32 @xor_add_sminval_i32(i32 %x) {
163 ; X86-LABEL: xor_add_sminval_i32:
165 ; X86-NEXT: movl $-2147483136, %eax # imm = 0x80000200
166 ; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
169 ; X64-LABEL: xor_add_sminval_i32:
171 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
172 ; X64-NEXT: leal -2147483136(%rdi), %eax
175 %r = xor i32 %s, 2147483648
179 define i64 @xor_add_sminval_i64(i64 %x, i64 %y) {
180 ; X86-LABEL: xor_add_sminval_i64:
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
189 ; X64-LABEL: xor_add_sminval_i64:
191 ; X64-NEXT: leaq (%rdi,%rsi), %rcx
192 ; X64-NEXT: movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
193 ; X64-NEXT: xorq %rcx, %rax
196 %r = xor i64 %s, -9223372036854775808
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:
207 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
208 ; X86-NEXT: addb $-128, %al
209 ; X86-NEXT: subb {{[0-9]+}}(%esp), %al
212 ; X64-LABEL: sub_xor_sminval_i8:
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
224 define i16 @add_xor_sminval_i16(i16 %x) {
225 ; X86-LABEL: add_xor_sminval_i16:
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
232 ; X64-LABEL: add_xor_sminval_i16:
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
238 %r = xor i16 %x, 32768
243 define i32 @sub_xor_sminval_i32(i32 %x) {
244 ; X86-LABEL: sub_xor_sminval_i32:
246 ; X86-NEXT: movl $2147483136, %eax # imm = 0x7FFFFE00
247 ; X86-NEXT: addl {{[0-9]+}}(%esp), %eax
250 ; X64-LABEL: sub_xor_sminval_i32:
252 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
253 ; X64-NEXT: leal 2147483136(%rdi), %eax
255 %r = xor i32 %x, 2147483648
260 define i64 @add_xor_sminval_i64(i64 %x, i64 %y) {
261 ; X86-LABEL: add_xor_sminval_i64:
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
270 ; X64-LABEL: add_xor_sminval_i64:
272 ; X64-NEXT: movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
273 ; X64-NEXT: addq %rdi, %rax
274 ; X64-NEXT: addq %rsi, %rax
276 %r = xor i64 %x, -9223372036854775808
282 ; XOR(SHL(X,C),MIN_SIGNED_VALUE)
285 define i8 @xor_shl_sminval_i8(i8 %x) {
286 ; X86-LABEL: xor_shl_sminval_i8:
288 ; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax
289 ; X86-NEXT: addb %al, %al
290 ; X86-NEXT: addb $-128, %al
293 ; X64-LABEL: xor_shl_sminval_i8:
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
305 define i16 @xor_shl_sminval_i16(i16 %x) {
306 ; X86-LABEL: xor_shl_sminval_i16:
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
314 ; X64-LABEL: xor_shl_sminval_i16:
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
322 %r = xor i16 %s, 32768
326 define i32 @xor_shl_sminval_i32(i32 %x) {
327 ; X86-LABEL: xor_shl_sminval_i32:
329 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
330 ; X86-NEXT: leal -2147483648(,%eax,8), %eax
333 ; X64-LABEL: xor_shl_sminval_i32:
335 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
336 ; X64-NEXT: leal -2147483648(,%rdi,8), %eax
339 %r = xor i32 %s, 2147483648
344 define i32 @xor_bigshl_sminval_i32(i32 %x) {
345 ; X86-LABEL: xor_bigshl_sminval_i32:
347 ; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
348 ; X86-NEXT: shll $8, %eax
349 ; X86-NEXT: addl $-2147483648, %eax # imm = 0x80000000
352 ; X64-LABEL: xor_bigshl_sminval_i32:
354 ; X64-NEXT: # kill: def $edi killed $edi def $rdi
355 ; X64-NEXT: shll $8, %edi
356 ; X64-NEXT: leal -2147483648(%rdi), %eax
359 %r = xor i32 %s, 2147483648
363 define i64 @xor_shl_sminval_i64(i64 %x) {
364 ; X86-LABEL: xor_shl_sminval_i64:
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
373 ; X64-LABEL: xor_shl_sminval_i64:
375 ; X64-NEXT: movabsq $-9223372036854775808, %rax # imm = 0x8000000000000000
376 ; X64-NEXT: leaq (%rax,%rdi,4), %rax
379 %r = xor i64 %s, -9223372036854775808