1*9880d681SAndroid Build Coastguard Worker; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; InstCombine and DAGCombiner transform an 'add' into an 'or' 5*9880d681SAndroid Build Coastguard Worker; if there are no common bits from the incoming operands. 6*9880d681SAndroid Build Coastguard Worker; LEA instruction selection should be able to see through that 7*9880d681SAndroid Build Coastguard Worker; transform and reduce add/shift/or instruction counts. 8*9880d681SAndroid Build Coastguard Worker 9*9880d681SAndroid Build Coastguard Workerdefine i32 @or_shift1_and1(i32 %x, i32 %y) { 10*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: or_shift1_and1: 11*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 12*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 13*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 14*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andl $1, %esi 15*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leal (%rsi,%rdi,2), %eax 16*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 17*9880d681SAndroid Build Coastguard Worker 18*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %x, 1 19*9880d681SAndroid Build Coastguard Worker %and = and i32 %y, 1 20*9880d681SAndroid Build Coastguard Worker %or = or i32 %and, %shl 21*9880d681SAndroid Build Coastguard Worker ret i32 %or 22*9880d681SAndroid Build Coastguard Worker} 23*9880d681SAndroid Build Coastguard Worker 24*9880d681SAndroid Build Coastguard Workerdefine i32 @or_shift1_and1_swapped(i32 %x, i32 %y) { 25*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: or_shift1_and1_swapped: 26*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 27*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 28*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 29*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andl $1, %esi 30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leal (%rsi,%rdi,2), %eax 31*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 32*9880d681SAndroid Build Coastguard Worker 33*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %x, 1 34*9880d681SAndroid Build Coastguard Worker %and = and i32 %y, 1 35*9880d681SAndroid Build Coastguard Worker %or = or i32 %shl, %and 36*9880d681SAndroid Build Coastguard Worker ret i32 %or 37*9880d681SAndroid Build Coastguard Worker} 38*9880d681SAndroid Build Coastguard Worker 39*9880d681SAndroid Build Coastguard Workerdefine i32 @or_shift2_and1(i32 %x, i32 %y) { 40*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: or_shift2_and1: 41*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 42*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 43*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 44*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andl $1, %esi 45*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leal (%rsi,%rdi,4), %eax 46*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 47*9880d681SAndroid Build Coastguard Worker 48*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %x, 2 49*9880d681SAndroid Build Coastguard Worker %and = and i32 %y, 1 50*9880d681SAndroid Build Coastguard Worker %or = or i32 %shl, %and 51*9880d681SAndroid Build Coastguard Worker ret i32 %or 52*9880d681SAndroid Build Coastguard Worker} 53*9880d681SAndroid Build Coastguard Worker 54*9880d681SAndroid Build Coastguard Workerdefine i32 @or_shift3_and1(i32 %x, i32 %y) { 55*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: or_shift3_and1: 56*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 57*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 58*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 59*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andl $1, %esi 60*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leal (%rsi,%rdi,8), %eax 61*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 62*9880d681SAndroid Build Coastguard Worker 63*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %x, 3 64*9880d681SAndroid Build Coastguard Worker %and = and i32 %y, 1 65*9880d681SAndroid Build Coastguard Worker %or = or i32 %shl, %and 66*9880d681SAndroid Build Coastguard Worker ret i32 %or 67*9880d681SAndroid Build Coastguard Worker} 68*9880d681SAndroid Build Coastguard Worker 69*9880d681SAndroid Build Coastguard Workerdefine i32 @or_shift3_and7(i32 %x, i32 %y) { 70*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: or_shift3_and7: 71*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 72*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 73*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 74*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andl $7, %esi 75*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leal (%rsi,%rdi,8), %eax 76*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %x, 3 79*9880d681SAndroid Build Coastguard Worker %and = and i32 %y, 7 80*9880d681SAndroid Build Coastguard Worker %or = or i32 %shl, %and 81*9880d681SAndroid Build Coastguard Worker ret i32 %or 82*9880d681SAndroid Build Coastguard Worker} 83*9880d681SAndroid Build Coastguard Worker 84*9880d681SAndroid Build Coastguard Worker; The shift is too big for an LEA. 85*9880d681SAndroid Build Coastguard Worker 86*9880d681SAndroid Build Coastguard Workerdefine i32 @or_shift4_and1(i32 %x, i32 %y) { 87*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: or_shift4_and1: 88*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 89*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %ESI<def> %ESI<kill> %RSI<def> 90*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 91*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: shll $4, %edi 92*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andl $1, %esi 93*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leal (%rsi,%rdi), %eax 94*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 95*9880d681SAndroid Build Coastguard Worker 96*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %x, 4 97*9880d681SAndroid Build Coastguard Worker %and = and i32 %y, 1 98*9880d681SAndroid Build Coastguard Worker %or = or i32 %shl, %and 99*9880d681SAndroid Build Coastguard Worker ret i32 %or 100*9880d681SAndroid Build Coastguard Worker} 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker; The mask is too big for the shift, so the 'or' isn't equivalent to an 'add'. 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Workerdefine i32 @or_shift3_and8(i32 %x, i32 %y) { 105*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: or_shift3_and8: 106*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 107*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill: %EDI<def> %EDI<kill> %RDI<def> 108*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leal (,%rdi,8), %eax 109*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andl $8, %esi 110*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orl %esi, %eax 111*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 112*9880d681SAndroid Build Coastguard Worker 113*9880d681SAndroid Build Coastguard Worker %shl = shl i32 %x, 3 114*9880d681SAndroid Build Coastguard Worker %and = and i32 %y, 8 115*9880d681SAndroid Build Coastguard Worker %or = or i32 %shl, %and 116*9880d681SAndroid Build Coastguard Worker ret i32 %or 117*9880d681SAndroid Build Coastguard Worker} 118*9880d681SAndroid Build Coastguard Worker 119*9880d681SAndroid Build Coastguard Worker; 64-bit operands should work too. 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Workerdefine i64 @or_shift1_and1_64(i64 %x, i64 %y) { 122*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: or_shift1_and1_64: 123*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 124*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andl $1, %esi 125*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leaq (%rsi,%rdi,2), %rax 126*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker %shl = shl i64 %x, 1 129*9880d681SAndroid Build Coastguard Worker %and = and i64 %y, 1 130*9880d681SAndroid Build Coastguard Worker %or = or i64 %and, %shl 131*9880d681SAndroid Build Coastguard Worker ret i64 %or 132*9880d681SAndroid Build Coastguard Worker} 133*9880d681SAndroid Build Coastguard Worker 134