Home | History | Annotate | Download | only in SystemZ
      1 ; Test STOCs that are presented as selects.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
      4 
      5 declare void @foo(i32 *)
      6 
      7 ; Test the simple case, with the loaded value first.
      8 define void @f1(i32 *%ptr, i32 %alt, i32 %limit) {
      9 ; CHECK-LABEL: f1:
     10 ; CHECK: clfi %r4, 42
     11 ; CHECK: stoche %r3, 0(%r2)
     12 ; CHECK: br %r14
     13   %cond = icmp ult i32 %limit, 42
     14   %orig = load i32 *%ptr
     15   %res = select i1 %cond, i32 %orig, i32 %alt
     16   store i32 %res, i32 *%ptr
     17   ret void
     18 }
     19 
     20 ; ...and with the loaded value second
     21 define void @f2(i32 *%ptr, i32 %alt, i32 %limit) {
     22 ; CHECK-LABEL: f2:
     23 ; CHECK: clfi %r4, 42
     24 ; CHECK: stocl %r3, 0(%r2)
     25 ; CHECK: br %r14
     26   %cond = icmp ult i32 %limit, 42
     27   %orig = load i32 *%ptr
     28   %res = select i1 %cond, i32 %alt, i32 %orig
     29   store i32 %res, i32 *%ptr
     30   ret void
     31 }
     32 
     33 ; Test cases where the value is explicitly sign-extended to 64 bits, with the
     34 ; loaded value first.
     35 define void @f3(i32 *%ptr, i64 %alt, i32 %limit) {
     36 ; CHECK-LABEL: f3:
     37 ; CHECK: clfi %r4, 42
     38 ; CHECK: stoche %r3, 0(%r2)
     39 ; CHECK: br %r14
     40   %cond = icmp ult i32 %limit, 42
     41   %orig = load i32 *%ptr
     42   %ext = sext i32 %orig to i64
     43   %res = select i1 %cond, i64 %ext, i64 %alt
     44   %trunc = trunc i64 %res to i32
     45   store i32 %trunc, i32 *%ptr
     46   ret void
     47 }
     48 
     49 ; ...and with the loaded value second
     50 define void @f4(i32 *%ptr, i64 %alt, i32 %limit) {
     51 ; CHECK-LABEL: f4:
     52 ; CHECK: clfi %r4, 42
     53 ; CHECK: stocl %r3, 0(%r2)
     54 ; CHECK: br %r14
     55   %cond = icmp ult i32 %limit, 42
     56   %orig = load i32 *%ptr
     57   %ext = sext i32 %orig to i64
     58   %res = select i1 %cond, i64 %alt, i64 %ext
     59   %trunc = trunc i64 %res to i32
     60   store i32 %trunc, i32 *%ptr
     61   ret void
     62 }
     63 
     64 ; Test cases where the value is explicitly zero-extended to 32 bits, with the
     65 ; loaded value first.
     66 define void @f5(i32 *%ptr, i64 %alt, i32 %limit) {
     67 ; CHECK-LABEL: f5:
     68 ; CHECK: clfi %r4, 42
     69 ; CHECK: stoche %r3, 0(%r2)
     70 ; CHECK: br %r14
     71   %cond = icmp ult i32 %limit, 42
     72   %orig = load i32 *%ptr
     73   %ext = zext i32 %orig to i64
     74   %res = select i1 %cond, i64 %ext, i64 %alt
     75   %trunc = trunc i64 %res to i32
     76   store i32 %trunc, i32 *%ptr
     77   ret void
     78 }
     79 
     80 ; ...and with the loaded value second
     81 define void @f6(i32 *%ptr, i64 %alt, i32 %limit) {
     82 ; CHECK-LABEL: f6:
     83 ; CHECK: clfi %r4, 42
     84 ; CHECK: stocl %r3, 0(%r2)
     85 ; CHECK: br %r14
     86   %cond = icmp ult i32 %limit, 42
     87   %orig = load i32 *%ptr
     88   %ext = zext i32 %orig to i64
     89   %res = select i1 %cond, i64 %alt, i64 %ext
     90   %trunc = trunc i64 %res to i32
     91   store i32 %trunc, i32 *%ptr
     92   ret void
     93 }
     94 
     95 ; Check the high end of the aligned STOC range.
     96 define void @f7(i32 *%base, i32 %alt, i32 %limit) {
     97 ; CHECK-LABEL: f7:
     98 ; CHECK: clfi %r4, 42
     99 ; CHECK: stoche %r3, 524284(%r2)
    100 ; CHECK: br %r14
    101   %ptr = getelementptr i32 *%base, i64 131071
    102   %cond = icmp ult i32 %limit, 42
    103   %orig = load i32 *%ptr
    104   %res = select i1 %cond, i32 %orig, i32 %alt
    105   store i32 %res, i32 *%ptr
    106   ret void
    107 }
    108 
    109 ; Check the next word up.  Other sequences besides this one would be OK.
    110 define void @f8(i32 *%base, i32 %alt, i32 %limit) {
    111 ; CHECK-LABEL: f8:
    112 ; CHECK: agfi %r2, 524288
    113 ; CHECK: clfi %r4, 42
    114 ; CHECK: stoche %r3, 0(%r2)
    115 ; CHECK: br %r14
    116   %ptr = getelementptr i32 *%base, i64 131072
    117   %cond = icmp ult i32 %limit, 42
    118   %orig = load i32 *%ptr
    119   %res = select i1 %cond, i32 %orig, i32 %alt
    120   store i32 %res, i32 *%ptr
    121   ret void
    122 }
    123 
    124 ; Check the low end of the STOC range.
    125 define void @f9(i32 *%base, i32 %alt, i32 %limit) {
    126 ; CHECK-LABEL: f9:
    127 ; CHECK: clfi %r4, 42
    128 ; CHECK: stoche %r3, -524288(%r2)
    129 ; CHECK: br %r14
    130   %ptr = getelementptr i32 *%base, i64 -131072
    131   %cond = icmp ult i32 %limit, 42
    132   %orig = load i32 *%ptr
    133   %res = select i1 %cond, i32 %orig, i32 %alt
    134   store i32 %res, i32 *%ptr
    135   ret void
    136 }
    137 
    138 ; Check the next word down, with the same comments as f8.
    139 define void @f10(i32 *%base, i32 %alt, i32 %limit) {
    140 ; CHECK-LABEL: f10:
    141 ; CHECK: agfi %r2, -524292
    142 ; CHECK: clfi %r4, 42
    143 ; CHECK: stoche %r3, 0(%r2)
    144 ; CHECK: br %r14
    145   %ptr = getelementptr i32 *%base, i64 -131073
    146   %cond = icmp ult i32 %limit, 42
    147   %orig = load i32 *%ptr
    148   %res = select i1 %cond, i32 %orig, i32 %alt
    149   store i32 %res, i32 *%ptr
    150   ret void
    151 }
    152 
    153 ; Try a frame index base.
    154 define void @f11(i32 %alt, i32 %limit) {
    155 ; CHECK-LABEL: f11:
    156 ; CHECK: brasl %r14, foo@PLT
    157 ; CHECK: stoche {{%r[0-9]+}}, {{[0-9]+}}(%r15)
    158 ; CHECK: brasl %r14, foo@PLT
    159 ; CHECK: br %r14
    160   %ptr = alloca i32
    161   call void @foo(i32 *%ptr)
    162   %cond = icmp ult i32 %limit, 42
    163   %orig = load i32 *%ptr
    164   %res = select i1 %cond, i32 %orig, i32 %alt
    165   store i32 %res, i32 *%ptr
    166   call void @foo(i32 *%ptr)
    167   ret void
    168 }
    169 
    170 ; Test that conditionally-executed stores do not use STOC, since STOC
    171 ; is allowed to trap even when the condition is false.
    172 define void @f12(i32 %a, i32 %b, i32 *%dest) {
    173 ; CHECK-LABEL: f12:
    174 ; CHECK-NOT: stoc
    175 ; CHECK: br %r14
    176 entry:
    177   %cmp = icmp ule i32 %a, %b
    178   br i1 %cmp, label %store, label %exit
    179 
    180 store:
    181   store i32 %b, i32 *%dest
    182   br label %exit
    183 
    184 exit:
    185   ret void
    186 }
    187