Home | History | Annotate | Download | only in X86
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s
      3 
      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.
      8 
      9 define i32 @or_shift1_and1(i32 %x, i32 %y) {
     10 ; CHECK-LABEL: or_shift1_and1:
     11 ; CHECK:       # %bb.0:
     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
     16 ; CHECK-NEXT:    retq
     17 
     18   %shl = shl i32 %x, 1
     19   %and = and i32 %y, 1
     20   %or = or i32 %and, %shl
     21   ret i32 %or
     22 }
     23 
     24 define i32 @or_shift1_and1_swapped(i32 %x, i32 %y) {
     25 ; CHECK-LABEL: or_shift1_and1_swapped:
     26 ; CHECK:       # %bb.0:
     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
     31 ; CHECK-NEXT:    retq
     32 
     33   %shl = shl i32 %x, 1
     34   %and = and i32 %y, 1
     35   %or = or i32 %shl, %and
     36   ret i32 %or
     37 }
     38 
     39 define i32 @or_shift2_and1(i32 %x, i32 %y) {
     40 ; CHECK-LABEL: or_shift2_and1:
     41 ; CHECK:       # %bb.0:
     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
     46 ; CHECK-NEXT:    retq
     47 
     48   %shl = shl i32 %x, 2
     49   %and = and i32 %y, 1
     50   %or = or i32 %shl, %and
     51   ret i32 %or
     52 }
     53 
     54 define i32 @or_shift3_and1(i32 %x, i32 %y) {
     55 ; CHECK-LABEL: or_shift3_and1:
     56 ; CHECK:       # %bb.0:
     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
     61 ; CHECK-NEXT:    retq
     62 
     63   %shl = shl i32 %x, 3
     64   %and = and i32 %y, 1
     65   %or = or i32 %shl, %and
     66   ret i32 %or
     67 }
     68 
     69 define i32 @or_shift3_and7(i32 %x, i32 %y) {
     70 ; CHECK-LABEL: or_shift3_and7:
     71 ; CHECK:       # %bb.0:
     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
     76 ; CHECK-NEXT:    retq
     77 
     78   %shl = shl i32 %x, 3
     79   %and = and i32 %y, 7
     80   %or = or i32 %shl, %and
     81   ret i32 %or
     82 }
     83 
     84 ; The shift is too big for an LEA.
     85 
     86 define i32 @or_shift4_and1(i32 %x, i32 %y) {
     87 ; CHECK-LABEL: or_shift4_and1:
     88 ; CHECK:       # %bb.0:
     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
     94 ; CHECK-NEXT:    retq
     95 
     96   %shl = shl i32 %x, 4
     97   %and = and i32 %y, 1
     98   %or = or i32 %shl, %and
     99   ret i32 %or
    100 }
    101 
    102 ; The mask is too big for the shift, so the 'or' isn't equivalent to an 'add'.
    103 
    104 define i32 @or_shift3_and8(i32 %x, i32 %y) {
    105 ; CHECK-LABEL: or_shift3_and8:
    106 ; CHECK:       # %bb.0:
    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
    111 ; CHECK-NEXT:    retq
    112 
    113   %shl = shl i32 %x, 3
    114   %and = and i32 %y, 8
    115   %or = or i32 %shl, %and
    116   ret i32 %or
    117 }
    118 
    119 ; 64-bit operands should work too.
    120 
    121 define i64 @or_shift1_and1_64(i64 %x, i64 %y) {
    122 ; CHECK-LABEL: or_shift1_and1_64:
    123 ; CHECK:       # %bb.0:
    124 ; CHECK-NEXT:    andl $1, %esi
    125 ; CHECK-NEXT:    leaq (%rsi,%rdi,2), %rax
    126 ; CHECK-NEXT:    retq
    127 
    128   %shl = shl i64 %x, 1
    129   %and = and i64 %y, 1
    130   %or = or i64 %and, %shl
    131   ret i64 %or
    132 }
    133 
    134