Home | History | Annotate | Download | only in SystemZ
      1 ; Test sign extensions from a halfword to an i32.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 ; Test register extension, starting with an i32.
      6 define i32 @f1(i32 %a) {
      7 ; CHECK-LABEL: f1:
      8 ; CHECK: lhr %r2, %r2
      9 ; CHECK: br %r14
     10   %half = trunc i32 %a to i16
     11   %ext = sext i16 %half to i32
     12   ret i32 %ext
     13 }
     14 
     15 ; ...and again with an i64.
     16 define i32 @f2(i64 %a) {
     17 ; CHECK-LABEL: f2:
     18 ; CHECK: lhr %r2, %r2
     19 ; CHECK: br %r14
     20   %half = trunc i64 %a to i16
     21   %ext = sext i16 %half to i32
     22   ret i32 %ext
     23 }
     24 
     25 ; Check the low end of the LH range.
     26 define i32 @f3(i16 *%src) {
     27 ; CHECK-LABEL: f3:
     28 ; CHECK: lh %r2, 0(%r2)
     29 ; CHECK: br %r14
     30   %half = load i16 , i16 *%src
     31   %ext = sext i16 %half to i32
     32   ret i32 %ext
     33 }
     34 
     35 ; Check the high end of the LH range.
     36 define i32 @f4(i16 *%src) {
     37 ; CHECK-LABEL: f4:
     38 ; CHECK: lh %r2, 4094(%r2)
     39 ; CHECK: br %r14
     40   %ptr = getelementptr i16, i16 *%src, i64 2047
     41   %half = load i16 , i16 *%ptr
     42   %ext = sext i16 %half to i32
     43   ret i32 %ext
     44 }
     45 
     46 ; Check the next halfword up, which needs LHY rather than LH.
     47 define i32 @f5(i16 *%src) {
     48 ; CHECK-LABEL: f5:
     49 ; CHECK: lhy %r2, 4096(%r2)
     50 ; CHECK: br %r14
     51   %ptr = getelementptr i16, i16 *%src, i64 2048
     52   %half = load i16 , i16 *%ptr
     53   %ext = sext i16 %half to i32
     54   ret i32 %ext
     55 }
     56 
     57 ; Check the high end of the LHY range.
     58 define i32 @f6(i16 *%src) {
     59 ; CHECK-LABEL: f6:
     60 ; CHECK: lhy %r2, 524286(%r2)
     61 ; CHECK: br %r14
     62   %ptr = getelementptr i16, i16 *%src, i64 262143
     63   %half = load i16 , i16 *%ptr
     64   %ext = sext i16 %half to i32
     65   ret i32 %ext
     66 }
     67 
     68 ; Check the next halfword up, which needs separate address logic.
     69 ; Other sequences besides this one would be OK.
     70 define i32 @f7(i16 *%src) {
     71 ; CHECK-LABEL: f7:
     72 ; CHECK: agfi %r2, 524288
     73 ; CHECK: lh %r2, 0(%r2)
     74 ; CHECK: br %r14
     75   %ptr = getelementptr i16, i16 *%src, i64 262144
     76   %half = load i16 , i16 *%ptr
     77   %ext = sext i16 %half to i32
     78   ret i32 %ext
     79 }
     80 
     81 ; Check the high end of the negative LHY range.
     82 define i32 @f8(i16 *%src) {
     83 ; CHECK-LABEL: f8:
     84 ; CHECK: lhy %r2, -2(%r2)
     85 ; CHECK: br %r14
     86   %ptr = getelementptr i16, i16 *%src, i64 -1
     87   %half = load i16 , i16 *%ptr
     88   %ext = sext i16 %half to i32
     89   ret i32 %ext
     90 }
     91 
     92 ; Check the low end of the LHY range.
     93 define i32 @f9(i16 *%src) {
     94 ; CHECK-LABEL: f9:
     95 ; CHECK: lhy %r2, -524288(%r2)
     96 ; CHECK: br %r14
     97   %ptr = getelementptr i16, i16 *%src, i64 -262144
     98   %half = load i16 , i16 *%ptr
     99   %ext = sext i16 %half to i32
    100   ret i32 %ext
    101 }
    102 
    103 ; Check the next halfword down, which needs separate address logic.
    104 ; Other sequences besides this one would be OK.
    105 define i32 @f10(i16 *%src) {
    106 ; CHECK-LABEL: f10:
    107 ; CHECK: agfi %r2, -524290
    108 ; CHECK: lh %r2, 0(%r2)
    109 ; CHECK: br %r14
    110   %ptr = getelementptr i16, i16 *%src, i64 -262145
    111   %half = load i16 , i16 *%ptr
    112   %ext = sext i16 %half to i32
    113   ret i32 %ext
    114 }
    115 
    116 ; Check that LH allows an index
    117 define i32 @f11(i64 %src, i64 %index) {
    118 ; CHECK-LABEL: f11:
    119 ; CHECK: lh %r2, 4094(%r3,%r2)
    120 ; CHECK: br %r14
    121   %add1 = add i64 %src, %index
    122   %add2 = add i64 %add1, 4094
    123   %ptr = inttoptr i64 %add2 to i16 *
    124   %half = load i16 , i16 *%ptr
    125   %ext = sext i16 %half to i32
    126   ret i32 %ext
    127 }
    128 
    129 ; Check that LH allows an index
    130 define i32 @f12(i64 %src, i64 %index) {
    131 ; CHECK-LABEL: f12:
    132 ; CHECK: lhy %r2, 4096(%r3,%r2)
    133 ; CHECK: br %r14
    134   %add1 = add i64 %src, %index
    135   %add2 = add i64 %add1, 4096
    136   %ptr = inttoptr i64 %add2 to i16 *
    137   %half = load i16 , i16 *%ptr
    138   %ext = sext i16 %half to i32
    139   ret i32 %ext
    140 }
    141 
    142 ; Test a case where we spill the source of at least one LHR.  We want
    143 ; to use LH if possible.
    144 define void @f13(i32 *%ptr) {
    145 ; CHECK-LABEL: f13:
    146 ; CHECK: lh {{%r[0-9]+}}, 16{{[26]}}(%r15)
    147 ; CHECK: br %r14
    148   %val0 = load volatile i32 , i32 *%ptr
    149   %val1 = load volatile i32 , i32 *%ptr
    150   %val2 = load volatile i32 , i32 *%ptr
    151   %val3 = load volatile i32 , i32 *%ptr
    152   %val4 = load volatile i32 , i32 *%ptr
    153   %val5 = load volatile i32 , i32 *%ptr
    154   %val6 = load volatile i32 , i32 *%ptr
    155   %val7 = load volatile i32 , i32 *%ptr
    156   %val8 = load volatile i32 , i32 *%ptr
    157   %val9 = load volatile i32 , i32 *%ptr
    158   %val10 = load volatile i32 , i32 *%ptr
    159   %val11 = load volatile i32 , i32 *%ptr
    160   %val12 = load volatile i32 , i32 *%ptr
    161   %val13 = load volatile i32 , i32 *%ptr
    162   %val14 = load volatile i32 , i32 *%ptr
    163   %val15 = load volatile i32 , i32 *%ptr
    164 
    165   %trunc0 = trunc i32 %val0 to i16
    166   %trunc1 = trunc i32 %val1 to i16
    167   %trunc2 = trunc i32 %val2 to i16
    168   %trunc3 = trunc i32 %val3 to i16
    169   %trunc4 = trunc i32 %val4 to i16
    170   %trunc5 = trunc i32 %val5 to i16
    171   %trunc6 = trunc i32 %val6 to i16
    172   %trunc7 = trunc i32 %val7 to i16
    173   %trunc8 = trunc i32 %val8 to i16
    174   %trunc9 = trunc i32 %val9 to i16
    175   %trunc10 = trunc i32 %val10 to i16
    176   %trunc11 = trunc i32 %val11 to i16
    177   %trunc12 = trunc i32 %val12 to i16
    178   %trunc13 = trunc i32 %val13 to i16
    179   %trunc14 = trunc i32 %val14 to i16
    180   %trunc15 = trunc i32 %val15 to i16
    181 
    182   %ext0 = sext i16 %trunc0 to i32
    183   %ext1 = sext i16 %trunc1 to i32
    184   %ext2 = sext i16 %trunc2 to i32
    185   %ext3 = sext i16 %trunc3 to i32
    186   %ext4 = sext i16 %trunc4 to i32
    187   %ext5 = sext i16 %trunc5 to i32
    188   %ext6 = sext i16 %trunc6 to i32
    189   %ext7 = sext i16 %trunc7 to i32
    190   %ext8 = sext i16 %trunc8 to i32
    191   %ext9 = sext i16 %trunc9 to i32
    192   %ext10 = sext i16 %trunc10 to i32
    193   %ext11 = sext i16 %trunc11 to i32
    194   %ext12 = sext i16 %trunc12 to i32
    195   %ext13 = sext i16 %trunc13 to i32
    196   %ext14 = sext i16 %trunc14 to i32
    197   %ext15 = sext i16 %trunc15 to i32
    198 
    199   store volatile i32 %val0, i32 *%ptr
    200   store volatile i32 %val1, i32 *%ptr
    201   store volatile i32 %val2, i32 *%ptr
    202   store volatile i32 %val3, i32 *%ptr
    203   store volatile i32 %val4, i32 *%ptr
    204   store volatile i32 %val5, i32 *%ptr
    205   store volatile i32 %val6, i32 *%ptr
    206   store volatile i32 %val7, i32 *%ptr
    207   store volatile i32 %val8, i32 *%ptr
    208   store volatile i32 %val9, i32 *%ptr
    209   store volatile i32 %val10, i32 *%ptr
    210   store volatile i32 %val11, i32 *%ptr
    211   store volatile i32 %val12, i32 *%ptr
    212   store volatile i32 %val13, i32 *%ptr
    213   store volatile i32 %val14, i32 *%ptr
    214   store volatile i32 %val15, i32 *%ptr
    215 
    216   store volatile i32 %ext0, i32 *%ptr
    217   store volatile i32 %ext1, i32 *%ptr
    218   store volatile i32 %ext2, i32 *%ptr
    219   store volatile i32 %ext3, i32 *%ptr
    220   store volatile i32 %ext4, i32 *%ptr
    221   store volatile i32 %ext5, i32 *%ptr
    222   store volatile i32 %ext6, i32 *%ptr
    223   store volatile i32 %ext7, i32 *%ptr
    224   store volatile i32 %ext8, i32 *%ptr
    225   store volatile i32 %ext9, i32 *%ptr
    226   store volatile i32 %ext10, i32 *%ptr
    227   store volatile i32 %ext11, i32 *%ptr
    228   store volatile i32 %ext12, i32 *%ptr
    229   store volatile i32 %ext13, i32 *%ptr
    230   store volatile i32 %ext14, i32 *%ptr
    231   store volatile i32 %ext15, i32 *%ptr
    232 
    233   ret void
    234 }
    235