1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
4 ; InstCombine and DAGCombiner transform an 'add' into an 'or'
5 ; if there are no common bits from the incoming operands.
6 ; LEA instruction selection should be able to see through that
7 ; transform and reduce add/shift/or instruction counts.
9 define i32 @or_shift1_and1(i32 %x, i32 %y) {
10 ; CHECK-LABEL: or_shift1_and1:
12 ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi
13 ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
14 ; CHECK-NEXT: andl $1, %esi
15 ; CHECK-NEXT: leal (%rsi,%rdi,2), %eax
20 %or = or i32 %and, %shl
24 define i32 @or_shift1_and1_swapped(i32 %x, i32 %y) {
25 ; CHECK-LABEL: or_shift1_and1_swapped:
27 ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi
28 ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
29 ; CHECK-NEXT: andl $1, %esi
30 ; CHECK-NEXT: leal (%rsi,%rdi,2), %eax
35 %or = or i32 %shl, %and
39 define i32 @or_shift2_and1(i32 %x, i32 %y) {
40 ; CHECK-LABEL: or_shift2_and1:
42 ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi
43 ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
44 ; CHECK-NEXT: andl $1, %esi
45 ; CHECK-NEXT: leal (%rsi,%rdi,4), %eax
50 %or = or i32 %shl, %and
54 define i32 @or_shift3_and1(i32 %x, i32 %y) {
55 ; CHECK-LABEL: or_shift3_and1:
57 ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi
58 ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
59 ; CHECK-NEXT: andl $1, %esi
60 ; CHECK-NEXT: leal (%rsi,%rdi,8), %eax
65 %or = or i32 %shl, %and
69 define i32 @or_shift3_and7(i32 %x, i32 %y) {
70 ; CHECK-LABEL: or_shift3_and7:
72 ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi
73 ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
74 ; CHECK-NEXT: andl $7, %esi
75 ; CHECK-NEXT: leal (%rsi,%rdi,8), %eax
80 %or = or i32 %shl, %and
84 ; The shift is too big for an LEA.
86 define i32 @or_shift4_and1(i32 %x, i32 %y) {
87 ; CHECK-LABEL: or_shift4_and1:
89 ; CHECK-NEXT: # kill: def $esi killed $esi def $rsi
90 ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
91 ; CHECK-NEXT: shll $4, %edi
92 ; CHECK-NEXT: andl $1, %esi
93 ; CHECK-NEXT: leal (%rsi,%rdi), %eax
98 %or = or i32 %shl, %and
102 ; The mask is too big for the shift, so the 'or' isn't equivalent to an 'add'.
104 define i32 @or_shift3_and8(i32 %x, i32 %y) {
105 ; CHECK-LABEL: or_shift3_and8:
107 ; CHECK-NEXT: # kill: def $edi killed $edi def $rdi
108 ; CHECK-NEXT: leal (,%rdi,8), %eax
109 ; CHECK-NEXT: andl $8, %esi
110 ; CHECK-NEXT: orl %esi, %eax
115 %or = or i32 %shl, %and
119 ; 64-bit operands should work too.
121 define i64 @or_shift1_and1_64(i64 %x, i64 %y) {
122 ; CHECK-LABEL: or_shift1_and1_64:
124 ; CHECK-NEXT: andl $1, %esi
125 ; CHECK-NEXT: leaq (%rsi,%rdi,2), %rax
130 %or = or i64 %and, %shl