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