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:    andl $1, %esi
     13 ; CHECK-NEXT:    leal (%rsi,%rdi,2), %eax
     14 ; CHECK-NEXT:    retq
     15 
     16   %shl = shl i32 %x, 1
     17   %and = and i32 %y, 1
     18   %or = or i32 %and, %shl
     19   ret i32 %or
     20 }
     21 
     22 define i32 @or_shift1_and1_swapped(i32 %x, i32 %y) {
     23 ; CHECK-LABEL: or_shift1_and1_swapped:
     24 ; CHECK:       # BB#0:
     25 ; CHECK-NEXT:    andl $1, %esi
     26 ; CHECK-NEXT:    leal (%rsi,%rdi,2), %eax
     27 ; CHECK-NEXT:    retq
     28 
     29   %shl = shl i32 %x, 1
     30   %and = and i32 %y, 1
     31   %or = or i32 %shl, %and
     32   ret i32 %or
     33 }
     34 
     35 define i32 @or_shift2_and1(i32 %x, i32 %y) {
     36 ; CHECK-LABEL: or_shift2_and1:
     37 ; CHECK:       # BB#0:
     38 ; CHECK-NEXT:    andl $1, %esi
     39 ; CHECK-NEXT:    leal (%rsi,%rdi,4), %eax
     40 ; CHECK-NEXT:    retq
     41 
     42   %shl = shl i32 %x, 2
     43   %and = and i32 %y, 1
     44   %or = or i32 %shl, %and
     45   ret i32 %or
     46 }
     47 
     48 define i32 @or_shift3_and1(i32 %x, i32 %y) {
     49 ; CHECK-LABEL: or_shift3_and1:
     50 ; CHECK:       # BB#0:
     51 ; CHECK-NEXT:    andl $1, %esi
     52 ; CHECK-NEXT:    leal (%rsi,%rdi,8), %eax
     53 ; CHECK-NEXT:    retq
     54 
     55   %shl = shl i32 %x, 3
     56   %and = and i32 %y, 1
     57   %or = or i32 %shl, %and
     58   ret i32 %or
     59 }
     60 
     61 define i32 @or_shift3_and7(i32 %x, i32 %y) {
     62 ; CHECK-LABEL: or_shift3_and7:
     63 ; CHECK:       # BB#0:
     64 ; CHECK-NEXT:    andl $7, %esi
     65 ; CHECK-NEXT:    leal (%rsi,%rdi,8), %eax
     66 ; CHECK-NEXT:    retq
     67 
     68   %shl = shl i32 %x, 3
     69   %and = and i32 %y, 7
     70   %or = or i32 %shl, %and
     71   ret i32 %or
     72 }
     73 
     74 ; The shift is too big for an LEA.
     75 
     76 define i32 @or_shift4_and1(i32 %x, i32 %y) {
     77 ; CHECK-LABEL: or_shift4_and1:
     78 ; CHECK:       # BB#0:
     79 ; CHECK-NEXT:    shll $4, %edi
     80 ; CHECK-NEXT:    andl $1, %esi
     81 ; CHECK-NEXT:    leal (%rsi,%rdi), %eax
     82 ; CHECK-NEXT:    retq
     83 
     84   %shl = shl i32 %x, 4
     85   %and = and i32 %y, 1
     86   %or = or i32 %shl, %and
     87   ret i32 %or
     88 }
     89 
     90 ; The mask is too big for the shift, so the 'or' isn't equivalent to an 'add'.
     91 
     92 define i32 @or_shift3_and8(i32 %x, i32 %y) {
     93 ; CHECK-LABEL: or_shift3_and8:
     94 ; CHECK:       # BB#0:
     95 ; CHECK-NEXT:    leal (,%rdi,8), %eax
     96 ; CHECK-NEXT:    andl $8, %esi
     97 ; CHECK-NEXT:    orl %esi, %eax
     98 ; CHECK-NEXT:    retq
     99 
    100   %shl = shl i32 %x, 3
    101   %and = and i32 %y, 8
    102   %or = or i32 %shl, %and
    103   ret i32 %or
    104 }
    105 
    106 ; 64-bit operands should work too.
    107 
    108 define i64 @or_shift1_and1_64(i64 %x, i64 %y) {
    109 ; CHECK-LABEL: or_shift1_and1_64:
    110 ; CHECK:       # BB#0:
    111 ; CHECK-NEXT:    andl $1, %esi
    112 ; CHECK-NEXT:    leaq (%rsi,%rdi,2), %rax
    113 ; CHECK-NEXT:    retq
    114 
    115   %shl = shl i64 %x, 1
    116   %and = and i64 %y, 1
    117   %or = or i64 %and, %shl
    118   ret i64 %or
    119 }
    120 
    121