Home | History | Annotate | Download | only in SystemZ
      1 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \
      2 ; RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-SCALAR %s
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 \
      4 ; RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-VECTOR %s
      5 
      6 declare double @llvm.fma.f64(double %f1, double %f2, double %f3)
      7 
      8 define double @f1(double %f1, double %f2, double %acc) {
      9 ; CHECK-LABEL: f1:
     10 ; CHECK-SCALAR: msdbr %f4, %f0, %f2
     11 ; CHECK-SCALAR: ldr %f0, %f4
     12 ; CHECK-VECTOR: wfmsdb %f0, %f0, %f2, %f4
     13 ; CHECK: br %r14
     14   %negacc = fsub double -0.0, %acc
     15   %res = call double @llvm.fma.f64 (double %f1, double %f2, double %negacc)
     16   ret double %res
     17 }
     18 
     19 define double @f2(double %f1, double *%ptr, double %acc) {
     20 ; CHECK-LABEL: f2:
     21 ; CHECK: msdb %f2, %f0, 0(%r2)
     22 ; CHECK: ldr %f0, %f2
     23 ; CHECK: br %r14
     24   %f2 = load double , double *%ptr
     25   %negacc = fsub double -0.0, %acc
     26   %res = call double @llvm.fma.f64 (double %f1, double %f2, double %negacc)
     27   ret double %res
     28 }
     29 
     30 define double @f3(double %f1, double *%base, double %acc) {
     31 ; CHECK-LABEL: f3:
     32 ; CHECK: msdb %f2, %f0, 4088(%r2)
     33 ; CHECK: ldr %f0, %f2
     34 ; CHECK: br %r14
     35   %ptr = getelementptr double, double *%base, i64 511
     36   %f2 = load double , double *%ptr
     37   %negacc = fsub double -0.0, %acc
     38   %res = call double @llvm.fma.f64 (double %f1, double %f2, double %negacc)
     39   ret double %res
     40 }
     41 
     42 define double @f4(double %f1, double *%base, double %acc) {
     43 ; The important thing here is that we don't generate an out-of-range
     44 ; displacement.  Other sequences besides this one would be OK.
     45 ;
     46 ; CHECK-LABEL: f4:
     47 ; CHECK: aghi %r2, 4096
     48 ; CHECK: msdb %f2, %f0, 0(%r2)
     49 ; CHECK: ldr %f0, %f2
     50 ; CHECK: br %r14
     51   %ptr = getelementptr double, double *%base, i64 512
     52   %f2 = load double , double *%ptr
     53   %negacc = fsub double -0.0, %acc
     54   %res = call double @llvm.fma.f64 (double %f1, double %f2, double %negacc)
     55   ret double %res
     56 }
     57 
     58 define double @f5(double %f1, double *%base, double %acc) {
     59 ; Here too the important thing is that we don't generate an out-of-range
     60 ; displacement.  Other sequences besides this one would be OK.
     61 ;
     62 ; CHECK-LABEL: f5:
     63 ; CHECK: aghi %r2, -8
     64 ; CHECK: msdb %f2, %f0, 0(%r2)
     65 ; CHECK: ldr %f0, %f2
     66 ; CHECK: br %r14
     67   %ptr = getelementptr double, double *%base, i64 -1
     68   %f2 = load double , double *%ptr
     69   %negacc = fsub double -0.0, %acc
     70   %res = call double @llvm.fma.f64 (double %f1, double %f2, double %negacc)
     71   ret double %res
     72 }
     73 
     74 define double @f6(double %f1, double *%base, i64 %index, double %acc) {
     75 ; CHECK-LABEL: f6:
     76 ; CHECK: sllg %r1, %r3, 3
     77 ; CHECK: msdb %f2, %f0, 0(%r1,%r2)
     78 ; CHECK: ldr %f0, %f2
     79 ; CHECK: br %r14
     80   %ptr = getelementptr double, double *%base, i64 %index
     81   %f2 = load double , double *%ptr
     82   %negacc = fsub double -0.0, %acc
     83   %res = call double @llvm.fma.f64 (double %f1, double %f2, double %negacc)
     84   ret double %res
     85 }
     86 
     87 define double @f7(double %f1, double *%base, i64 %index, double %acc) {
     88 ; CHECK-LABEL: f7:
     89 ; CHECK: sllg %r1, %r3, 3
     90 ; CHECK: msdb %f2, %f0, 4088({{%r1,%r2|%r2,%r1}})
     91 ; CHECK: ldr %f0, %f2
     92 ; CHECK: br %r14
     93   %index2 = add i64 %index, 511
     94   %ptr = getelementptr double, double *%base, i64 %index2
     95   %f2 = load double , double *%ptr
     96   %negacc = fsub double -0.0, %acc
     97   %res = call double @llvm.fma.f64 (double %f1, double %f2, double %negacc)
     98   ret double %res
     99 }
    100 
    101 define double @f8(double %f1, double *%base, i64 %index, double %acc) {
    102 ; CHECK-LABEL: f8:
    103 ; CHECK: sllg %r1, %r3, 3
    104 ; CHECK: lay %r1, 4096({{%r1,%r2|%r2,%r1}})
    105 ; CHECK: msdb %f2, %f0, 0(%r1)
    106 ; CHECK: ldr %f0, %f2
    107 ; CHECK: br %r14
    108   %index2 = add i64 %index, 512
    109   %ptr = getelementptr double, double *%base, i64 %index2
    110   %f2 = load double , double *%ptr
    111   %negacc = fsub double -0.0, %acc
    112   %res = call double @llvm.fma.f64 (double %f1, double %f2, double %negacc)
    113   ret double %res
    114 }
    115