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