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