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 , 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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 , 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, i8 *%src, i64 4095 154 %byte = load i8 , 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, i8 *%src, i64 4096 168 %byte = load i8 , 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, i8 *%src, i64 524287 182 %byte = load i8 , 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, i8 *%src, i64 524288 197 %byte = load i8 , 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, i8 *%src, i64 -524288 211 %byte = load i8 , 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, i8 *%src, i64 -524289 226 %byte = load i8 , 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, i8 *%src, i64 %index 240 %byte = load i8 , 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