Home | History | Annotate | Download | only in SystemZ
      1 ; Test 64-bit ordered comparisons that are really between a memory halfword
      2 ; and a constant.
      3 ;
      4 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      5 
      6 ; Check unsigned comparison near the low end of the CLHHSI range, using zero
      7 ; extension.
      8 define double @f1(double %a, double %b, i16 *%ptr) {
      9 ; CHECK-LABEL: f1:
     10 ; CHECK: clhhsi 0(%r2), 1
     11 ; CHECK-NEXT: jh
     12 ; CHECK: br %r14
     13   %val = load i16 , i16 *%ptr
     14   %ext = zext i16 %val to i64
     15   %cond = icmp ugt i64 %ext, 1
     16   %res = select i1 %cond, double %a, double %b
     17   ret double %res
     18 }
     19 
     20 ; Check unsigned comparison near the low end of the CLHHSI range, using sign
     21 ; extension.
     22 define double @f2(double %a, double %b, i16 *%ptr) {
     23 ; CHECK-LABEL: f2:
     24 ; CHECK: clhhsi 0(%r2), 1
     25 ; CHECK-NEXT: jh
     26 ; CHECK: br %r14
     27   %val = load i16 , i16 *%ptr
     28   %ext = sext i16 %val to i64
     29   %cond = icmp ugt i64 %ext, 1
     30   %res = select i1 %cond, double %a, double %b
     31   ret double %res
     32 }
     33 
     34 ; Check unsigned comparison near the high end of the CLHHSI range, using zero
     35 ; extension.
     36 define double @f3(double %a, double %b, i16 *%ptr) {
     37 ; CHECK-LABEL: f3:
     38 ; CHECK: clhhsi 0(%r2), 65534
     39 ; CHECK-NEXT: jl
     40 ; CHECK: br %r14
     41   %val = load i16 , i16 *%ptr
     42   %ext = zext i16 %val to i64
     43   %cond = icmp ult i64 %ext, 65534
     44   %res = select i1 %cond, double %a, double %b
     45   ret double %res
     46 }
     47 
     48 ; Check unsigned comparison near the high end of the CLHHSI range, using sign
     49 ; extension.
     50 define double @f4(double %a, double %b, i16 *%ptr) {
     51 ; CHECK-LABEL: f4:
     52 ; CHECK: clhhsi 0(%r2), 65534
     53 ; CHECK-NEXT: jl
     54 ; CHECK: br %r14
     55   %val = load i16 , i16 *%ptr
     56   %ext = sext i16 %val to i64
     57   %cond = icmp ult i64 %ext, -2
     58   %res = select i1 %cond, double %a, double %b
     59   ret double %res
     60 }
     61 
     62 ; Check unsigned comparison above the high end of the CLHHSI range, using zero
     63 ; extension.  The condition is always true.
     64 define double @f5(double %a, double %b, i16 *%ptr) {
     65 ; CHECK-LABEL: f5:
     66 ; CHECK-NOT: clhhsi
     67 ; CHECK: br %r14
     68   %val = load i16 , i16 *%ptr
     69   %ext = zext i16 %val to i64
     70   %cond = icmp ult i64 %ext, 65536
     71   %res = select i1 %cond, double %a, double %b
     72   ret double %res
     73 }
     74 
     75 ; When using unsigned comparison with sign extension, equality with values
     76 ; in the range [32768, MAX-32769] is impossible, and ordered comparisons with
     77 ; those values are effectively sign tests.  Since such comparisons are
     78 ; unlikely to occur in practice, we don't bother optimizing the second case,
     79 ; and simply ignore CLHHSI for this range.  First check the low end of the
     80 ; range.
     81 define double @f6(double %a, double %b, i16 *%ptr) {
     82 ; CHECK-LABEL: f6:
     83 ; CHECK-NOT: clhhsi
     84 ; CHECK: br %r14
     85   %val = load i16 , i16 *%ptr
     86   %ext = sext i16 %val to i64
     87   %cond = icmp ult i64 %ext, 32768
     88   %res = select i1 %cond, double %a, double %b
     89   ret double %res
     90 }
     91 
     92 ; ...and then the high end.
     93 define double @f7(double %a, double %b, i16 *%ptr) {
     94 ; CHECK-LABEL: f7:
     95 ; CHECK-NOT: clhhsi
     96 ; CHECK: br %r14
     97   %val = load i16 , i16 *%ptr
     98   %ext = sext i16 %val to i64
     99   %cond = icmp ult i64 %ext, -32769
    100   %res = select i1 %cond, double %a, double %b
    101   ret double %res
    102 }
    103 
    104 ; Check signed comparison near the low end of the CLHHSI range, using zero
    105 ; extension.  This is equivalent to unsigned comparison.
    106 define double @f8(double %a, double %b, i16 *%ptr) {
    107 ; CHECK-LABEL: f8:
    108 ; CHECK: clhhsi 0(%r2), 1
    109 ; CHECK-NEXT: jh
    110 ; CHECK: br %r14
    111   %val = load i16 , i16 *%ptr
    112   %ext = zext i16 %val to i64
    113   %cond = icmp sgt i64 %ext, 1
    114   %res = select i1 %cond, double %a, double %b
    115   ret double %res
    116 }
    117 
    118 ; Check signed comparison near the low end of the CLHHSI range, using sign
    119 ; extension.  This should use CHHSI instead.
    120 define double @f9(double %a, double %b, i16 *%ptr) {
    121 ; CHECK-LABEL: f9:
    122 ; CHECK: chhsi 0(%r2), 1
    123 ; CHECK-NEXT: jh
    124 ; CHECK: br %r14
    125   %val = load i16 , i16 *%ptr
    126   %ext = sext i16 %val to i64
    127   %cond = icmp sgt i64 %ext, 1
    128   %res = select i1 %cond, double %a, double %b
    129   ret double %res
    130 }
    131 
    132 ; Check signed comparison near the high end of the CLHHSI range, using zero
    133 ; extension.  This is equivalent to unsigned comparison.
    134 define double @f10(double %a, double %b, i16 *%ptr) {
    135 ; CHECK-LABEL: f10:
    136 ; CHECK: clhhsi 0(%r2), 65534
    137 ; CHECK-NEXT: jl
    138 ; CHECK: br %r14
    139   %val = load i16 , i16 *%ptr
    140   %ext = zext i16 %val to i64
    141   %cond = icmp slt i64 %ext, 65534
    142   %res = select i1 %cond, double %a, double %b
    143   ret double %res
    144 }
    145 
    146 ; Check signed comparison near the high end of the CLHHSI range, using sign
    147 ; extension.  This should use CHHSI instead.
    148 define double @f11(double %a, double %b, i16 *%ptr) {
    149 ; CHECK-LABEL: f11:
    150 ; CHECK: chhsi 0(%r2), -2
    151 ; CHECK-NEXT: jl
    152 ; CHECK: br %r14
    153   %val = load i16 , i16 *%ptr
    154   %ext = sext i16 %val to i64
    155   %cond = icmp slt i64 %ext, -2
    156   %res = select i1 %cond, double %a, double %b
    157   ret double %res
    158 }
    159 
    160 ; Check signed comparison above the high end of the CLHHSI range, using zero
    161 ; extension.  The condition is always true.
    162 define double @f12(double %a, double %b, i16 *%ptr) {
    163 ; CHECK-LABEL: f12:
    164 ; CHECK-NOT: cli
    165 ; CHECK: br %r14
    166   %val = load i16 , i16 *%ptr
    167   %ext = zext i16 %val to i64
    168   %cond = icmp slt i64 %ext, 65536
    169   %res = select i1 %cond, double %a, double %b
    170   ret double %res
    171 }
    172 
    173 ; Check signed comparison near the high end of the CHHSI range, using sign
    174 ; extension.
    175 define double @f13(double %a, double %b, i16 *%ptr) {
    176 ; CHECK-LABEL: f13:
    177 ; CHECK: chhsi 0(%r2), 32766
    178 ; CHECK-NEXT: jl
    179 ; CHECK: br %r14
    180   %val = load i16 , i16 *%ptr
    181   %ext = sext i16 %val to i64
    182   %cond = icmp slt i64 %ext, 32766
    183   %res = select i1 %cond, double %a, double %b
    184   ret double %res
    185 }
    186 
    187 ; Check signed comparison above the high end of the CHHSI range, using sign
    188 ; extension.  This condition is always true.
    189 define double @f14(double %a, double %b, i16 *%ptr) {
    190 ; CHECK-LABEL: f14:
    191 ; CHECK-NOT: chhsi
    192 ; CHECK: br %r14
    193   %val = load i16 , i16 *%ptr
    194   %ext = sext i16 %val to i64
    195   %cond = icmp slt i64 %ext, 32768
    196   %res = select i1 %cond, double %a, double %b
    197   ret double %res
    198 }
    199 
    200 ; Check signed comparison near the low end of the CHHSI range, using sign
    201 ; extension.
    202 define double @f15(double %a, double %b, i16 *%ptr) {
    203 ; CHECK-LABEL: f15:
    204 ; CHECK: chhsi 0(%r2), -32767
    205 ; CHECK-NEXT: jh
    206 ; CHECK: br %r14
    207   %val = load i16 , i16 *%ptr
    208   %ext = sext i16 %val to i64
    209   %cond = icmp sgt i64 %ext, -32767
    210   %res = select i1 %cond, double %a, double %b
    211   ret double %res
    212 }
    213 
    214 ; Check signed comparison below the low end of the CHHSI range, using sign
    215 ; extension.  This condition is always true.
    216 define double @f16(double %a, double %b, i16 *%ptr) {
    217 ; CHECK-LABEL: f16:
    218 ; CHECK-NOT: chhsi
    219 ; CHECK: br %r14
    220   %val = load i16 , i16 *%ptr
    221   %ext = sext i16 %val to i64
    222   %cond = icmp sgt i64 %ext, -32769
    223   %res = select i1 %cond, double %a, double %b
    224   ret double %res
    225 }
    226