Home | History | Annotate | Download | only in SystemZ
      1 ; Test multiplication of two f64s, producing an f64 result.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \
      4 ; RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-SCALAR %s
      5 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
      6 
      7 declare double @foo()
      8 
      9 ; Check register multiplication.
     10 define double @f1(double %f1, double %f2) {
     11 ; CHECK-LABEL: f1:
     12 ; CHECK: mdbr %f0, %f2
     13 ; CHECK: br %r14
     14   %res = fmul double %f1, %f2
     15   ret double %res
     16 }
     17 
     18 ; Check the low end of the MDB range.
     19 define double @f2(double %f1, double *%ptr) {
     20 ; CHECK-LABEL: f2:
     21 ; CHECK: mdb %f0, 0(%r2)
     22 ; CHECK: br %r14
     23   %f2 = load double , double *%ptr
     24   %res = fmul double %f1, %f2
     25   ret double %res
     26 }
     27 
     28 ; Check the high end of the aligned MDB range.
     29 define double @f3(double %f1, double *%base) {
     30 ; CHECK-LABEL: f3:
     31 ; CHECK: mdb %f0, 4088(%r2)
     32 ; CHECK: br %r14
     33   %ptr = getelementptr double, double *%base, i64 511
     34   %f2 = load double , double *%ptr
     35   %res = fmul double %f1, %f2
     36   ret double %res
     37 }
     38 
     39 ; Check the next doubleword up, which needs separate address logic.
     40 ; Other sequences besides this one would be OK.
     41 define double @f4(double %f1, double *%base) {
     42 ; CHECK-LABEL: f4:
     43 ; CHECK: aghi %r2, 4096
     44 ; CHECK: mdb %f0, 0(%r2)
     45 ; CHECK: br %r14
     46   %ptr = getelementptr double, double *%base, i64 512
     47   %f2 = load double , double *%ptr
     48   %res = fmul double %f1, %f2
     49   ret double %res
     50 }
     51 
     52 ; Check negative displacements, which also need separate address logic.
     53 define double @f5(double %f1, double *%base) {
     54 ; CHECK-LABEL: f5:
     55 ; CHECK: aghi %r2, -8
     56 ; CHECK: mdb %f0, 0(%r2)
     57 ; CHECK: br %r14
     58   %ptr = getelementptr double, double *%base, i64 -1
     59   %f2 = load double , double *%ptr
     60   %res = fmul double %f1, %f2
     61   ret double %res
     62 }
     63 
     64 ; Check that MDB allows indices.
     65 define double @f6(double %f1, double *%base, i64 %index) {
     66 ; CHECK-LABEL: f6:
     67 ; CHECK: sllg %r1, %r3, 3
     68 ; CHECK: mdb %f0, 800(%r1,%r2)
     69 ; CHECK: br %r14
     70   %ptr1 = getelementptr double, double *%base, i64 %index
     71   %ptr2 = getelementptr double, double *%ptr1, i64 100
     72   %f2 = load double , double *%ptr2
     73   %res = fmul double %f1, %f2
     74   ret double %res
     75 }
     76 
     77 ; Check that multiplications of spilled values can use MDB rather than MDBR.
     78 define double @f7(double *%ptr0) {
     79 ; CHECK-LABEL: f7:
     80 ; CHECK: brasl %r14, foo@PLT
     81 ; CHECK-SCALAR: mdb %f0, 160(%r15)
     82 ; CHECK: br %r14
     83   %ptr1 = getelementptr double, double *%ptr0, i64 2
     84   %ptr2 = getelementptr double, double *%ptr0, i64 4
     85   %ptr3 = getelementptr double, double *%ptr0, i64 6
     86   %ptr4 = getelementptr double, double *%ptr0, i64 8
     87   %ptr5 = getelementptr double, double *%ptr0, i64 10
     88   %ptr6 = getelementptr double, double *%ptr0, i64 12
     89   %ptr7 = getelementptr double, double *%ptr0, i64 14
     90   %ptr8 = getelementptr double, double *%ptr0, i64 16
     91   %ptr9 = getelementptr double, double *%ptr0, i64 18
     92   %ptr10 = getelementptr double, double *%ptr0, i64 20
     93 
     94   %val0 = load double , double *%ptr0
     95   %val1 = load double , double *%ptr1
     96   %val2 = load double , double *%ptr2
     97   %val3 = load double , double *%ptr3
     98   %val4 = load double , double *%ptr4
     99   %val5 = load double , double *%ptr5
    100   %val6 = load double , double *%ptr6
    101   %val7 = load double , double *%ptr7
    102   %val8 = load double , double *%ptr8
    103   %val9 = load double , double *%ptr9
    104   %val10 = load double , double *%ptr10
    105 
    106   %ret = call double @foo()
    107 
    108   %mul0 = fmul double %ret, %val0
    109   %mul1 = fmul double %mul0, %val1
    110   %mul2 = fmul double %mul1, %val2
    111   %mul3 = fmul double %mul2, %val3
    112   %mul4 = fmul double %mul3, %val4
    113   %mul5 = fmul double %mul4, %val5
    114   %mul6 = fmul double %mul5, %val6
    115   %mul7 = fmul double %mul6, %val7
    116   %mul8 = fmul double %mul7, %val8
    117   %mul9 = fmul double %mul8, %val9
    118   %mul10 = fmul double %mul9, %val10
    119 
    120   ret double %mul10
    121 }
    122