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