Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=core2 | FileCheck %s -check-prefix=CHECK -check-prefix=SSE
      2 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7-avx | FileCheck %s -check-prefix=CHECK -check-prefix=AVX
      3 
      4 
      5 ; Verify that we correctly generate 'addsub' instructions from
      6 ; a sequence of vector extracts + float add/sub + vector inserts.
      7 
      8 define <4 x float> @test1(<4 x float> %A, <4 x float> %B) {
      9   %1 = extractelement <4 x float> %A, i32 0
     10   %2 = extractelement <4 x float> %B, i32 0
     11   %sub = fsub float %1, %2
     12   %3 = extractelement <4 x float> %A, i32 2
     13   %4 = extractelement <4 x float> %B, i32 2
     14   %sub2 = fsub float %3, %4
     15   %5 = extractelement <4 x float> %A, i32 1
     16   %6 = extractelement <4 x float> %B, i32 1
     17   %add = fadd float %5, %6
     18   %7 = extractelement <4 x float> %A, i32 3
     19   %8 = extractelement <4 x float> %B, i32 3
     20   %add2 = fadd float %7, %8
     21   %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1
     22   %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3
     23   %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 0
     24   %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 2
     25   ret <4 x float> %vecinsert4
     26 }
     27 ; CHECK-LABEL: test1
     28 ; SSE: addsubps
     29 ; AVX: vaddsubps
     30 ; CHECK-NEXT: ret
     31 
     32 
     33 define <4 x float> @test2(<4 x float> %A, <4 x float> %B) {
     34   %1 = extractelement <4 x float> %A, i32 2
     35   %2 = extractelement <4 x float> %B, i32 2
     36   %sub2 = fsub float %1, %2
     37   %3 = extractelement <4 x float> %A, i32 3
     38   %4 = extractelement <4 x float> %B, i32 3
     39   %add2 = fadd float %3, %4
     40   %vecinsert1 = insertelement <4 x float> undef, float %sub2, i32 2
     41   %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3
     42   ret <4 x float> %vecinsert2
     43 }
     44 ; CHECK-LABEL: test2
     45 ; SSE: addsubps
     46 ; AVX: vaddsubps
     47 ; CHECK-NEXT: ret
     48 
     49 
     50 define <4 x float> @test3(<4 x float> %A, <4 x float> %B) {
     51   %1 = extractelement <4 x float> %A, i32 0
     52   %2 = extractelement <4 x float> %B, i32 0
     53   %sub = fsub float %1, %2
     54   %3 = extractelement <4 x float> %A, i32 3
     55   %4 = extractelement <4 x float> %B, i32 3
     56   %add = fadd float %4, %3
     57   %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 0
     58   %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add, i32 3
     59   ret <4 x float> %vecinsert2
     60 }
     61 ; CHECK-LABEL: test3
     62 ; SSE: addsubps
     63 ; AVX: vaddsubps
     64 ; CHECK-NEXT: ret
     65 
     66 
     67 define <4 x float> @test4(<4 x float> %A, <4 x float> %B) {
     68   %1 = extractelement <4 x float> %A, i32 2
     69   %2 = extractelement <4 x float> %B, i32 2
     70   %sub = fsub float %1, %2
     71   %3 = extractelement <4 x float> %A, i32 1
     72   %4 = extractelement <4 x float> %B, i32 1
     73   %add = fadd float %3, %4
     74   %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 2
     75   %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add, i32 1
     76   ret <4 x float> %vecinsert2
     77 }
     78 ; CHECK-LABEL: test4
     79 ; SSE: addsubps
     80 ; AVX: vaddsubps
     81 ; CHECK-NEXT: ret
     82 
     83 
     84 define <4 x float> @test5(<4 x float> %A, <4 x float> %B) {
     85   %1 = extractelement <4 x float> %A, i32 0
     86   %2 = extractelement <4 x float> %B, i32 0
     87   %sub2 = fsub float %1, %2
     88   %3 = extractelement <4 x float> %A, i32 1
     89   %4 = extractelement <4 x float> %B, i32 1
     90   %add2 = fadd float %3, %4
     91   %vecinsert1 = insertelement <4 x float> undef, float %sub2, i32 0
     92   %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 1
     93   ret <4 x float> %vecinsert2
     94 }
     95 ; CHECK-LABEL: test5
     96 ; SSE: addsubps
     97 ; AVX: vaddsubps
     98 ; CHECK-NEXT: ret
     99 
    100 
    101 define <4 x float> @test6(<4 x float> %A, <4 x float> %B) {
    102   %1 = extractelement <4 x float> %A, i32 0
    103   %2 = extractelement <4 x float> %B, i32 0
    104   %sub = fsub float %1, %2
    105   %3 = extractelement <4 x float> %A, i32 2
    106   %4 = extractelement <4 x float> %B, i32 2
    107   %sub2 = fsub float %3, %4
    108   %5 = extractelement <4 x float> %A, i32 1
    109   %6 = extractelement <4 x float> %B, i32 1
    110   %add = fadd float %5, %6
    111   %7 = extractelement <4 x float> %A, i32 3
    112   %8 = extractelement <4 x float> %B, i32 3
    113   %add2 = fadd float %7, %8
    114   %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1
    115   %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3
    116   %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 0
    117   %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 2
    118   ret <4 x float> %vecinsert4
    119 }
    120 ; CHECK-LABEL: test6
    121 ; SSE: addsubps
    122 ; AVX: vaddsubps
    123 ; CHECK-NEXT: ret
    124 
    125 
    126 define <4 x double> @test7(<4 x double> %A, <4 x double> %B) {
    127   %1 = extractelement <4 x double> %A, i32 0
    128   %2 = extractelement <4 x double> %B, i32 0
    129   %sub = fsub double %1, %2
    130   %3 = extractelement <4 x double> %A, i32 2
    131   %4 = extractelement <4 x double> %B, i32 2
    132   %sub2 = fsub double %3, %4
    133   %5 = extractelement <4 x double> %A, i32 1
    134   %6 = extractelement <4 x double> %B, i32 1
    135   %add = fadd double %5, %6
    136   %7 = extractelement <4 x double> %A, i32 3
    137   %8 = extractelement <4 x double> %B, i32 3
    138   %add2 = fadd double %7, %8
    139   %vecinsert1 = insertelement <4 x double> undef, double %add, i32 1
    140   %vecinsert2 = insertelement <4 x double> %vecinsert1, double %add2, i32 3
    141   %vecinsert3 = insertelement <4 x double> %vecinsert2, double %sub, i32 0
    142   %vecinsert4 = insertelement <4 x double> %vecinsert3, double %sub2, i32 2
    143   ret <4 x double> %vecinsert4
    144 }
    145 ; CHECK-LABEL: test7
    146 ; SSE: addsubpd
    147 ; SSE-NEXT: addsubpd
    148 ; AVX: vaddsubpd
    149 ; AVX-NOT: vaddsubpd
    150 ; CHECK: ret
    151 
    152 
    153 define <2 x double> @test8(<2 x double> %A, <2 x double> %B) {
    154   %1 = extractelement <2 x double> %A, i32 0
    155   %2 = extractelement <2 x double> %B, i32 0
    156   %sub = fsub double %1, %2
    157   %3 = extractelement <2 x double> %A, i32 1
    158   %4 = extractelement <2 x double> %B, i32 1
    159   %add = fadd double %3, %4
    160   %vecinsert1 = insertelement <2 x double> undef, double %sub, i32 0
    161   %vecinsert2 = insertelement <2 x double> %vecinsert1, double %add, i32 1
    162   ret <2 x double> %vecinsert2
    163 }
    164 ; CHECK-LABEL: test8
    165 ; SSE: addsubpd
    166 ; AVX: vaddsubpd
    167 ; CHECK: ret
    168 
    169 
    170 define <8 x float> @test9(<8 x float> %A, <8 x float> %B) {
    171   %1 = extractelement <8 x float> %A, i32 0
    172   %2 = extractelement <8 x float> %B, i32 0
    173   %sub = fsub float %1, %2
    174   %3 = extractelement <8 x float> %A, i32 2
    175   %4 = extractelement <8 x float> %B, i32 2
    176   %sub2 = fsub float %3, %4
    177   %5 = extractelement <8 x float> %A, i32 1
    178   %6 = extractelement <8 x float> %B, i32 1
    179   %add = fadd float %5, %6
    180   %7 = extractelement <8 x float> %A, i32 3
    181   %8 = extractelement <8 x float> %B, i32 3
    182   %add2 = fadd float %7, %8
    183   %9 = extractelement <8 x float> %A, i32 4
    184   %10 = extractelement <8 x float> %B, i32 4
    185   %sub3 = fsub float %9, %10
    186   %11 = extractelement <8 x float> %A, i32 6
    187   %12 = extractelement <8 x float> %B, i32 6
    188   %sub4 = fsub float %11, %12
    189   %13 = extractelement <8 x float> %A, i32 5
    190   %14 = extractelement <8 x float> %B, i32 5
    191   %add3 = fadd float %13, %14
    192   %15 = extractelement <8 x float> %A, i32 7
    193   %16 = extractelement <8 x float> %B, i32 7
    194   %add4 = fadd float %15, %16
    195   %vecinsert1 = insertelement <8 x float> undef, float %add, i32 1
    196   %vecinsert2 = insertelement <8 x float> %vecinsert1, float %add2, i32 3
    197   %vecinsert3 = insertelement <8 x float> %vecinsert2, float %sub, i32 0
    198   %vecinsert4 = insertelement <8 x float> %vecinsert3, float %sub2, i32 2
    199   %vecinsert5 = insertelement <8 x float> %vecinsert4, float %add3, i32 5
    200   %vecinsert6 = insertelement <8 x float> %vecinsert5, float %add4, i32 7
    201   %vecinsert7 = insertelement <8 x float> %vecinsert6, float %sub3, i32 4
    202   %vecinsert8 = insertelement <8 x float> %vecinsert7, float %sub4, i32 6
    203   ret <8 x float> %vecinsert8
    204 }
    205 ; CHECK-LABEL: test9
    206 ; SSE: addsubps
    207 ; SSE-NEXT: addsubps
    208 ; AVX: vaddsubps
    209 ; AVX-NOT: vaddsubps
    210 ; CHECK: ret
    211 
    212 
    213 ; Verify that we don't generate addsub instruction for the following
    214 ; functions.
    215 define <4 x float> @test10(<4 x float> %A, <4 x float> %B) {
    216   %1 = extractelement <4 x float> %A, i32 0
    217   %2 = extractelement <4 x float> %B, i32 0
    218   %sub = fsub float %1, %2
    219   %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 0
    220   ret <4 x float> %vecinsert1
    221 }
    222 ; CHECK-LABEL: test10
    223 ; CHECK-NOT: addsubps
    224 ; CHECK: ret
    225 
    226 
    227 define <4 x float> @test11(<4 x float> %A, <4 x float> %B) {
    228   %1 = extractelement <4 x float> %A, i32 2
    229   %2 = extractelement <4 x float> %B, i32 2
    230   %sub = fsub float %1, %2
    231   %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 2
    232   ret <4 x float> %vecinsert1
    233 }
    234 ; CHECK-LABEL: test11
    235 ; CHECK-NOT: addsubps
    236 ; CHECK: ret
    237 
    238 
    239 define <4 x float> @test12(<4 x float> %A, <4 x float> %B) {
    240   %1 = extractelement <4 x float> %A, i32 1
    241   %2 = extractelement <4 x float> %B, i32 1
    242   %add = fadd float %1, %2
    243   %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1
    244   ret <4 x float> %vecinsert1
    245 }
    246 ; CHECK-LABEL: test12
    247 ; CHECK-NOT: addsubps
    248 ; CHECK: ret
    249 
    250 
    251 define <4 x float> @test13(<4 x float> %A, <4 x float> %B) {
    252   %1 = extractelement <4 x float> %A, i32 3
    253   %2 = extractelement <4 x float> %B, i32 3
    254   %add = fadd float %1, %2
    255   %vecinsert1 = insertelement <4 x float> undef, float %add, i32 3
    256   ret <4 x float> %vecinsert1
    257 }
    258 ; CHECK-LABEL: test13
    259 ; CHECK-NOT: addsubps
    260 ; CHECK: ret
    261 
    262 
    263 define <4 x float> @test14(<4 x float> %A, <4 x float> %B) {
    264   %1 = extractelement <4 x float> %A, i32 0
    265   %2 = extractelement <4 x float> %B, i32 0
    266   %sub = fsub float %1, %2
    267   %3 = extractelement <4 x float> %A, i32 2
    268   %4 = extractelement <4 x float> %B, i32 2
    269   %sub2 = fsub float %3, %4
    270   %vecinsert1 = insertelement <4 x float> undef, float %sub, i32 0
    271   %vecinsert2 = insertelement <4 x float> %vecinsert1, float %sub2, i32 2
    272   ret <4 x float> %vecinsert2
    273 }
    274 ; CHECK-LABEL: test14
    275 ; CHECK-NOT: addsubps
    276 ; CHECK: ret
    277 
    278 
    279 define <4 x float> @test15(<4 x float> %A, <4 x float> %B) {
    280   %1 = extractelement <4 x float> %A, i32 1
    281   %2 = extractelement <4 x float> %B, i32 1
    282   %add = fadd float %1, %2
    283   %3 = extractelement <4 x float> %A, i32 3
    284   %4 = extractelement <4 x float> %B, i32 3
    285   %add2 = fadd float %3, %4
    286   %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1
    287   %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3
    288   ret <4 x float> %vecinsert2
    289 }
    290 ; CHECK-LABEL: test15
    291 ; CHECK-NOT: addsubps
    292 ; CHECK: ret
    293 
    294 
    295 define <4 x float> @test16(<4 x float> %A, <4 x float> %B) {
    296   %1 = extractelement <4 x float> %A, i32 0
    297   %2 = extractelement <4 x float> %B, i32 0
    298   %sub = fsub float %1, undef
    299   %3 = extractelement <4 x float> %A, i32 2
    300   %4 = extractelement <4 x float> %B, i32 2
    301   %sub2 = fsub float %3, %4
    302   %5 = extractelement <4 x float> %A, i32 1
    303   %6 = extractelement <4 x float> %B, i32 1
    304   %add = fadd float %5, undef
    305   %7 = extractelement <4 x float> %A, i32 3
    306   %8 = extractelement <4 x float> %B, i32 3
    307   %add2 = fadd float %7, %8
    308   %vecinsert1 = insertelement <4 x float> undef, float %add, i32 1
    309   %vecinsert2 = insertelement <4 x float> %vecinsert1, float %add2, i32 3
    310   %vecinsert3 = insertelement <4 x float> %vecinsert2, float %sub, i32 0
    311   %vecinsert4 = insertelement <4 x float> %vecinsert3, float %sub2, i32 2
    312   ret <4 x float> %vecinsert4
    313 }
    314 ; CHECK-LABEL: test16
    315 ; CHECK-NOT: addsubps
    316 ; CHECK: ret
    317 
    318 
    319