Home | History | Annotate | Download | only in X86
      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