Home | History | Annotate | Download | only in SystemZ
      1 ; Test insertions of memory into the low byte of an i32.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 ; Check a plain insertion with (or (and ... -0xff) (zext (load ....))).
      6 ; The whole sequence can be performed by IC.
      7 define i32 @f1(i32 %orig, i8 *%ptr) {
      8 ; CHECK-LABEL: f1:
      9 ; CHECK-NOT: ni
     10 ; CHECK: ic %r2, 0(%r3)
     11 ; CHECK: br %r14
     12   %val = load i8 , i8 *%ptr
     13   %ptr2 = zext i8 %val to i32
     14   %ptr1 = and i32 %orig, -256
     15   %or = or i32 %ptr1, %ptr2
     16   ret i32 %or
     17 }
     18 
     19 ; Like f1, but with the operands reversed.
     20 define i32 @f2(i32 %orig, i8 *%ptr) {
     21 ; CHECK-LABEL: f2:
     22 ; CHECK-NOT: ni
     23 ; CHECK: ic %r2, 0(%r3)
     24 ; CHECK: br %r14
     25   %val = load i8 , i8 *%ptr
     26   %ptr2 = zext i8 %val to i32
     27   %ptr1 = and i32 %orig, -256
     28   %or = or i32 %ptr2, %ptr1
     29   ret i32 %or
     30 }
     31 
     32 ; Check a case where more bits than lower 8 are masked out of the
     33 ; register value.  We can use IC but must keep the original mask.
     34 define i32 @f3(i32 %orig, i8 *%ptr) {
     35 ; CHECK-LABEL: f3:
     36 ; CHECK: nill %r2, 65024
     37 ; CHECK: ic %r2, 0(%r3)
     38 ; CHECK: br %r14
     39   %val = load i8 , i8 *%ptr
     40   %ptr2 = zext i8 %val to i32
     41   %ptr1 = and i32 %orig, -512
     42   %or = or i32 %ptr1, %ptr2
     43   ret i32 %or
     44 }
     45 
     46 ; Like f3, but with the operands reversed.
     47 define i32 @f4(i32 %orig, i8 *%ptr) {
     48 ; CHECK-LABEL: f4:
     49 ; CHECK: nill %r2, 65024
     50 ; CHECK: ic %r2, 0(%r3)
     51 ; CHECK: br %r14
     52   %val = load i8 , i8 *%ptr
     53   %ptr2 = zext i8 %val to i32
     54   %ptr1 = and i32 %orig, -512
     55   %or = or i32 %ptr2, %ptr1
     56   ret i32 %or
     57 }
     58 
     59 ; Check a case where the low 8 bits are cleared by a shift left.
     60 define i32 @f5(i32 %orig, i8 *%ptr) {
     61 ; CHECK-LABEL: f5:
     62 ; CHECK: sll %r2, 8
     63 ; CHECK: ic %r2, 0(%r3)
     64 ; CHECK: br %r14
     65   %val = load i8 , i8 *%ptr
     66   %ptr2 = zext i8 %val to i32
     67   %ptr1 = shl i32 %orig, 8
     68   %or = or i32 %ptr1, %ptr2
     69   ret i32 %or
     70 }
     71 
     72 ; Like f5, but with the operands reversed.
     73 define i32 @f6(i32 %orig, i8 *%ptr) {
     74 ; CHECK-LABEL: f6:
     75 ; CHECK: sll %r2, 8
     76 ; CHECK: ic %r2, 0(%r3)
     77 ; CHECK: br %r14
     78   %val = load i8 , i8 *%ptr
     79   %ptr2 = zext i8 %val to i32
     80   %ptr1 = shl i32 %orig, 8
     81   %or = or i32 %ptr2, %ptr1
     82   ret i32 %or
     83 }
     84 
     85 ; Check insertions into a constant.
     86 define i32 @f7(i32 %orig, i8 *%ptr) {
     87 ; CHECK-LABEL: f7:
     88 ; CHECK: lhi %r2, 256
     89 ; CHECK: ic %r2, 0(%r3)
     90 ; CHECK: br %r14
     91   %val = load i8 , i8 *%ptr
     92   %ptr2 = zext i8 %val to i32
     93   %or = or i32 %ptr2, 256
     94   ret i32 %or
     95 }
     96 
     97 ; Like f7, but with the operands reversed.
     98 define i32 @f8(i32 %orig, i8 *%ptr) {
     99 ; CHECK-LABEL: f8:
    100 ; CHECK: lhi %r2, 256
    101 ; CHECK: ic %r2, 0(%r3)
    102 ; CHECK: br %r14
    103   %val = load i8 , i8 *%ptr
    104   %ptr2 = zext i8 %val to i32
    105   %or = or i32 256, %ptr2
    106   ret i32 %or
    107 }
    108 
    109 ; Check the high end of the IC range.
    110 define i32 @f9(i32 %orig, i8 *%src) {
    111 ; CHECK-LABEL: f9:
    112 ; CHECK: ic %r2, 4095(%r3)
    113 ; CHECK: br %r14
    114   %ptr = getelementptr i8, i8 *%src, i64 4095
    115   %val = load i8 , i8 *%ptr
    116   %src2 = zext i8 %val to i32
    117   %src1 = and i32 %orig, -256
    118   %or = or i32 %src2, %src1
    119   ret i32 %or
    120 }
    121 
    122 ; Check the next byte up, which should use ICY instead of IC.
    123 define i32 @f10(i32 %orig, i8 *%src) {
    124 ; CHECK-LABEL: f10:
    125 ; CHECK: icy %r2, 4096(%r3)
    126 ; CHECK: br %r14
    127   %ptr = getelementptr i8, i8 *%src, i64 4096
    128   %val = load i8 , i8 *%ptr
    129   %src2 = zext i8 %val to i32
    130   %src1 = and i32 %orig, -256
    131   %or = or i32 %src2, %src1
    132   ret i32 %or
    133 }
    134 
    135 ; Check the high end of the ICY range.
    136 define i32 @f11(i32 %orig, i8 *%src) {
    137 ; CHECK-LABEL: f11:
    138 ; CHECK: icy %r2, 524287(%r3)
    139 ; CHECK: br %r14
    140   %ptr = getelementptr i8, i8 *%src, i64 524287
    141   %val = load i8 , i8 *%ptr
    142   %src2 = zext i8 %val to i32
    143   %src1 = and i32 %orig, -256
    144   %or = or i32 %src2, %src1
    145   ret i32 %or
    146 }
    147 
    148 ; Check the next byte up, which needs separate address logic.
    149 ; Other sequences besides this one would be OK.
    150 define i32 @f12(i32 %orig, i8 *%src) {
    151 ; CHECK-LABEL: f12:
    152 ; CHECK: agfi %r3, 524288
    153 ; CHECK: ic %r2, 0(%r3)
    154 ; CHECK: br %r14
    155   %ptr = getelementptr i8, i8 *%src, i64 524288
    156   %val = load i8 , i8 *%ptr
    157   %src2 = zext i8 %val to i32
    158   %src1 = and i32 %orig, -256
    159   %or = or i32 %src2, %src1
    160   ret i32 %or
    161 }
    162 
    163 ; Check the high end of the negative ICY range.
    164 define i32 @f13(i32 %orig, i8 *%src) {
    165 ; CHECK-LABEL: f13:
    166 ; CHECK: icy %r2, -1(%r3)
    167 ; CHECK: br %r14
    168   %ptr = getelementptr i8, i8 *%src, i64 -1
    169   %val = load i8 , i8 *%ptr
    170   %src2 = zext i8 %val to i32
    171   %src1 = and i32 %orig, -256
    172   %or = or i32 %src2, %src1
    173   ret i32 %or
    174 }
    175 
    176 ; Check the low end of the ICY range.
    177 define i32 @f14(i32 %orig, i8 *%src) {
    178 ; CHECK-LABEL: f14:
    179 ; CHECK: icy %r2, -524288(%r3)
    180 ; CHECK: br %r14
    181   %ptr = getelementptr i8, i8 *%src, i64 -524288
    182   %val = load i8 , i8 *%ptr
    183   %src2 = zext i8 %val to i32
    184   %src1 = and i32 %orig, -256
    185   %or = or i32 %src2, %src1
    186   ret i32 %or
    187 }
    188 
    189 ; Check the next byte down, which needs separate address logic.
    190 ; Other sequences besides this one would be OK.
    191 define i32 @f15(i32 %orig, i8 *%src) {
    192 ; CHECK-LABEL: f15:
    193 ; CHECK: agfi %r3, -524289
    194 ; CHECK: ic %r2, 0(%r3)
    195 ; CHECK: br %r14
    196   %ptr = getelementptr i8, i8 *%src, i64 -524289
    197   %val = load i8 , i8 *%ptr
    198   %src2 = zext i8 %val to i32
    199   %src1 = and i32 %orig, -256
    200   %or = or i32 %src2, %src1
    201   ret i32 %or
    202 }
    203 
    204 ; Check that IC allows an index.
    205 define i32 @f16(i32 %orig, i8 *%src, i64 %index) {
    206 ; CHECK-LABEL: f16:
    207 ; CHECK: ic %r2, 4095({{%r4,%r3|%r3,%r4}})
    208 ; CHECK: br %r14
    209   %ptr1 = getelementptr i8, i8 *%src, i64 %index
    210   %ptr2 = getelementptr i8, i8 *%ptr1, i64 4095
    211   %val = load i8 , i8 *%ptr2
    212   %src2 = zext i8 %val to i32
    213   %src1 = and i32 %orig, -256
    214   %or = or i32 %src2, %src1
    215   ret i32 %or
    216 }
    217 
    218 ; Check that ICY allows an index.
    219 define i32 @f17(i32 %orig, i8 *%src, i64 %index) {
    220 ; CHECK-LABEL: f17:
    221 ; CHECK: icy %r2, 4096({{%r4,%r3|%r3,%r4}})
    222 ; CHECK: br %r14
    223   %ptr1 = getelementptr i8, i8 *%src, i64 %index
    224   %ptr2 = getelementptr i8, i8 *%ptr1, i64 4096
    225   %val = load i8 , i8 *%ptr2
    226   %src2 = zext i8 %val to i32
    227   %src1 = and i32 %orig, -256
    228   %or = or i32 %src2, %src1
    229   ret i32 %or
    230 }
    231