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