Home | History | Annotate | Download | only in SystemZ
      1 ; Test 32-bit signed comparison in which the second operand is sign-extended
      2 ; from an i16 memory value.
      3 ;
      4 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      5 
      6 ; Check the low end of the CH range.
      7 define void @f1(i32 %lhs, i16 *%src, i32 *%dst) {
      8 ; CHECK-LABEL: f1:
      9 ; CHECK: ch %r2, 0(%r3)
     10 ; CHECK: br %r14
     11   %half = load i16 , i16 *%src
     12   %rhs = sext i16 %half to i32
     13   %cond = icmp slt i32 %lhs, %rhs
     14   %res = select i1 %cond, i32 100, i32 200
     15   store i32 %res, i32 *%dst
     16   ret void
     17 }
     18 
     19 ; Check the high end of the aligned CH range.
     20 define void @f2(i32 %lhs, i16 *%src, i32 *%dst) {
     21 ; CHECK-LABEL: f2:
     22 ; CHECK: ch %r2, 4094(%r3)
     23 ; CHECK: br %r14
     24   %ptr = getelementptr i16, i16 *%src, i64 2047
     25   %half = load i16 , i16 *%ptr
     26   %rhs = sext i16 %half to i32
     27   %cond = icmp slt i32 %lhs, %rhs
     28   %res = select i1 %cond, i32 100, i32 200
     29   store i32 %res, i32 *%dst
     30   ret void
     31 }
     32 
     33 ; Check the next halfword up, which should use CHY instead of CH.
     34 define void @f3(i32 %lhs, i16 *%src, i32 *%dst) {
     35 ; CHECK-LABEL: f3:
     36 ; CHECK: chy %r2, 4096(%r3)
     37 ; CHECK: br %r14
     38   %ptr = getelementptr i16, i16 *%src, i64 2048
     39   %half = load i16 , i16 *%ptr
     40   %rhs = sext i16 %half to i32
     41   %cond = icmp slt i32 %lhs, %rhs
     42   %res = select i1 %cond, i32 100, i32 200
     43   store i32 %res, i32 *%dst
     44   ret void
     45 }
     46 
     47 ; Check the high end of the aligned CHY range.
     48 define void @f4(i32 %lhs, i16 *%src, i32 *%dst) {
     49 ; CHECK-LABEL: f4:
     50 ; CHECK: chy %r2, 524286(%r3)
     51 ; CHECK: br %r14
     52   %ptr = getelementptr i16, i16 *%src, i64 262143
     53   %half = load i16 , i16 *%ptr
     54   %rhs = sext i16 %half to i32
     55   %cond = icmp slt i32 %lhs, %rhs
     56   %res = select i1 %cond, i32 100, i32 200
     57   store i32 %res, i32 *%dst
     58   ret void
     59 }
     60 
     61 ; Check the next halfword up, which needs separate address logic.
     62 ; Other sequences besides this one would be OK.
     63 define void @f5(i32 %lhs, i16 *%src, i32 *%dst) {
     64 ; CHECK-LABEL: f5:
     65 ; CHECK: agfi %r3, 524288
     66 ; CHECK: ch %r2, 0(%r3)
     67 ; CHECK: br %r14
     68   %ptr = getelementptr i16, i16 *%src, i64 262144
     69   %half = load i16 , i16 *%ptr
     70   %rhs = sext i16 %half to i32
     71   %cond = icmp slt i32 %lhs, %rhs
     72   %res = select i1 %cond, i32 100, i32 200
     73   store i32 %res, i32 *%dst
     74   ret void
     75 }
     76 
     77 ; Check the high end of the negative aligned CHY range.
     78 define void @f6(i32 %lhs, i16 *%src, i32 *%dst) {
     79 ; CHECK-LABEL: f6:
     80 ; CHECK: chy %r2, -2(%r3)
     81 ; CHECK: br %r14
     82   %ptr = getelementptr i16, i16 *%src, i64 -1
     83   %half = load i16 , i16 *%ptr
     84   %rhs = sext i16 %half to i32
     85   %cond = icmp slt i32 %lhs, %rhs
     86   %res = select i1 %cond, i32 100, i32 200
     87   store i32 %res, i32 *%dst
     88   ret void
     89 }
     90 
     91 ; Check the low end of the CHY range.
     92 define void @f7(i32 %lhs, i16 *%src, i32 *%dst) {
     93 ; CHECK-LABEL: f7:
     94 ; CHECK: chy %r2, -524288(%r3)
     95 ; CHECK: br %r14
     96   %ptr = getelementptr i16, i16 *%src, i64 -262144
     97   %half = load i16 , i16 *%ptr
     98   %rhs = sext i16 %half to i32
     99   %cond = icmp slt i32 %lhs, %rhs
    100   %res = select i1 %cond, i32 100, i32 200
    101   store i32 %res, i32 *%dst
    102   ret void
    103 }
    104 
    105 ; Check the next halfword down, which needs separate address logic.
    106 ; Other sequences besides this one would be OK.
    107 define void @f8(i32 %lhs, i16 *%src, i32 *%dst) {
    108 ; CHECK-LABEL: f8:
    109 ; CHECK: agfi %r3, -524290
    110 ; CHECK: ch %r2, 0(%r3)
    111 ; CHECK: br %r14
    112   %ptr = getelementptr i16, i16 *%src, i64 -262145
    113   %half = load i16 , i16 *%ptr
    114   %rhs = sext i16 %half to i32
    115   %cond = icmp slt i32 %lhs, %rhs
    116   %res = select i1 %cond, i32 100, i32 200
    117   store i32 %res, i32 *%dst
    118   ret void
    119 }
    120 
    121 ; Check that CH allows an index.
    122 define void @f9(i32 %lhs, i64 %base, i64 %index, i32 *%dst) {
    123 ; CHECK-LABEL: f9:
    124 ; CHECK: ch %r2, 4094({{%r4,%r3|%r3,%r4}})
    125 ; CHECK: br %r14
    126   %add1 = add i64 %base, %index
    127   %add2 = add i64 %add1, 4094
    128   %ptr = inttoptr i64 %add2 to i16 *
    129   %half = load i16 , i16 *%ptr
    130   %rhs = sext i16 %half to i32
    131   %cond = icmp slt i32 %lhs, %rhs
    132   %res = select i1 %cond, i32 100, i32 200
    133   store i32 %res, i32 *%dst
    134   ret void
    135 }
    136 
    137 ; Check that CHY allows an index.
    138 define void @f10(i32 %lhs, i64 %base, i64 %index, i32 *%dst) {
    139 ; CHECK-LABEL: f10:
    140 ; CHECK: chy %r2, 4096({{%r4,%r3|%r3,%r4}})
    141 ; CHECK: br %r14
    142   %add1 = add i64 %base, %index
    143   %add2 = add i64 %add1, 4096
    144   %ptr = inttoptr i64 %add2 to i16 *
    145   %half = load i16 , i16 *%ptr
    146   %rhs = sext i16 %half to i32
    147   %cond = icmp slt i32 %lhs, %rhs
    148   %res = select i1 %cond, i32 100, i32 200
    149   store i32 %res, i32 *%dst
    150   ret void
    151 }
    152 
    153 ; Check the comparison can be reversed if that allows CH to be used.
    154 define double @f11(double %a, double %b, i32 %rhs, i16 *%src) {
    155 ; CHECK-LABEL: f11:
    156 ; CHECK: ch %r2, 0(%r3)
    157 ; CHECK-NEXT: jh {{\.L.*}}
    158 ; CHECK: ldr %f0, %f2
    159 ; CHECK: br %r14
    160   %half = load i16 , i16 *%src
    161   %lhs = sext i16 %half to i32
    162   %cond = icmp slt i32 %lhs, %rhs
    163   %res = select i1 %cond, double %a, double %b
    164   ret double %res
    165 }
    166