Home | History | Annotate | Download | only in SystemZ
      1 ; Test 64-bit floating-point comparison.  The tests assume a z10 implementation
      2 ; of select, using conditional branches rather than LOCGR.
      3 ;
      4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 \
      5 ; RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-SCALAR %s
      6 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 -verify-machineinstrs\
      7 ; RUN:   | FileCheck -check-prefix=CHECK -check-prefix=CHECK-VECTOR %s
      8 
      9 declare double @foo()
     10 
     11 ; Check comparison with registers.
     12 define i64 @f1(i64 %a, i64 %b, double %f1, double %f2) {
     13 ; CHECK-LABEL: f1:
     14 ; CHECK: cdbr %f0, %f2
     15 ; CHECK-SCALAR-NEXT: ber %r14
     16 ; CHECK-SCALAR: lgr %r2, %r3
     17 ; CHECK-VECTOR-NEXT: locgrne %r2, %r3
     18 ; CHECK: br %r14
     19   %cond = fcmp oeq double %f1, %f2
     20   %res = select i1 %cond, i64 %a, i64 %b
     21   ret i64 %res
     22 }
     23 
     24 ; Check the low end of the CDB range.
     25 define i64 @f2(i64 %a, i64 %b, double %f1, double *%ptr) {
     26 ; CHECK-LABEL: f2:
     27 ; CHECK: cdb %f0, 0(%r4)
     28 ; CHECK-SCALAR-NEXT: ber %r14
     29 ; CHECK-SCALAR: lgr %r2, %r3
     30 ; CHECK-VECTOR-NEXT: locgrne %r2, %r3
     31 ; CHECK: br %r14
     32   %f2 = load double , double *%ptr
     33   %cond = fcmp oeq double %f1, %f2
     34   %res = select i1 %cond, i64 %a, i64 %b
     35   ret i64 %res
     36 }
     37 
     38 ; Check the high end of the aligned CDB range.
     39 define i64 @f3(i64 %a, i64 %b, double %f1, double *%base) {
     40 ; CHECK-LABEL: f3:
     41 ; CHECK: cdb %f0, 4088(%r4)
     42 ; CHECK-SCALAR-NEXT: ber %r14
     43 ; CHECK-SCALAR: lgr %r2, %r3
     44 ; CHECK-VECTOR-NEXT: locgrne %r2, %r3
     45 ; CHECK: br %r14
     46   %ptr = getelementptr double, double *%base, i64 511
     47   %f2 = load double , double *%ptr
     48   %cond = fcmp oeq double %f1, %f2
     49   %res = select i1 %cond, i64 %a, i64 %b
     50   ret i64 %res
     51 }
     52 
     53 ; Check the next doubleword up, which needs separate address logic.
     54 ; Other sequences besides this one would be OK.
     55 define i64 @f4(i64 %a, i64 %b, double %f1, double *%base) {
     56 ; CHECK-LABEL: f4:
     57 ; CHECK: aghi %r4, 4096
     58 ; CHECK: cdb %f0, 0(%r4)
     59 ; CHECK-SCALAR-NEXT: ber %r14
     60 ; CHECK-SCALAR: lgr %r2, %r3
     61 ; CHECK-VECTOR-NEXT: locgrne %r2, %r3
     62 ; CHECK: br %r14
     63   %ptr = getelementptr double, double *%base, i64 512
     64   %f2 = load double , double *%ptr
     65   %cond = fcmp oeq double %f1, %f2
     66   %res = select i1 %cond, i64 %a, i64 %b
     67   ret i64 %res
     68 }
     69 
     70 ; Check negative displacements, which also need separate address logic.
     71 define i64 @f5(i64 %a, i64 %b, double %f1, double *%base) {
     72 ; CHECK-LABEL: f5:
     73 ; CHECK: aghi %r4, -8
     74 ; CHECK: cdb %f0, 0(%r4)
     75 ; CHECK-SCALAR-NEXT: ber %r14
     76 ; CHECK-SCALAR: lgr %r2, %r3
     77 ; CHECK-VECTOR-NEXT: locgrne %r2, %r3
     78 ; CHECK: br %r14
     79   %ptr = getelementptr double, double *%base, i64 -1
     80   %f2 = load double , double *%ptr
     81   %cond = fcmp oeq double %f1, %f2
     82   %res = select i1 %cond, i64 %a, i64 %b
     83   ret i64 %res
     84 }
     85 
     86 ; Check that CDB allows indices.
     87 define i64 @f6(i64 %a, i64 %b, double %f1, double *%base, i64 %index) {
     88 ; CHECK-LABEL: f6:
     89 ; CHECK: sllg %r1, %r5, 3
     90 ; CHECK: cdb %f0, 800(%r1,%r4)
     91 ; CHECK-SCALAR-NEXT: ber %r14
     92 ; CHECK-SCALAR: lgr %r2, %r3
     93 ; CHECK-VECTOR-NEXT: locgrne %r2, %r3
     94 ; CHECK: br %r14
     95   %ptr1 = getelementptr double, double *%base, i64 %index
     96   %ptr2 = getelementptr double, double *%ptr1, i64 100
     97   %f2 = load double , double *%ptr2
     98   %cond = fcmp oeq double %f1, %f2
     99   %res = select i1 %cond, i64 %a, i64 %b
    100   ret i64 %res
    101 }
    102 
    103 ; Check that comparisons of spilled values can use CDB rather than CDBR.
    104 define double @f7(double *%ptr0) {
    105 ; CHECK-LABEL: f7:
    106 ; CHECK: brasl %r14, foo@PLT
    107 ; CHECK-SCALAR: cdb {{%f[0-9]+}}, 160(%r15)
    108 ; CHECK: br %r14
    109   %ptr1 = getelementptr double, double *%ptr0, i64 2
    110   %ptr2 = getelementptr double, double *%ptr0, i64 4
    111   %ptr3 = getelementptr double, double *%ptr0, i64 6
    112   %ptr4 = getelementptr double, double *%ptr0, i64 8
    113   %ptr5 = getelementptr double, double *%ptr0, i64 10
    114   %ptr6 = getelementptr double, double *%ptr0, i64 12
    115   %ptr7 = getelementptr double, double *%ptr0, i64 14
    116   %ptr8 = getelementptr double, double *%ptr0, i64 16
    117   %ptr9 = getelementptr double, double *%ptr0, i64 18
    118   %ptr10 = getelementptr double, double *%ptr0, i64 20
    119 
    120   %val0 = load double , double *%ptr0
    121   %val1 = load double , double *%ptr1
    122   %val2 = load double , double *%ptr2
    123   %val3 = load double , double *%ptr3
    124   %val4 = load double , double *%ptr4
    125   %val5 = load double , double *%ptr5
    126   %val6 = load double , double *%ptr6
    127   %val7 = load double , double *%ptr7
    128   %val8 = load double , double *%ptr8
    129   %val9 = load double , double *%ptr9
    130   %val10 = load double , double *%ptr10
    131 
    132   %ret = call double @foo()
    133 
    134   %cmp0 = fcmp olt double %ret, %val0
    135   %cmp1 = fcmp olt double %ret, %val1
    136   %cmp2 = fcmp olt double %ret, %val2
    137   %cmp3 = fcmp olt double %ret, %val3
    138   %cmp4 = fcmp olt double %ret, %val4
    139   %cmp5 = fcmp olt double %ret, %val5
    140   %cmp6 = fcmp olt double %ret, %val6
    141   %cmp7 = fcmp olt double %ret, %val7
    142   %cmp8 = fcmp olt double %ret, %val8
    143   %cmp9 = fcmp olt double %ret, %val9
    144   %cmp10 = fcmp olt double %ret, %val10
    145 
    146   %sel0 = select i1 %cmp0, double %ret, double 0.0
    147   %sel1 = select i1 %cmp1, double %sel0, double 1.0
    148   %sel2 = select i1 %cmp2, double %sel1, double 2.0
    149   %sel3 = select i1 %cmp3, double %sel2, double 3.0
    150   %sel4 = select i1 %cmp4, double %sel3, double 4.0
    151   %sel5 = select i1 %cmp5, double %sel4, double 5.0
    152   %sel6 = select i1 %cmp6, double %sel5, double 6.0
    153   %sel7 = select i1 %cmp7, double %sel6, double 7.0
    154   %sel8 = select i1 %cmp8, double %sel7, double 8.0
    155   %sel9 = select i1 %cmp9, double %sel8, double 9.0
    156   %sel10 = select i1 %cmp10, double %sel9, double 10.0
    157 
    158   ret double %sel10
    159 }
    160 
    161 ; Check comparison with zero.
    162 define i64 @f8(i64 %a, i64 %b, double %f) {
    163 ; CHECK-LABEL: f8:
    164 ; CHECK-SCALAR: ltdbr %f0, %f0
    165 ; CHECK-SCALAR-NEXT: ber %r14
    166 ; CHECK-SCALAR: lgr %r2, %r3
    167 ; CHECK-VECTOR: ltdbr %f0, %f0
    168 ; CHECK-VECTOR-NEXT: locgrne %r2, %r3
    169 ; CHECK: br %r14
    170   %cond = fcmp oeq double %f, 0.0
    171   %res = select i1 %cond, i64 %a, i64 %b
    172   ret i64 %res
    173 }
    174 
    175 ; Check the comparison can be reversed if that allows CDB to be used,
    176 define i64 @f9(i64 %a, i64 %b, double %f2, double *%ptr) {
    177 ; CHECK-LABEL: f9:
    178 ; CHECK: cdb %f0, 0(%r4)
    179 ; CHECK-SCALAR-NEXT: blr %r14
    180 ; CHECK-SCALAR: lgr %r2, %r3
    181 ; CHECK-VECTOR-NEXT: locgrnl %r2, %r3
    182 ; CHECK: br %r14
    183   %f1 = load double , double *%ptr
    184   %cond = fcmp ogt double %f1, %f2
    185   %res = select i1 %cond, i64 %a, i64 %b
    186   ret i64 %res
    187 }
    188