Home | History | Annotate | Download | only in SystemZ
      1 ; Test insertions of i32s into the low half of an i64.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 ; Insertion of an i32 can be done using LR.
      6 define i64 @f1(i64 %a, i32 %b) {
      7 ; CHECK-LABEL: f1:
      8 ; CHECK-NOT: {{%r[23]}}
      9 ; CHECK: lr %r2, %r3
     10 ; CHECK: br %r14
     11   %low = zext i32 %b to i64
     12   %high = and i64 %a, -4294967296
     13   %res = or i64 %high, %low
     14   ret i64 %res
     15 }
     16 
     17 ; ... and again with the operands reversed.
     18 define i64 @f2(i64 %a, i32 %b) {
     19 ; CHECK-LABEL: f2:
     20 ; CHECK-NOT: {{%r[23]}}
     21 ; CHECK: lr %r2, %r3
     22 ; CHECK: br %r14
     23   %low = zext i32 %b to i64
     24   %high = and i64 %a, -4294967296
     25   %res = or i64 %low, %high
     26   ret i64 %res
     27 }
     28 
     29 ; Like f1, but with "in register" zero extension.
     30 define i64 @f3(i64 %a, i64 %b) {
     31 ; CHECK-LABEL: f3:
     32 ; CHECK-NOT: {{%r[23]}}
     33 ; CHECK: lr %r2, %r3
     34 ; CHECK: br %r14
     35   %low = and i64 %b, 4294967295
     36   %high = and i64 %a, -4294967296
     37   %res = or i64 %high, %low
     38   ret i64 %res
     39 }
     40 
     41 ; ... and again with the operands reversed.
     42 define i64 @f4(i64 %a, i64 %b) {
     43 ; CHECK-LABEL: f4:
     44 ; CHECK-NOT: {{%r[23]}}
     45 ; CHECK: lr %r2, %r3
     46 ; CHECK: br %r14
     47   %low = and i64 %b, 4294967295
     48   %high = and i64 %a, -4294967296
     49   %res = or i64 %low, %high
     50   ret i64 %res
     51 }
     52 
     53 ; Unary operations can be done directly into the low half.
     54 define i64 @f5(i64 %a, i32 %b) {
     55 ; CHECK-LABEL: f5:
     56 ; CHECK-NOT: {{%r[23]}}
     57 ; CHECK: lcr %r2, %r3
     58 ; CHECK: br %r14
     59   %neg = sub i32 0, %b
     60   %low = zext i32 %neg to i64
     61   %high = and i64 %a, -4294967296
     62   %res = or i64 %high, %low
     63   ret i64 %res
     64 }
     65 
     66 ; ...likewise three-operand binary operations like RLL.
     67 define i64 @f6(i64 %a, i32 %b) {
     68 ; CHECK-LABEL: f6:
     69 ; CHECK-NOT: {{%r[23]}}
     70 ; CHECK: rll %r2, %r3, 1
     71 ; CHECK: br %r14
     72   %parta = shl i32 %b, 1
     73   %partb = lshr i32 %b, 31
     74   %rot = or i32 %parta, %partb
     75   %low = zext i32 %rot to i64
     76   %high = and i64 %a, -4294967296
     77   %res = or i64 %low, %high
     78   ret i64 %res
     79 }
     80 
     81 ; Loads can be done directly into the low half.  The range of L is checked
     82 ; in the move tests.
     83 define i64 @f7(i64 %a, i32 *%src) {
     84 ; CHECK-LABEL: f7:
     85 ; CHECK-NOT: {{%r[23]}}
     86 ; CHECK: l %r2, 0(%r3)
     87 ; CHECK: br %r14
     88   %b = load i32 , i32 *%src
     89   %low = zext i32 %b to i64
     90   %high = and i64 %a, -4294967296
     91   %res = or i64 %high, %low
     92   ret i64 %res
     93 }
     94 
     95 ; ...likewise extending loads.
     96 define i64 @f8(i64 %a, i8 *%src) {
     97 ; CHECK-LABEL: f8:
     98 ; CHECK-NOT: {{%r[23]}}
     99 ; CHECK: lb %r2, 0(%r3)
    100 ; CHECK: br %r14
    101   %byte = load i8 , i8 *%src
    102   %b = sext i8 %byte to i32
    103   %low = zext i32 %b to i64
    104   %high = and i64 %a, -4294967296
    105   %res = or i64 %high, %low
    106   ret i64 %res
    107 }
    108 
    109 ; Check a case like f1 in which there is no AND.  We simply know from context
    110 ; that the upper half of one OR operand and the lower half of the other are
    111 ; both clear.
    112 define i64 @f9(i64 %a, i32 %b) {
    113 ; CHECK-LABEL: f9:
    114 ; CHECK: sllg %r2, %r2, 32
    115 ; CHECK: lr %r2, %r3
    116 ; CHECK: br %r14
    117   %shift = shl i64 %a, 32
    118   %low = zext i32 %b to i64
    119   %or = or i64 %shift, %low
    120   ret i64 %or
    121 }
    122 
    123 ; ...and again with the operands reversed.
    124 define i64 @f10(i64 %a, i32 %b) {
    125 ; CHECK-LABEL: f10:
    126 ; CHECK: sllg %r2, %r2, 32
    127 ; CHECK: lr %r2, %r3
    128 ; CHECK: br %r14
    129   %shift = shl i64 %a, 32
    130   %low = zext i32 %b to i64
    131   %or = or i64 %low, %shift
    132   ret i64 %or
    133 }
    134 
    135 ; Like f9, but with "in register" zero extension.
    136 define i64 @f11(i64 %a, i64 %b) {
    137 ; CHECK-LABEL: f11:
    138 ; CHECK: lr %r2, %r3
    139 ; CHECK: br %r14
    140   %shift = shl i64 %a, 32
    141   %low = and i64 %b, 4294967295
    142   %or = or i64 %shift, %low
    143   ret i64 %or
    144 }
    145 
    146 ; ...and again with the operands reversed.
    147 define i64 @f12(i64 %a, i64 %b) {
    148 ; CHECK-LABEL: f12:
    149 ; CHECK: lr %r2, %r3
    150 ; CHECK: br %r14
    151   %shift = shl i64 %a, 32
    152   %low = and i64 %b, 4294967295
    153   %or = or i64 %low, %shift
    154   ret i64 %or
    155 }
    156 
    157 ; Like f9, but for larger shifts than 32.
    158 define i64 @f13(i64 %a, i32 %b) {
    159 ; CHECK-LABEL: f13:
    160 ; CHECK: sllg %r2, %r2, 60
    161 ; CHECK: lr %r2, %r3
    162 ; CHECK: br %r14
    163   %shift = shl i64 %a, 60
    164   %low = zext i32 %b to i64
    165   %or = or i64 %shift, %low
    166   ret i64 %or
    167 }
    168 
    169 ; We previously wrongly removed the upper AND as dead.
    170 define i64 @f14(i64 %a, i64 %b) {
    171 ; CHECK-LABEL: f14:
    172 ; CHECK: risbg {{%r[0-5]}}, %r2, 6, 134, 0
    173 ; CHECK: br %r14
    174   %and1 = and i64 %a, 144115188075855872
    175   %and2 = and i64 %b, 15
    176   %or = or i64 %and1, %and2
    177   %res = icmp eq i64 %or, 0
    178   %ext = sext i1 %res to i64
    179   ret i64 %ext
    180 }
    181 
    182 ; Check another representation of f8.
    183 define i64 @f15(i64 %a, i8 *%src) {
    184 ; CHECK-LABEL: f15:
    185 ; CHECK-NOT: {{%r[23]}}
    186 ; CHECK: lb %r2, 0(%r3)
    187 ; CHECK: br %r14
    188   %byte = load i8 , i8 *%src
    189   %b = sext i8 %byte to i64
    190   %low = and i64 %b, 4294967295
    191   %high = and i64 %a, -4294967296
    192   %res = or i64 %high, %low
    193   ret i64 %res
    194 }
    195