Home | History | Annotate | Download | only in PowerPC
      1 ; RUN: llc < %s -mcpu=pwr7 -mattr=+vsx | FileCheck %s
      2 ; RUN: llc < %s -mcpu=pwr7 -mattr=+vsx -fast-isel -O0 | FileCheck -check-prefix=CHECK-FISL %s
      3 
      4 ; Also run with -schedule-ppc-vsx-fma-mutation-early as a stress test for the
      5 ; live-interval-updating logic.
      6 ; RUN: llc < %s -mcpu=pwr7 -mattr=+vsx -schedule-ppc-vsx-fma-mutation-early
      7 target datalayout = "E-m:e-i64:64-n32:64"
      8 target triple = "powerpc64-unknown-linux-gnu"
      9 
     10 define void @test1(double %a, double %b, double %c, double %e, double* nocapture %d) #0 {
     11 entry:
     12   %0 = tail call double @llvm.fma.f64(double %b, double %c, double %a)
     13   store double %0, double* %d, align 8
     14   %1 = tail call double @llvm.fma.f64(double %b, double %e, double %a)
     15   %arrayidx1 = getelementptr inbounds double, double* %d, i64 1
     16   store double %1, double* %arrayidx1, align 8
     17   ret void
     18 
     19 ; CHECK-LABEL: @test1
     20 ; CHECK-DAG: li [[C1:[0-9]+]], 8
     21 ; CHECK-DAG: xsmaddmdp 3, 2, 1
     22 ; CHECK-DAG: xsmaddadp 1, 2, 4
     23 ; CHECK-DAG: stxsdx 3, 0, 7
     24 ; CHECK-DAG: stxsdx 1, 7, [[C1]]
     25 ; CHECK: blr
     26 
     27 ; CHECK-FISL-LABEL: @test1
     28 ; CHECK-FISL-DAG: fmr 0, 1
     29 ; CHECK-FISL-DAG: xsmaddadp 0, 2, 3
     30 ; CHECK-FISL-DAG: stxsdx 0, 0, 7
     31 ; CHECK-FISL-DAG: xsmaddadp 1, 2, 4
     32 ; CHECK-FISL-DAG: li [[C1:[0-9]+]], 8
     33 ; CHECK-FISL-DAG: stxsdx 1, 7, [[C1]]
     34 ; CHECK-FISL: blr
     35 }
     36 
     37 define void @test2(double %a, double %b, double %c, double %e, double %f, double* nocapture %d) #0 {
     38 entry:
     39   %0 = tail call double @llvm.fma.f64(double %b, double %c, double %a)
     40   store double %0, double* %d, align 8
     41   %1 = tail call double @llvm.fma.f64(double %b, double %e, double %a)
     42   %arrayidx1 = getelementptr inbounds double, double* %d, i64 1
     43   store double %1, double* %arrayidx1, align 8
     44   %2 = tail call double @llvm.fma.f64(double %b, double %f, double %a)
     45   %arrayidx2 = getelementptr inbounds double, double* %d, i64 2
     46   store double %2, double* %arrayidx2, align 8
     47   ret void
     48 
     49 ; CHECK-LABEL: @test2
     50 ; CHECK-DAG: li [[C1:[0-9]+]], 8
     51 ; CHECK-DAG: li [[C2:[0-9]+]], 16
     52 ; FIXME: We no longer get this because of copy ordering at the MI level.
     53 ; CHECX-DAG: xsmaddmdp 3, 2, 1
     54 ; CHECX-DAG: xsmaddmdp 4, 2, 1
     55 ; CHECX-DAG: xsmaddadp 1, 2, 5
     56 ; CHECX-DAG: stxsdx 3, 0, 8
     57 ; CHECX-DAG: stxsdx 4, 8, [[C1]]
     58 ; CHECX-DAG: stxsdx 1, 8, [[C2]]
     59 ; CHECK: blr
     60 
     61 ; CHECK-FISL-LABEL: @test2
     62 ; CHECK-FISL-DAG: fmr 0, 1
     63 ; CHECK-FISL-DAG: xsmaddadp 0, 2, 3
     64 ; CHECK-FISL-DAG: stxsdx 0, 0, 8
     65 ; CHECK-FISL-DAG: fmr 0, 1
     66 ; CHECK-FISL-DAG: xsmaddadp 0, 2, 4
     67 ; CHECK-FISL-DAG: li [[C1:[0-9]+]], 8
     68 ; CHECK-FISL-DAG: stxsdx 0, 8, [[C1]]
     69 ; CHECK-FISL-DAG: xsmaddadp 1, 2, 5
     70 ; CHECK-FISL-DAG: li [[C2:[0-9]+]], 16
     71 ; CHECK-FISL-DAG: stxsdx 1, 8, [[C2]]
     72 ; CHECK-FISL: blr
     73 }
     74 
     75 define void @test3(double %a, double %b, double %c, double %e, double %f, double* nocapture %d) #0 {
     76 entry:
     77   %0 = tail call double @llvm.fma.f64(double %b, double %c, double %a)
     78   store double %0, double* %d, align 8
     79   %1 = tail call double @llvm.fma.f64(double %b, double %e, double %a)
     80   %2 = tail call double @llvm.fma.f64(double %b, double %c, double %1)
     81   %arrayidx1 = getelementptr inbounds double, double* %d, i64 3
     82   store double %2, double* %arrayidx1, align 8
     83   %3 = tail call double @llvm.fma.f64(double %b, double %f, double %a)
     84   %arrayidx2 = getelementptr inbounds double, double* %d, i64 2
     85   store double %3, double* %arrayidx2, align 8
     86   %arrayidx3 = getelementptr inbounds double, double* %d, i64 1
     87   store double %1, double* %arrayidx3, align 8
     88   ret void
     89 
     90 ; CHECK-LABEL: @test3
     91 ; CHECK-DAG: fmr [[F1:[0-9]+]], 1
     92 ; CHECK-DAG: li [[C1:[0-9]+]], 24
     93 ; CHECK-DAG: li [[C2:[0-9]+]], 16
     94 ; CHECK-DAG: li [[C3:[0-9]+]], 8
     95 ; CHECK-DAG: xsmaddmdp 4, 2, 1
     96 ; CHECK-DAG: xsmaddadp 1, 2, 5
     97 
     98 ; Note: We could convert this next FMA to M-type as well, but it would require
     99 ; re-ordering the instructions.
    100 ; CHECK-DAG: xsmaddadp [[F1]], 2, 3
    101 
    102 ; CHECK-DAG: xsmaddmdp 3, 2, 4
    103 ; CHECK-DAG: stxsdx [[F1]], 0, 8
    104 ; CHECK-DAG: stxsdx 3, 8, [[C1]]
    105 ; CHECK-DAG: stxsdx 1, 8, [[C2]]
    106 ; CHECK-DAG: stxsdx 4, 8, [[C3]]
    107 ; CHECK: blr
    108 
    109 ; CHECK-FISL-LABEL: @test3
    110 ; CHECK-FISL-DAG: fmr [[F1:[0-9]+]], 1
    111 ; CHECK-FISL-DAG: xsmaddadp [[F1]], 2, 4
    112 ; CHECK-FISL-DAG: fmr 4, [[F1]]
    113 ; CHECK-FISL-DAG: xsmaddadp 4, 2, 3
    114 ; CHECK-FISL-DAG: li [[C1:[0-9]+]], 24
    115 ; CHECK-FISL-DAG: stxsdx 4, 8, [[C1]]
    116 ; CHECK-FISL-DAG: xsmaddadp 1, 2, 5
    117 ; CHECK-FISL-DAG: li [[C2:[0-9]+]], 16
    118 ; CHECK-FISL-DAG: stxsdx 1, 8, [[C2]]
    119 ; CHECK-FISL-DAG: li [[C3:[0-9]+]], 8
    120 ; CHECK-FISL-DAG: stxsdx 0, 8, [[C3]]
    121 ; CHECK-FISL: blr
    122 }
    123 
    124 define void @test4(double %a, double %b, double %c, double %e, double %f, double* nocapture %d) #0 {
    125 entry:
    126   %0 = tail call double @llvm.fma.f64(double %b, double %c, double %a)
    127   store double %0, double* %d, align 8
    128   %1 = tail call double @llvm.fma.f64(double %b, double %e, double %a)
    129   %arrayidx1 = getelementptr inbounds double, double* %d, i64 1
    130   store double %1, double* %arrayidx1, align 8
    131   %2 = tail call double @llvm.fma.f64(double %b, double %c, double %1)
    132   %arrayidx3 = getelementptr inbounds double, double* %d, i64 3
    133   store double %2, double* %arrayidx3, align 8
    134   %3 = tail call double @llvm.fma.f64(double %b, double %f, double %a)
    135   %arrayidx4 = getelementptr inbounds double, double* %d, i64 2
    136   store double %3, double* %arrayidx4, align 8
    137   ret void
    138 
    139 ; CHECK-LABEL: @test4
    140 ; CHECK-DAG: fmr [[F1:[0-9]+]], 1
    141 ; CHECK-DAG: li [[C1:[0-9]+]], 8
    142 ; CHECK-DAG: li [[C2:[0-9]+]], 16
    143 ; CHECK-DAG: xsmaddmdp 4, 2, 1
    144 
    145 ; Note: We could convert this next FMA to M-type as well, but it would require
    146 ; re-ordering the instructions.
    147 ; CHECK-DAG: xsmaddadp 1, 2, 5
    148 
    149 ; CHECK-DAG: xsmaddadp [[F1]], 2, 3
    150 ; CHECK-DAG: stxsdx [[F1]], 0, 8
    151 ; CHECK-DAG: stxsdx 4, 8, [[C1]]
    152 ; CHECK-DAG: li [[C3:[0-9]+]], 24
    153 ; CHECK-DAG: xsmaddadp 4, 2, 3
    154 ; CHECK-DAG: stxsdx 4, 8, [[C3]]
    155 ; CHECK-DAG: stxsdx 1, 8, [[C2]]
    156 ; CHECK: blr
    157 
    158 ; CHECK-FISL-LABEL: @test4
    159 ; CHECK-FISL-DAG: fmr [[F1:[0-9]+]], 1
    160 ; CHECK-FISL-DAG: xsmaddadp [[F1]], 2, 3
    161 ; CHECK-FISL-DAG: stxsdx 0, 0, 8
    162 ; CHECK-FISL-DAG: fmr [[F1]], 1
    163 ; CHECK-FISL-DAG: xsmaddadp [[F1]], 2, 4
    164 ; CHECK-FISL-DAG: li [[C3:[0-9]+]], 8
    165 ; CHECK-FISL-DAG: stxsdx 0, 8, [[C3]]
    166 ; CHECK-FISL-DAG: xsmaddadp 0, 2, 3
    167 ; CHECK-FISL-DAG: li [[C1:[0-9]+]], 24
    168 ; CHECK-FISL-DAG: stxsdx 0, 8, [[C1]]
    169 ; CHECK-FISL-DAG: xsmaddadp 1, 2, 5
    170 ; CHECK-FISL-DAG: li [[C2:[0-9]+]], 16
    171 ; CHECK-FISL-DAG: stxsdx 1, 8, [[C2]]
    172 ; CHECK-FISL: blr
    173 }
    174 
    175 declare double @llvm.fma.f64(double, double, double) #0
    176 
    177 define void @testv1(<2 x double> %a, <2 x double> %b, <2 x double> %c, <2 x double> %e, <2 x double>* nocapture %d) #0 {
    178 entry:
    179   %0 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> %a)
    180   store <2 x double> %0, <2 x double>* %d, align 8
    181   %1 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %e, <2 x double> %a)
    182   %arrayidx1 = getelementptr inbounds <2 x double>, <2 x double>* %d, i64 1
    183   store <2 x double> %1, <2 x double>* %arrayidx1, align 8
    184   ret void
    185 
    186 ; CHECK-LABEL: @testv1
    187 ; CHECK-DAG: xvmaddmdp 36, 35, 34
    188 ; CHECK-DAG: xvmaddadp 34, 35, 37
    189 ; CHECK-DAG: li [[C1:[0-9]+]], 16
    190 ; CHECK-DAG: stxvd2x 36, 0, 3
    191 ; CHECK-DAG: stxvd2x 34, 3, [[C1:[0-9]+]]
    192 ; CHECK: blr
    193 
    194 ; CHECK-FISL-LABEL: @testv1
    195 ; CHECK-FISL-DAG: xxlor 0, 34, 34
    196 ; CHECK-FISL-DAG: xvmaddadp 0, 35, 36
    197 ; CHECK-FISL-DAG: stxvd2x 0, 0, 3
    198 ; CHECK-FISL-DAG: xvmaddadp 34, 35, 37
    199 ; CHECK-FISL-DAG: li [[C1:[0-9]+]], 16
    200 ; CHECK-FISL-DAG: stxvd2x 34, 3, [[C1:[0-9]+]]
    201 ; CHECK-FISL: blr
    202 }
    203 
    204 define void @testv2(<2 x double> %a, <2 x double> %b, <2 x double> %c, <2 x double> %e, <2 x double> %f, <2 x double>* nocapture %d) #0 {
    205 entry:
    206   %0 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> %a)
    207   store <2 x double> %0, <2 x double>* %d, align 8
    208   %1 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %e, <2 x double> %a)
    209   %arrayidx1 = getelementptr inbounds <2 x double>, <2 x double>* %d, i64 1
    210   store <2 x double> %1, <2 x double>* %arrayidx1, align 8
    211   %2 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %f, <2 x double> %a)
    212   %arrayidx2 = getelementptr inbounds <2 x double>, <2 x double>* %d, i64 2
    213   store <2 x double> %2, <2 x double>* %arrayidx2, align 8
    214   ret void
    215 
    216 ; CHECK-LABEL: @testv2
    217 ; FIXME: We currently don't get this because of copy ordering on the MI level.
    218 ; CHECX-DAG: xvmaddmdp 36, 35, 34
    219 ; CHECX-DAG: xvmaddmdp 37, 35, 34
    220 ; CHECX-DAG: li [[C1:[0-9]+]], 16
    221 ; CHECX-DAG: li [[C2:[0-9]+]], 32
    222 ; CHECX-DAG: xvmaddadp 34, 35, 38
    223 ; CHECX-DAG: stxvd2x 36, 0, 3
    224 ; CHECX-DAG: stxvd2x 37, 3, [[C1:[0-9]+]]
    225 ; CHECX-DAG: stxvd2x 34, 3, [[C2:[0-9]+]]
    226 ; CHECK: blr
    227 
    228 ; CHECK-FISL-LABEL: @testv2
    229 ; CHECK-FISL-DAG: xxlor 0, 34, 34
    230 ; CHECK-FISL-DAG: xvmaddadp 0, 35, 36
    231 ; CHECK-FISL-DAG: stxvd2x 0, 0, 3
    232 ; CHECK-FISL-DAG: xxlor 0, 34, 34
    233 ; CHECK-FISL-DAG: xvmaddadp 0, 35, 37
    234 ; CHECK-FISL-DAG: li [[C1:[0-9]+]], 16
    235 ; CHECK-FISL-DAG: stxvd2x 0, 3, [[C1:[0-9]+]]
    236 ; CHECK-FISL-DAG: xvmaddadp 34, 35, 38
    237 ; CHECK-FISL-DAG: li [[C2:[0-9]+]], 32
    238 ; CHECK-FISL-DAG: stxvd2x 34, 3, [[C2:[0-9]+]]
    239 ; CHECK-FISL: blr
    240 }
    241 
    242 define void @testv3(<2 x double> %a, <2 x double> %b, <2 x double> %c, <2 x double> %e, <2 x double> %f, <2 x double>* nocapture %d) #0 {
    243 entry:
    244   %0 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> %a)
    245   store <2 x double> %0, <2 x double>* %d, align 8
    246   %1 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %e, <2 x double> %a)
    247   %2 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> %1)
    248   %arrayidx1 = getelementptr inbounds <2 x double>, <2 x double>* %d, i64 3
    249   store <2 x double> %2, <2 x double>* %arrayidx1, align 8
    250   %3 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %f, <2 x double> %a)
    251   %arrayidx2 = getelementptr inbounds <2 x double>, <2 x double>* %d, i64 2
    252   store <2 x double> %3, <2 x double>* %arrayidx2, align 8
    253   %arrayidx3 = getelementptr inbounds <2 x double>, <2 x double>* %d, i64 1
    254   store <2 x double> %1, <2 x double>* %arrayidx3, align 8
    255   ret void
    256 
    257 ; Note: There is some unavoidable changeability in this variant.  If the
    258 ; FMAs are reordered differently, the algorithm can pick a different
    259 ; multiplicand to destroy, changing the register assignment.  There isn't
    260 ; a good way to express this possibility, so hopefully this doesn't change
    261 ; too often.
    262 
    263 ; CHECK-LABEL: @testv3
    264 ; CHECK-DAG: xxlor [[V1:[0-9]+]], 34, 34
    265 ; CHECK-DAG: li [[C1:[0-9]+]], 48
    266 ; CHECK-DAG: li [[C2:[0-9]+]], 32
    267 ; CHECK-DAG: xvmaddmdp 37, 35, 34
    268 ; CHECK-DAG: li [[C3:[0-9]+]], 16
    269 
    270 ; Note: We could convert this next FMA to M-type as well, but it would require
    271 ; re-ordering the instructions.
    272 ; CHECK-DAG: xvmaddadp [[V1]], 35, 36
    273 
    274 ; CHECK-DAG: xvmaddmdp 36, 35, 37
    275 ; CHECK-DAG: xvmaddadp 34, 35, 38
    276 ; CHECK-DAG: stxvd2x 32, 0, 3
    277 ; CHECK-DAG: stxvd2x 36, 3, [[C1]]
    278 ; CHECK-DAG: stxvd2x 34, 3, [[C2]]
    279 ; CHECK-DAG: stxvd2x 37, 3, [[C3]]
    280 ; CHECK: blr
    281 
    282 ; CHECK-FISL-LABEL: @testv3
    283 ; CHECK-FISL-DAG: xxlor [[V1:[0-9]+]], 34, 34
    284 ; CHECK-FISL-DAG: xvmaddadp [[V1]], 35, 36
    285 ; CHECK-FISL-DAG: stxvd2x [[V1]], 0, 3
    286 ; CHECK-FISL-DAG: xxlor [[V2:[0-9]+]], 34, 34
    287 ; CHECK-FISL-DAG: xvmaddadp [[V2]], 35, 37
    288 ; CHECK-FISL-DAG: xxlor [[V3:[0-9]+]], 0, 0
    289 ; CHECK-FISL-DAG: xvmaddadp [[V3]], 35, 36
    290 ; CHECK-FISL-DAG: li [[C1:[0-9]+]], 48
    291 ; CHECK-FISL-DAG: stxvd2x [[V3]], 3, [[C1]]
    292 ; CHECK-FISL-DAG: xvmaddadp 34, 35, 38
    293 ; CHECK-FISL-DAG: li [[C2:[0-9]+]], 32
    294 ; CHECK-FISL-DAG: stxvd2x 34, 3, [[C2]]
    295 ; CHECK-FISL-DAG: li [[C3:[0-9]+]], 16
    296 ; CHECK-FISL-DAG: stxvd2x 0, 3, [[C3]]
    297 ; CHECK-FISL: blr
    298 }
    299 
    300 define void @testv4(<2 x double> %a, <2 x double> %b, <2 x double> %c, <2 x double> %e, <2 x double> %f, <2 x double>* nocapture %d) #0 {
    301 entry:
    302   %0 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> %a)
    303   store <2 x double> %0, <2 x double>* %d, align 8
    304   %1 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %e, <2 x double> %a)
    305   %arrayidx1 = getelementptr inbounds <2 x double>, <2 x double>* %d, i64 1
    306   store <2 x double> %1, <2 x double>* %arrayidx1, align 8
    307   %2 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %c, <2 x double> %1)
    308   %arrayidx3 = getelementptr inbounds <2 x double>, <2 x double>* %d, i64 3
    309   store <2 x double> %2, <2 x double>* %arrayidx3, align 8
    310   %3 = tail call <2 x double> @llvm.fma.v2f64(<2 x double> %b, <2 x double> %f, <2 x double> %a)
    311   %arrayidx4 = getelementptr inbounds <2 x double>, <2 x double>* %d, i64 2
    312   store <2 x double> %3, <2 x double>* %arrayidx4, align 8
    313   ret void
    314 
    315 ; CHECK-LABEL: @testv4
    316 ; CHECK-DAG: xxlor [[V1:[0-9]+]], 34, 34
    317 ; CHECK-DAG: xvmaddmdp 37, 35, 34
    318 ; CHECK-DAG: li [[C1:[0-9]+]], 16
    319 ; CHECK-DAG: li [[C2:[0-9]+]], 32
    320 ; CHECK-DAG: xvmaddadp 34, 35, 38
    321 
    322 ; Note: We could convert this next FMA to M-type as well, but it would require
    323 ; re-ordering the instructions.
    324 ; CHECK-DAG: xvmaddadp [[V1]], 35, 36
    325 
    326 ; CHECK-DAG: stxvd2x 32, 0, 3
    327 ; CHECK-DAG: stxvd2x 37, 3, [[C1]]
    328 ; CHECK-DAG: li [[C3:[0-9]+]], 48
    329 ; CHECK-DAG: xvmaddadp 37, 35, 36
    330 ; CHECK-DAG: stxvd2x 37, 3, [[C3]]
    331 ; CHECK-DAG: stxvd2x 34, 3, [[C2]]
    332 ; CHECK: blr
    333 
    334 ; CHECK-FISL-LABEL: @testv4
    335 ; CHECK-FISL-DAG: xxlor [[V1:[0-9]+]], 34, 34
    336 ; CHECK-FISL-DAG: xvmaddadp [[V1]], 35, 36
    337 ; CHECK-FISL-DAG: stxvd2x 0, 0, 3
    338 ; CHECK-FISL-DAG: xxlor [[V2:[0-9]+]], 34, 34
    339 ; CHECK-FISL-DAG: xvmaddadp [[V2]], 35, 37
    340 ; CHECK-FISL-DAG: li [[C1:[0-9]+]], 16
    341 ; CHECK-FISL-DAG: stxvd2x 0, 3, [[C1]]
    342 ; CHECK-FISL-DAG: xvmaddadp 0, 35, 37
    343 ; CHECK-FISL-DAG: li [[C3:[0-9]+]], 48
    344 ; CHECK-FISL-DAG: stxvd2x 0, 3, [[C3]]
    345 ; CHECK-FISL-DAG: xvmaddadp 0, 35, 36
    346 ; CHECK-FISL-DAG: li [[C2:[0-9]+]], 32
    347 ; CHECK-FISL-DAG: stxvd2x 34, 3, [[C2]]
    348 ; CHECK-FISL: blr
    349 }
    350 
    351 declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) #0
    352 
    353 attributes #0 = { nounwind readnone }
    354 
    355