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 9define 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 22define 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 35define 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 48define 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 61define 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 76define 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 92define 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 108define 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