Home | History | Annotate | Download | only in SystemZ
      1 ; Test the use of TM and TMY.
      2 ;
      3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
      4 
      5 @g = global i32 0
      6 
      7 ; Check a simple branching use of TM.
      8 define void @f1(i8 *%src) {
      9 ; CHECK-LABEL: f1:
     10 ; CHECK: tm 0(%r2), 1
     11 ; CHECK: je {{\.L.*}}
     12 ; CHECK: br %r14
     13 entry:
     14   %byte = load i8 *%src
     15   %and = and i8 %byte, 1
     16   %cmp = icmp eq i8 %and, 0
     17   br i1 %cmp, label %exit, label %store
     18 
     19 store:
     20   store i32 1, i32 *@g
     21   br label %exit
     22 
     23 exit:
     24   ret void
     25 }
     26 
     27 
     28 ; Check that we do not fold across an aliasing store.
     29 define void @f2(i8 *%src) {
     30 ; CHECK-LABEL: f2:
     31 ; CHECK: llc [[REG:%r[0-5]]], 0(%r2)
     32 ; CHECK: mvi 0(%r2), 0
     33 ; CHECK: tmll [[REG]], 1
     34 ; CHECK: je {{\.L.*}}
     35 ; CHECK: br %r14
     36 entry:
     37   %byte = load i8 *%src
     38   store i8 0, i8 *%src
     39   %and = and i8 %byte, 1
     40   %cmp = icmp eq i8 %and, 0
     41   br i1 %cmp, label %exit, label %store
     42 
     43 store:
     44   store i32 1, i32 *@g
     45   br label %exit
     46 
     47 exit:
     48   ret void
     49 }
     50 
     51 ; Check a simple select-based use of TM.
     52 define double @f3(i8 *%src, double %a, double %b) {
     53 ; CHECK-LABEL: f3:
     54 ; CHECK: tm 0(%r2), 1
     55 ; CHECK: je {{\.L.*}}
     56 ; CHECK: br %r14
     57   %byte = load i8 *%src
     58   %and = and i8 %byte, 1
     59   %cmp = icmp eq i8 %and, 0
     60   %res = select i1 %cmp, double %b, double %a
     61   ret double %res
     62 }
     63 
     64 ; Check that we do not fold across an aliasing store.
     65 define double @f4(i8 *%src, double %a, double %b) {
     66 ; CHECK-LABEL: f4:
     67 ; CHECK: tm 0(%r2), 1
     68 ; CHECK: je {{\.L.*}}
     69 ; CHECK: mvi 0(%r2), 0
     70 ; CHECK: br %r14
     71   %byte = load i8 *%src
     72   %and = and i8 %byte, 1
     73   %cmp = icmp eq i8 %and, 0
     74   %res = select i1 %cmp, double %b, double %a
     75   store i8 0, i8 *%src
     76   ret double %res
     77 }
     78 
     79 ; Check an inequality check.
     80 define double @f5(i8 *%src, double %a, double %b) {
     81 ; CHECK-LABEL: f5:
     82 ; CHECK: tm 0(%r2), 1
     83 ; CHECK: jne {{\.L.*}}
     84 ; CHECK: br %r14
     85   %byte = load i8 *%src
     86   %and = and i8 %byte, 1
     87   %cmp = icmp ne i8 %and, 0
     88   %res = select i1 %cmp, double %b, double %a
     89   ret double %res
     90 }
     91 
     92 ; Check that we can also use TM for equality comparisons with the mask.
     93 define double @f6(i8 *%src, double %a, double %b) {
     94 ; CHECK-LABEL: f6:
     95 ; CHECK: tm 0(%r2), 254
     96 ; CHECK: jo {{\.L.*}}
     97 ; CHECK: br %r14
     98   %byte = load i8 *%src
     99   %and = and i8 %byte, 254
    100   %cmp = icmp eq i8 %and, 254
    101   %res = select i1 %cmp, double %b, double %a
    102   ret double %res
    103 }
    104 
    105 ; Check inequality comparisons with the mask.
    106 define double @f7(i8 *%src, double %a, double %b) {
    107 ; CHECK-LABEL: f7:
    108 ; CHECK: tm 0(%r2), 254
    109 ; CHECK: jno {{\.L.*}}
    110 ; CHECK: br %r14
    111   %byte = load i8 *%src
    112   %and = and i8 %byte, 254
    113   %cmp = icmp ne i8 %and, 254
    114   %res = select i1 %cmp, double %b, double %a
    115   ret double %res
    116 }
    117 
    118 ; Check that we do not use the memory TM instruction when CC is being tested
    119 ; for 2.
    120 define double @f8(i8 *%src, double %a, double %b) {
    121 ; CHECK-LABEL: f8:
    122 ; CHECK: llc [[REG:%r[0-5]]], 0(%r2)
    123 ; CHECK: tmll [[REG]], 3
    124 ; CHECK: jh {{\.L.*}}
    125 ; CHECK: br %r14
    126   %byte = load i8 *%src
    127   %and = and i8 %byte, 3
    128   %cmp = icmp eq i8 %and, 2
    129   %res = select i1 %cmp, double %b, double %a
    130   ret double %res
    131 }
    132 
    133 ; ...likewise 1.
    134 define double @f9(i8 *%src, double %a, double %b) {
    135 ; CHECK-LABEL: f9:
    136 ; CHECK: llc [[REG:%r[0-5]]], 0(%r2)
    137 ; CHECK: tmll [[REG]], 3
    138 ; CHECK: jl {{\.L.*}}
    139 ; CHECK: br %r14
    140   %byte = load i8 *%src
    141   %and = and i8 %byte, 3
    142   %cmp = icmp eq i8 %and, 1
    143   %res = select i1 %cmp, double %b, double %a
    144   ret double %res
    145 }
    146 
    147 ; Check the high end of the TM range.
    148 define double @f10(i8 *%src, double %a, double %b) {
    149 ; CHECK-LABEL: f10:
    150 ; CHECK: tm 4095(%r2), 1
    151 ; CHECK: je {{\.L.*}}
    152 ; CHECK: br %r14
    153   %ptr = getelementptr i8 *%src, i64 4095
    154   %byte = load i8 *%ptr
    155   %and = and i8 %byte, 1
    156   %cmp = icmp eq i8 %and, 0
    157   %res = select i1 %cmp, double %b, double %a
    158   ret double %res
    159 }
    160 
    161 ; Check the low end of the positive TMY range.
    162 define double @f11(i8 *%src, double %a, double %b) {
    163 ; CHECK-LABEL: f11:
    164 ; CHECK: tmy 4096(%r2), 1
    165 ; CHECK: je {{\.L.*}}
    166 ; CHECK: br %r14
    167   %ptr = getelementptr i8 *%src, i64 4096
    168   %byte = load i8 *%ptr
    169   %and = and i8 %byte, 1
    170   %cmp = icmp eq i8 %and, 0
    171   %res = select i1 %cmp, double %b, double %a
    172   ret double %res
    173 }
    174 
    175 ; Check the high end of the TMY range.
    176 define double @f12(i8 *%src, double %a, double %b) {
    177 ; CHECK-LABEL: f12:
    178 ; CHECK: tmy 524287(%r2), 1
    179 ; CHECK: je {{\.L.*}}
    180 ; CHECK: br %r14
    181   %ptr = getelementptr i8 *%src, i64 524287
    182   %byte = load i8 *%ptr
    183   %and = and i8 %byte, 1
    184   %cmp = icmp eq i8 %and, 0
    185   %res = select i1 %cmp, double %b, double %a
    186   ret double %res
    187 }
    188 
    189 ; Check the next byte up, which needs separate address logic.
    190 define double @f13(i8 *%src, double %a, double %b) {
    191 ; CHECK-LABEL: f13:
    192 ; CHECK: agfi %r2, 524288
    193 ; CHECK: tm 0(%r2), 1
    194 ; CHECK: je {{\.L.*}}
    195 ; CHECK: br %r14
    196   %ptr = getelementptr i8 *%src, i64 524288
    197   %byte = load i8 *%ptr
    198   %and = and i8 %byte, 1
    199   %cmp = icmp eq i8 %and, 0
    200   %res = select i1 %cmp, double %b, double %a
    201   ret double %res
    202 }
    203 
    204 ; Check the low end of the TMY range.
    205 define double @f14(i8 *%src, double %a, double %b) {
    206 ; CHECK-LABEL: f14:
    207 ; CHECK: tmy -524288(%r2), 1
    208 ; CHECK: je {{\.L.*}}
    209 ; CHECK: br %r14
    210   %ptr = getelementptr i8 *%src, i64 -524288
    211   %byte = load i8 *%ptr
    212   %and = and i8 %byte, 1
    213   %cmp = icmp eq i8 %and, 0
    214   %res = select i1 %cmp, double %b, double %a
    215   ret double %res
    216 }
    217 
    218 ; Check the next byte down, which needs separate address logic.
    219 define double @f15(i8 *%src, double %a, double %b) {
    220 ; CHECK-LABEL: f15:
    221 ; CHECK: agfi %r2, -524289
    222 ; CHECK: tm 0(%r2), 1
    223 ; CHECK: je {{\.L.*}}
    224 ; CHECK: br %r14
    225   %ptr = getelementptr i8 *%src, i64 -524289
    226   %byte = load i8 *%ptr
    227   %and = and i8 %byte, 1
    228   %cmp = icmp eq i8 %and, 0
    229   %res = select i1 %cmp, double %b, double %a
    230   ret double %res
    231 }
    232 
    233 ; Check that TM(Y) does not allow an index
    234 define double @f16(i8 *%src, i64 %index, double %a, double %b) {
    235 ; CHECK-LABEL: f16:
    236 ; CHECK: tm 0({{%r[1-5]}}), 1
    237 ; CHECK: je {{\.L.*}}
    238 ; CHECK: br %r14
    239   %ptr = getelementptr i8 *%src, i64 %index
    240   %byte = load i8 *%ptr
    241   %and = and i8 %byte, 1
    242   %cmp = icmp eq i8 %and, 0
    243   %res = select i1 %cmp, double %b, double %a
    244   ret double %res
    245 }
    246