Home | History | Annotate | Download | only in SystemZ
      1 ; Test f32 conditional stores that are presented as selects.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
      4 
      5 declare void @foo(float *)
      6 
      7 ; Test with the loaded value first.
      8 define void @f1(float *%ptr, float %alt, i32 %limit) {
      9 ; CHECK-LABEL: f1:
     10 ; CHECK-NOT: %r2
     11 ; CHECK: blr %r14
     12 ; CHECK-NOT: %r2
     13 ; CHECK: ste %f0, 0(%r2)
     14 ; CHECK: br %r14
     15   %cond = icmp ult i32 %limit, 420
     16   %orig = load float , float *%ptr
     17   %res = select i1 %cond, float %orig, float %alt
     18   store float %res, float *%ptr
     19   ret void
     20 }
     21 
     22 ; ...and with the loaded value second
     23 define void @f2(float *%ptr, float %alt, i32 %limit) {
     24 ; CHECK-LABEL: f2:
     25 ; CHECK-NOT: %r2
     26 ; CHECK: bher %r14
     27 ; CHECK-NOT: %r2
     28 ; CHECK: ste %f0, 0(%r2)
     29 ; CHECK: br %r14
     30   %cond = icmp ult i32 %limit, 420
     31   %orig = load float , float *%ptr
     32   %res = select i1 %cond, float %alt, float %orig
     33   store float %res, float *%ptr
     34   ret void
     35 }
     36 
     37 ; Check the high end of the aligned STE range.
     38 define void @f3(float *%base, float %alt, i32 %limit) {
     39 ; CHECK-LABEL: f3:
     40 ; CHECK-NOT: %r2
     41 ; CHECK: blr %r14
     42 ; CHECK-NOT: %r2
     43 ; CHECK: ste %f0, 4092(%r2)
     44 ; CHECK: br %r14
     45   %ptr = getelementptr float, float *%base, i64 1023
     46   %cond = icmp ult i32 %limit, 420
     47   %orig = load float , float *%ptr
     48   %res = select i1 %cond, float %orig, float %alt
     49   store float %res, float *%ptr
     50   ret void
     51 }
     52 
     53 ; Check the next word up, which should use STEY instead of STE.
     54 define void @f4(float *%base, float %alt, i32 %limit) {
     55 ; CHECK-LABEL: f4:
     56 ; CHECK-NOT: %r2
     57 ; CHECK: blr %r14
     58 ; CHECK-NOT: %r2
     59 ; CHECK: stey %f0, 4096(%r2)
     60 ; CHECK: br %r14
     61   %ptr = getelementptr float, float *%base, i64 1024
     62   %cond = icmp ult i32 %limit, 420
     63   %orig = load float , float *%ptr
     64   %res = select i1 %cond, float %orig, float %alt
     65   store float %res, float *%ptr
     66   ret void
     67 }
     68 
     69 ; Check the high end of the aligned STEY range.
     70 define void @f5(float *%base, float %alt, i32 %limit) {
     71 ; CHECK-LABEL: f5:
     72 ; CHECK-NOT: %r2
     73 ; CHECK: blr %r14
     74 ; CHECK-NOT: %r2
     75 ; CHECK: stey %f0, 524284(%r2)
     76 ; CHECK: br %r14
     77   %ptr = getelementptr float, float *%base, i64 131071
     78   %cond = icmp ult i32 %limit, 420
     79   %orig = load float , float *%ptr
     80   %res = select i1 %cond, float %orig, float %alt
     81   store float %res, float *%ptr
     82   ret void
     83 }
     84 
     85 ; Check the next word up, which needs separate address logic.
     86 ; Other sequences besides this one would be OK.
     87 define void @f6(float *%base, float %alt, i32 %limit) {
     88 ; CHECK-LABEL: f6:
     89 ; CHECK-NOT: %r2
     90 ; CHECK: blr %r14
     91 ; CHECK-NOT: %r2
     92 ; CHECK: agfi %r2, 524288
     93 ; CHECK: ste %f0, 0(%r2)
     94 ; CHECK: br %r14
     95   %ptr = getelementptr float, float *%base, i64 131072
     96   %cond = icmp ult i32 %limit, 420
     97   %orig = load float , float *%ptr
     98   %res = select i1 %cond, float %orig, float %alt
     99   store float %res, float *%ptr
    100   ret void
    101 }
    102 
    103 ; Check the low end of the STEY range.
    104 define void @f7(float *%base, float %alt, i32 %limit) {
    105 ; CHECK-LABEL: f7:
    106 ; CHECK-NOT: %r2
    107 ; CHECK: blr %r14
    108 ; CHECK-NOT: %r2
    109 ; CHECK: stey %f0, -524288(%r2)
    110 ; CHECK: br %r14
    111   %ptr = getelementptr float, float *%base, i64 -131072
    112   %cond = icmp ult i32 %limit, 420
    113   %orig = load float , float *%ptr
    114   %res = select i1 %cond, float %orig, float %alt
    115   store float %res, float *%ptr
    116   ret void
    117 }
    118 
    119 ; Check the next word down, which needs separate address logic.
    120 ; Other sequences besides this one would be OK.
    121 define void @f8(float *%base, float %alt, i32 %limit) {
    122 ; CHECK-LABEL: f8:
    123 ; CHECK-NOT: %r2
    124 ; CHECK: blr %r14
    125 ; CHECK-NOT: %r2
    126 ; CHECK: agfi %r2, -524292
    127 ; CHECK: ste %f0, 0(%r2)
    128 ; CHECK: br %r14
    129   %ptr = getelementptr float, float *%base, i64 -131073
    130   %cond = icmp ult i32 %limit, 420
    131   %orig = load float , float *%ptr
    132   %res = select i1 %cond, float %orig, float %alt
    133   store float %res, float *%ptr
    134   ret void
    135 }
    136 
    137 ; Check that STEY allows an index.
    138 define void @f9(i64 %base, i64 %index, float %alt, i32 %limit) {
    139 ; CHECK-LABEL: f9:
    140 ; CHECK-NOT: %r2
    141 ; CHECK: blr %r14
    142 ; CHECK-NOT: %r2
    143 ; CHECK: stey %f0, 4096(%r3,%r2)
    144 ; CHECK: br %r14
    145   %add1 = add i64 %base, %index
    146   %add2 = add i64 %add1, 4096
    147   %ptr = inttoptr i64 %add2 to float *
    148   %cond = icmp ult i32 %limit, 420
    149   %orig = load float , float *%ptr
    150   %res = select i1 %cond, float %orig, float %alt
    151   store float %res, float *%ptr
    152   ret void
    153 }
    154 
    155 ; Check that volatile loads are not matched.
    156 define void @f10(float *%ptr, float %alt, i32 %limit) {
    157 ; CHECK-LABEL: f10:
    158 ; CHECK: le {{%f[0-5]}}, 0(%r2)
    159 ; CHECK: {{jl|jnl}} [[LABEL:[^ ]*]]
    160 ; CHECK: [[LABEL]]:
    161 ; CHECK: ste {{%f[0-5]}}, 0(%r2)
    162 ; CHECK: br %r14
    163   %cond = icmp ult i32 %limit, 420
    164   %orig = load volatile float , float *%ptr
    165   %res = select i1 %cond, float %orig, float %alt
    166   store float %res, float *%ptr
    167   ret void
    168 }
    169 
    170 ; ...likewise stores.  In this case we should have a conditional load into %f0.
    171 define void @f11(float *%ptr, float %alt, i32 %limit) {
    172 ; CHECK-LABEL: f11:
    173 ; CHECK: jhe [[LABEL:[^ ]*]]
    174 ; CHECK: le %f0, 0(%r2)
    175 ; CHECK: [[LABEL]]:
    176 ; CHECK: ste %f0, 0(%r2)
    177 ; CHECK: br %r14
    178   %cond = icmp ult i32 %limit, 420
    179   %orig = load float , float *%ptr
    180   %res = select i1 %cond, float %orig, float %alt
    181   store volatile float %res, float *%ptr
    182   ret void
    183 }
    184 
    185 ; Try a frame index base.
    186 define void @f12(float %alt, i32 %limit) {
    187 ; CHECK-LABEL: f12:
    188 ; CHECK: brasl %r14, foo@PLT
    189 ; CHECK-NOT: %r15
    190 ; CHECK: jl [[LABEL:[^ ]*]]
    191 ; CHECK-NOT: %r15
    192 ; CHECK: ste {{%f[0-9]+}}, {{[0-9]+}}(%r15)
    193 ; CHECK: [[LABEL]]:
    194 ; CHECK: brasl %r14, foo@PLT
    195 ; CHECK: br %r14
    196   %ptr = alloca float
    197   call void @foo(float *%ptr)
    198   %cond = icmp ult i32 %limit, 420
    199   %orig = load float , float *%ptr
    200   %res = select i1 %cond, float %orig, float %alt
    201   store float %res, float *%ptr
    202   call void @foo(float *%ptr)
    203   ret void
    204 }
    205