1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -stop-after machine-combiner -o - | FileCheck %s --check-prefix=DEAD 3*9880d681SAndroid Build Coastguard Worker 4*9880d681SAndroid Build Coastguard Worker; Verify that integer multiplies are reassociated. The first multiply in 5*9880d681SAndroid Build Coastguard Worker; each test should be independent of the result of the preceding add (lea). 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; TODO: This test does not actually test i16 machine instruction reassociation 8*9880d681SAndroid Build Coastguard Worker; because the operands are being promoted to i32 types. 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Workerdefine i16 @reassociate_muls_i16(i16 %x0, i16 %x1, i16 %x2, i16 %x3) { 11*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_muls_i16: 12*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 13*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 14*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 15*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leal (%rdi,%rsi), %eax 16*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: imull %ecx, %edx 17*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: imull %edx, %eax 18*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 19*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 20*9880d681SAndroid Build Coastguard Worker %t0 = add i16 %x0, %x1 21*9880d681SAndroid Build Coastguard Worker %t1 = mul i16 %x2, %t0 22*9880d681SAndroid Build Coastguard Worker %t2 = mul i16 %x3, %t1 23*9880d681SAndroid Build Coastguard Worker ret i16 %t2 24*9880d681SAndroid Build Coastguard Worker} 25*9880d681SAndroid Build Coastguard Worker 26*9880d681SAndroid Build Coastguard Workerdefine i32 @reassociate_muls_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) { 27*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_muls_i32: 28*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 29*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: # kill 31*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leal (%rdi,%rsi), %eax 32*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: imull %ecx, %edx 33*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: imull %edx, %eax 34*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 35*9880d681SAndroid Build Coastguard Worker 36*9880d681SAndroid Build Coastguard Worker; DEAD: ADD32rr 37*9880d681SAndroid Build Coastguard Worker; DEAD-NEXT: IMUL32rr{{.*}}implicit-def dead %eflags 38*9880d681SAndroid Build Coastguard Worker; DEAD-NEXT: IMUL32rr{{.*}}implicit-def dead %eflags 39*9880d681SAndroid Build Coastguard Worker 40*9880d681SAndroid Build Coastguard Worker %t0 = add i32 %x0, %x1 41*9880d681SAndroid Build Coastguard Worker %t1 = mul i32 %x2, %t0 42*9880d681SAndroid Build Coastguard Worker %t2 = mul i32 %x3, %t1 43*9880d681SAndroid Build Coastguard Worker ret i32 %t2 44*9880d681SAndroid Build Coastguard Worker} 45*9880d681SAndroid Build Coastguard Worker 46*9880d681SAndroid Build Coastguard Workerdefine i64 @reassociate_muls_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) { 47*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_muls_i64: 48*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 49*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: leaq (%rdi,%rsi), %rax 50*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: imulq %rcx, %rdx 51*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: imulq %rdx, %rax 52*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 53*9880d681SAndroid Build Coastguard Worker %t0 = add i64 %x0, %x1 54*9880d681SAndroid Build Coastguard Worker %t1 = mul i64 %x2, %t0 55*9880d681SAndroid Build Coastguard Worker %t2 = mul i64 %x3, %t1 56*9880d681SAndroid Build Coastguard Worker ret i64 %t2 57*9880d681SAndroid Build Coastguard Worker} 58*9880d681SAndroid Build Coastguard Worker 59*9880d681SAndroid Build Coastguard Worker; Verify that integer 'ands' are reassociated. The first 'and' in 60*9880d681SAndroid Build Coastguard Worker; each test should be independent of the result of the preceding sub. 61*9880d681SAndroid Build Coastguard Worker 62*9880d681SAndroid Build Coastguard Workerdefine i8 @reassociate_ands_i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3) { 63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_ands_i8: 64*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 65*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subb %sil, %dil 66*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andb %cl, %dl 67*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andb %dil, %dl 68*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl %edx, %eax 69*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 70*9880d681SAndroid Build Coastguard Worker %t0 = sub i8 %x0, %x1 71*9880d681SAndroid Build Coastguard Worker %t1 = and i8 %x2, %t0 72*9880d681SAndroid Build Coastguard Worker %t2 = and i8 %x3, %t1 73*9880d681SAndroid Build Coastguard Worker ret i8 %t2 74*9880d681SAndroid Build Coastguard Worker} 75*9880d681SAndroid Build Coastguard Worker 76*9880d681SAndroid Build Coastguard Worker; TODO: No way to test i16? These appear to always get promoted to i32. 77*9880d681SAndroid Build Coastguard Worker 78*9880d681SAndroid Build Coastguard Workerdefine i32 @reassociate_ands_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) { 79*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_ands_i32: 80*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subl %esi, %edi 82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andl %ecx, %edx 83*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andl %edi, %edx 84*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl %edx, %eax 85*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 86*9880d681SAndroid Build Coastguard Worker %t0 = sub i32 %x0, %x1 87*9880d681SAndroid Build Coastguard Worker %t1 = and i32 %x2, %t0 88*9880d681SAndroid Build Coastguard Worker %t2 = and i32 %x3, %t1 89*9880d681SAndroid Build Coastguard Worker ret i32 %t2 90*9880d681SAndroid Build Coastguard Worker} 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Workerdefine i64 @reassociate_ands_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) { 93*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_ands_i64: 94*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 95*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subq %rsi, %rdi 96*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andq %rcx, %rdx 97*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: andq %rdi, %rdx 98*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movq %rdx, %rax 99*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 100*9880d681SAndroid Build Coastguard Worker %t0 = sub i64 %x0, %x1 101*9880d681SAndroid Build Coastguard Worker %t1 = and i64 %x2, %t0 102*9880d681SAndroid Build Coastguard Worker %t2 = and i64 %x3, %t1 103*9880d681SAndroid Build Coastguard Worker ret i64 %t2 104*9880d681SAndroid Build Coastguard Worker} 105*9880d681SAndroid Build Coastguard Worker 106*9880d681SAndroid Build Coastguard Worker; Verify that integer 'ors' are reassociated. The first 'or' in 107*9880d681SAndroid Build Coastguard Worker; each test should be independent of the result of the preceding sub. 108*9880d681SAndroid Build Coastguard Worker 109*9880d681SAndroid Build Coastguard Workerdefine i8 @reassociate_ors_i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3) { 110*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_ors_i8: 111*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 112*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subb %sil, %dil 113*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orb %cl, %dl 114*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orb %dil, %dl 115*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl %edx, %eax 116*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 117*9880d681SAndroid Build Coastguard Worker %t0 = sub i8 %x0, %x1 118*9880d681SAndroid Build Coastguard Worker %t1 = or i8 %x2, %t0 119*9880d681SAndroid Build Coastguard Worker %t2 = or i8 %x3, %t1 120*9880d681SAndroid Build Coastguard Worker ret i8 %t2 121*9880d681SAndroid Build Coastguard Worker} 122*9880d681SAndroid Build Coastguard Worker 123*9880d681SAndroid Build Coastguard Worker; TODO: No way to test i16? These appear to always get promoted to i32. 124*9880d681SAndroid Build Coastguard Worker 125*9880d681SAndroid Build Coastguard Workerdefine i32 @reassociate_ors_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) { 126*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_ors_i32: 127*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 128*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subl %esi, %edi 129*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orl %ecx, %edx 130*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orl %edi, %edx 131*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl %edx, %eax 132*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 133*9880d681SAndroid Build Coastguard Worker %t0 = sub i32 %x0, %x1 134*9880d681SAndroid Build Coastguard Worker %t1 = or i32 %x2, %t0 135*9880d681SAndroid Build Coastguard Worker %t2 = or i32 %x3, %t1 136*9880d681SAndroid Build Coastguard Worker ret i32 %t2 137*9880d681SAndroid Build Coastguard Worker} 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Workerdefine i64 @reassociate_ors_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) { 140*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_ors_i64: 141*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 142*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subq %rsi, %rdi 143*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orq %rcx, %rdx 144*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: orq %rdi, %rdx 145*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movq %rdx, %rax 146*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 147*9880d681SAndroid Build Coastguard Worker %t0 = sub i64 %x0, %x1 148*9880d681SAndroid Build Coastguard Worker %t1 = or i64 %x2, %t0 149*9880d681SAndroid Build Coastguard Worker %t2 = or i64 %x3, %t1 150*9880d681SAndroid Build Coastguard Worker ret i64 %t2 151*9880d681SAndroid Build Coastguard Worker} 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker; Verify that integer 'xors' are reassociated. The first 'xor' in 154*9880d681SAndroid Build Coastguard Worker; each test should be independent of the result of the preceding sub. 155*9880d681SAndroid Build Coastguard Worker 156*9880d681SAndroid Build Coastguard Workerdefine i8 @reassociate_xors_i8(i8 %x0, i8 %x1, i8 %x2, i8 %x3) { 157*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_xors_i8: 158*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 159*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subb %sil, %dil 160*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorb %cl, %dl 161*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorb %dil, %dl 162*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl %edx, %eax 163*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 164*9880d681SAndroid Build Coastguard Worker %t0 = sub i8 %x0, %x1 165*9880d681SAndroid Build Coastguard Worker %t1 = xor i8 %x2, %t0 166*9880d681SAndroid Build Coastguard Worker %t2 = xor i8 %x3, %t1 167*9880d681SAndroid Build Coastguard Worker ret i8 %t2 168*9880d681SAndroid Build Coastguard Worker} 169*9880d681SAndroid Build Coastguard Worker 170*9880d681SAndroid Build Coastguard Worker; TODO: No way to test i16? These appear to always get promoted to i32. 171*9880d681SAndroid Build Coastguard Worker 172*9880d681SAndroid Build Coastguard Workerdefine i32 @reassociate_xors_i32(i32 %x0, i32 %x1, i32 %x2, i32 %x3) { 173*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_xors_i32: 174*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 175*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subl %esi, %edi 176*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl %ecx, %edx 177*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorl %edi, %edx 178*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movl %edx, %eax 179*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 180*9880d681SAndroid Build Coastguard Worker %t0 = sub i32 %x0, %x1 181*9880d681SAndroid Build Coastguard Worker %t1 = xor i32 %x2, %t0 182*9880d681SAndroid Build Coastguard Worker %t2 = xor i32 %x3, %t1 183*9880d681SAndroid Build Coastguard Worker ret i32 %t2 184*9880d681SAndroid Build Coastguard Worker} 185*9880d681SAndroid Build Coastguard Worker 186*9880d681SAndroid Build Coastguard Workerdefine i64 @reassociate_xors_i64(i64 %x0, i64 %x1, i64 %x2, i64 %x3) { 187*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: reassociate_xors_i64: 188*9880d681SAndroid Build Coastguard Worker; CHECK: # BB#0: 189*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subq %rsi, %rdi 190*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorq %rcx, %rdx 191*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: xorq %rdi, %rdx 192*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movq %rdx, %rax 193*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: retq 194*9880d681SAndroid Build Coastguard Worker %t0 = sub i64 %x0, %x1 195*9880d681SAndroid Build Coastguard Worker %t1 = xor i64 %x2, %t0 196*9880d681SAndroid Build Coastguard Worker %t2 = xor i64 %x3, %t1 197*9880d681SAndroid Build Coastguard Worker ret i64 %t2 198*9880d681SAndroid Build Coastguard Worker} 199*9880d681SAndroid Build Coastguard Worker 200