Home | History | Annotate | Download | only in SystemZ
      1 ; Test 64-bit comparison in which the second operand is a zero-extended i32.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 declare i64 @foo()
      6 
      7 ; Check unsigned register comparison.
      8 define double @f1(double %a, double %b, i64 %i1, i32 %unext) {
      9 ; CHECK-LABEL: f1:
     10 ; CHECK: clgfr %r2, %r3
     11 ; CHECK-NEXT: jl
     12 ; CHECK: ldr %f0, %f2
     13 ; CHECK: br %r14
     14   %i2 = zext i32 %unext to i64
     15   %cond = icmp ult i64 %i1, %i2
     16   %res = select i1 %cond, double %a, double %b
     17   ret double %res
     18 }
     19 
     20 ; ...and again with a different representation.
     21 define double @f2(double %a, double %b, i64 %i1, i64 %unext) {
     22 ; CHECK-LABEL: f2:
     23 ; CHECK: clgfr %r2, %r3
     24 ; CHECK-NEXT: jl
     25 ; CHECK: ldr %f0, %f2
     26 ; CHECK: br %r14
     27   %i2 = and i64 %unext, 4294967295
     28   %cond = icmp ult i64 %i1, %i2
     29   %res = select i1 %cond, double %a, double %b
     30   ret double %res
     31 }
     32 
     33 ; Check signed register comparison, which can't use CLGFR.
     34 define double @f3(double %a, double %b, i64 %i1, i32 %unext) {
     35 ; CHECK-LABEL: f3:
     36 ; CHECK-NOT: clgfr
     37 ; CHECK: br %r14
     38   %i2 = zext i32 %unext to i64
     39   %cond = icmp slt i64 %i1, %i2
     40   %res = select i1 %cond, double %a, double %b
     41   ret double %res
     42 }
     43 
     44 ; ...and again with a different representation
     45 define double @f4(double %a, double %b, i64 %i1, i64 %unext) {
     46 ; CHECK-LABEL: f4:
     47 ; CHECK-NOT: clgfr
     48 ; CHECK: br %r14
     49   %i2 = and i64 %unext, 4294967295
     50   %cond = icmp slt i64 %i1, %i2
     51   %res = select i1 %cond, double %a, double %b
     52   ret double %res
     53 }
     54 
     55 ; Check register equality.
     56 define double @f5(double %a, double %b, i64 %i1, i32 %unext) {
     57 ; CHECK-LABEL: f5:
     58 ; CHECK: clgfr %r2, %r3
     59 ; CHECK-NEXT: je
     60 ; CHECK: ldr %f0, %f2
     61 ; CHECK: br %r14
     62   %i2 = zext i32 %unext to i64
     63   %cond = icmp eq i64 %i1, %i2
     64   %res = select i1 %cond, double %a, double %b
     65   ret double %res
     66 }
     67 
     68 ; ...and again with a different representation
     69 define double @f6(double %a, double %b, i64 %i1, i64 %unext) {
     70 ; CHECK-LABEL: f6:
     71 ; CHECK: clgfr %r2, %r3
     72 ; CHECK-NEXT: je
     73 ; CHECK: ldr %f0, %f2
     74 ; CHECK: br %r14
     75   %i2 = and i64 %unext, 4294967295
     76   %cond = icmp eq i64 %i1, %i2
     77   %res = select i1 %cond, double %a, double %b
     78   ret double %res
     79 }
     80 
     81 ; Check register inequality.
     82 define double @f7(double %a, double %b, i64 %i1, i32 %unext) {
     83 ; CHECK-LABEL: f7:
     84 ; CHECK: clgfr %r2, %r3
     85 ; CHECK-NEXT: jlh
     86 ; CHECK: ldr %f0, %f2
     87 ; CHECK: br %r14
     88   %i2 = zext i32 %unext to i64
     89   %cond = icmp ne i64 %i1, %i2
     90   %res = select i1 %cond, double %a, double %b
     91   ret double %res
     92 }
     93 
     94 ; ...and again with a different representation
     95 define double @f8(double %a, double %b, i64 %i1, i64 %unext) {
     96 ; CHECK-LABEL: f8:
     97 ; CHECK: clgfr %r2, %r3
     98 ; CHECK-NEXT: jlh
     99 ; CHECK: ldr %f0, %f2
    100 ; CHECK: br %r14
    101   %i2 = and i64 %unext, 4294967295
    102   %cond = icmp ne i64 %i1, %i2
    103   %res = select i1 %cond, double %a, double %b
    104   ret double %res
    105 }
    106 
    107 ; Check unsigned comparisonn with memory.
    108 define double @f9(double %a, double %b, i64 %i1, i32 *%ptr) {
    109 ; CHECK-LABEL: f9:
    110 ; CHECK: clgf %r2, 0(%r3)
    111 ; CHECK-NEXT: jl
    112 ; CHECK: ldr %f0, %f2
    113 ; CHECK: br %r14
    114   %unext = load i32 *%ptr
    115   %i2 = zext i32 %unext to i64
    116   %cond = icmp ult i64 %i1, %i2
    117   %res = select i1 %cond, double %a, double %b
    118   ret double %res
    119 }
    120 
    121 ; Check signed comparison with memory.
    122 define double @f10(double %a, double %b, i64 %i1, i32 *%ptr) {
    123 ; CHECK-LABEL: f10:
    124 ; CHECK-NOT: clgf
    125 ; CHECK: br %r14
    126   %unext = load i32 *%ptr
    127   %i2 = zext i32 %unext to i64
    128   %cond = icmp slt i64 %i1, %i2
    129   %res = select i1 %cond, double %a, double %b
    130   ret double %res
    131 }
    132 
    133 ; Check memory equality.
    134 define double @f11(double %a, double %b, i64 %i1, i32 *%ptr) {
    135 ; CHECK-LABEL: f11:
    136 ; CHECK: clgf %r2, 0(%r3)
    137 ; CHECK-NEXT: je
    138 ; CHECK: ldr %f0, %f2
    139 ; CHECK: br %r14
    140   %unext = load i32 *%ptr
    141   %i2 = zext i32 %unext to i64
    142   %cond = icmp eq i64 %i1, %i2
    143   %res = select i1 %cond, double %a, double %b
    144   ret double %res
    145 }
    146 
    147 ; Check memory inequality.
    148 define double @f12(double %a, double %b, i64 %i1, i32 *%ptr) {
    149 ; CHECK-LABEL: f12:
    150 ; CHECK: clgf %r2, 0(%r3)
    151 ; CHECK-NEXT: jlh
    152 ; CHECK: ldr %f0, %f2
    153 ; CHECK: br %r14
    154   %unext = load i32 *%ptr
    155   %i2 = zext i32 %unext to i64
    156   %cond = icmp ne i64 %i1, %i2
    157   %res = select i1 %cond, double %a, double %b
    158   ret double %res
    159 }
    160 
    161 ; Check the high end of the aligned CLGF range.
    162 define double @f13(double %a, double %b, i64 %i1, i32 *%base) {
    163 ; CHECK-LABEL: f13:
    164 ; CHECK: clgf %r2, 524284(%r3)
    165 ; CHECK-NEXT: jl
    166 ; CHECK: ldr %f0, %f2
    167 ; CHECK: br %r14
    168   %ptr = getelementptr i32 *%base, i64 131071
    169   %unext = load i32 *%ptr
    170   %i2 = zext i32 %unext to i64
    171   %cond = icmp ult i64 %i1, %i2
    172   %res = select i1 %cond, double %a, double %b
    173   ret double %res
    174 }
    175 
    176 ; Check the next word up, which needs separate address logic.
    177 ; Other sequences besides this one would be OK.
    178 define double @f14(double %a, double %b, i64 %i1, i32 *%base) {
    179 ; CHECK-LABEL: f14:
    180 ; CHECK: agfi %r3, 524288
    181 ; CHECK: clgf %r2, 0(%r3)
    182 ; CHECK-NEXT: jl
    183 ; CHECK: ldr %f0, %f2
    184 ; CHECK: br %r14
    185   %ptr = getelementptr i32 *%base, i64 131072
    186   %unext = load i32 *%ptr
    187   %i2 = zext i32 %unext to i64
    188   %cond = icmp ult i64 %i1, %i2
    189   %res = select i1 %cond, double %a, double %b
    190   ret double %res
    191 }
    192 
    193 ; Check the high end of the negative aligned CLGF range.
    194 define double @f15(double %a, double %b, i64 %i1, i32 *%base) {
    195 ; CHECK-LABEL: f15:
    196 ; CHECK: clgf %r2, -4(%r3)
    197 ; CHECK-NEXT: jl
    198 ; CHECK: ldr %f0, %f2
    199 ; CHECK: br %r14
    200   %ptr = getelementptr i32 *%base, i64 -1
    201   %unext = load i32 *%ptr
    202   %i2 = zext i32 %unext to i64
    203   %cond = icmp ult i64 %i1, %i2
    204   %res = select i1 %cond, double %a, double %b
    205   ret double %res
    206 }
    207 
    208 ; Check the low end of the CLGF range.
    209 define double @f16(double %a, double %b, i64 %i1, i32 *%base) {
    210 ; CHECK-LABEL: f16:
    211 ; CHECK: clgf %r2, -524288(%r3)
    212 ; CHECK-NEXT: jl
    213 ; CHECK: ldr %f0, %f2
    214 ; CHECK: br %r14
    215   %ptr = getelementptr i32 *%base, i64 -131072
    216   %unext = load i32 *%ptr
    217   %i2 = zext i32 %unext to i64
    218   %cond = icmp ult i64 %i1, %i2
    219   %res = select i1 %cond, double %a, double %b
    220   ret double %res
    221 }
    222 
    223 ; Check the next word down, which needs separate address logic.
    224 ; Other sequences besides this one would be OK.
    225 define double @f17(double %a, double %b, i64 %i1, i32 *%base) {
    226 ; CHECK-LABEL: f17:
    227 ; CHECK: agfi %r3, -524292
    228 ; CHECK: clgf %r2, 0(%r3)
    229 ; CHECK-NEXT: jl
    230 ; CHECK: ldr %f0, %f2
    231 ; CHECK: br %r14
    232   %ptr = getelementptr i32 *%base, i64 -131073
    233   %unext = load i32 *%ptr
    234   %i2 = zext i32 %unext to i64
    235   %cond = icmp ult i64 %i1, %i2
    236   %res = select i1 %cond, double %a, double %b
    237   ret double %res
    238 }
    239 
    240 ; Check that CLGF allows an index.
    241 define double @f18(double %a, double %b, i64 %i1, i64 %base, i64 %index) {
    242 ; CHECK-LABEL: f18:
    243 ; CHECK: clgf %r2, 524284({{%r4,%r3|%r3,%r4}})
    244 ; CHECK-NEXT: jl
    245 ; CHECK: ldr %f0, %f2
    246 ; CHECK: br %r14
    247   %add1 = add i64 %base, %index
    248   %add2 = add i64 %add1, 524284
    249   %ptr = inttoptr i64 %add2 to i32 *
    250   %unext = load i32 *%ptr
    251   %i2 = zext i32 %unext to i64
    252   %cond = icmp ult i64 %i1, %i2
    253   %res = select i1 %cond, double %a, double %b
    254   ret double %res
    255 }
    256 
    257 ; Check that comparisons of spilled values can use CLGF rather than CLGFR.
    258 define i64 @f19(i32 *%ptr0) {
    259 ; CHECK-LABEL: f19:
    260 ; CHECK: brasl %r14, foo@PLT
    261 ; CHECK: clgf {{%r[0-9]+}}, 16{{[04]}}(%r15)
    262 ; CHECK: br %r14
    263   %ptr1 = getelementptr i32 *%ptr0, i64 2
    264   %ptr2 = getelementptr i32 *%ptr0, i64 4
    265   %ptr3 = getelementptr i32 *%ptr0, i64 6
    266   %ptr4 = getelementptr i32 *%ptr0, i64 8
    267   %ptr5 = getelementptr i32 *%ptr0, i64 10
    268   %ptr6 = getelementptr i32 *%ptr0, i64 12
    269   %ptr7 = getelementptr i32 *%ptr0, i64 14
    270   %ptr8 = getelementptr i32 *%ptr0, i64 16
    271   %ptr9 = getelementptr i32 *%ptr0, i64 18
    272 
    273   %val0 = load i32 *%ptr0
    274   %val1 = load i32 *%ptr1
    275   %val2 = load i32 *%ptr2
    276   %val3 = load i32 *%ptr3
    277   %val4 = load i32 *%ptr4
    278   %val5 = load i32 *%ptr5
    279   %val6 = load i32 *%ptr6
    280   %val7 = load i32 *%ptr7
    281   %val8 = load i32 *%ptr8
    282   %val9 = load i32 *%ptr9
    283 
    284   %frob0 = add i32 %val0, 100
    285   %frob1 = add i32 %val1, 100
    286   %frob2 = add i32 %val2, 100
    287   %frob3 = add i32 %val3, 100
    288   %frob4 = add i32 %val4, 100
    289   %frob5 = add i32 %val5, 100
    290   %frob6 = add i32 %val6, 100
    291   %frob7 = add i32 %val7, 100
    292   %frob8 = add i32 %val8, 100
    293   %frob9 = add i32 %val9, 100
    294 
    295   store i32 %frob0, i32 *%ptr0
    296   store i32 %frob1, i32 *%ptr1
    297   store i32 %frob2, i32 *%ptr2
    298   store i32 %frob3, i32 *%ptr3
    299   store i32 %frob4, i32 *%ptr4
    300   store i32 %frob5, i32 *%ptr5
    301   store i32 %frob6, i32 *%ptr6
    302   store i32 %frob7, i32 *%ptr7
    303   store i32 %frob8, i32 *%ptr8
    304   store i32 %frob9, i32 *%ptr9
    305 
    306   %ret = call i64 @foo()
    307 
    308   %ext0 = zext i32 %frob0 to i64
    309   %ext1 = zext i32 %frob1 to i64
    310   %ext2 = zext i32 %frob2 to i64
    311   %ext3 = zext i32 %frob3 to i64
    312   %ext4 = zext i32 %frob4 to i64
    313   %ext5 = zext i32 %frob5 to i64
    314   %ext6 = zext i32 %frob6 to i64
    315   %ext7 = zext i32 %frob7 to i64
    316   %ext8 = zext i32 %frob8 to i64
    317   %ext9 = zext i32 %frob9 to i64
    318 
    319   %cmp0 = icmp ult i64 %ret, %ext0
    320   %cmp1 = icmp ult i64 %ret, %ext1
    321   %cmp2 = icmp ult i64 %ret, %ext2
    322   %cmp3 = icmp ult i64 %ret, %ext3
    323   %cmp4 = icmp ult i64 %ret, %ext4
    324   %cmp5 = icmp ult i64 %ret, %ext5
    325   %cmp6 = icmp ult i64 %ret, %ext6
    326   %cmp7 = icmp ult i64 %ret, %ext7
    327   %cmp8 = icmp ult i64 %ret, %ext8
    328   %cmp9 = icmp ult i64 %ret, %ext9
    329 
    330   %sel0 = select i1 %cmp0, i64 %ret, i64 0
    331   %sel1 = select i1 %cmp1, i64 %sel0, i64 1
    332   %sel2 = select i1 %cmp2, i64 %sel1, i64 2
    333   %sel3 = select i1 %cmp3, i64 %sel2, i64 3
    334   %sel4 = select i1 %cmp4, i64 %sel3, i64 4
    335   %sel5 = select i1 %cmp5, i64 %sel4, i64 5
    336   %sel6 = select i1 %cmp6, i64 %sel5, i64 6
    337   %sel7 = select i1 %cmp7, i64 %sel6, i64 7
    338   %sel8 = select i1 %cmp8, i64 %sel7, i64 8
    339   %sel9 = select i1 %cmp9, i64 %sel8, i64 9
    340 
    341   ret i64 %sel9
    342 }
    343