1 ; Test the use of TEST UNDER MASK for 64-bit operations. 2 ; 3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z10 | FileCheck %s 4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 5 6 @g = global i32 0 7 8 ; Check the lowest useful TMLL value. 9 define void @f1(i64 %a) { 10 ; CHECK-LABEL: f1: 11 ; CHECK: tmll %r2, 1 12 ; CHECK: je {{\.L.*}} 13 ; CHECK: br %r14 14 entry: 15 %and = and i64 %a, 1 16 %cmp = icmp eq i64 %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 ; Check the high end of the TMLL range. 28 define void @f2(i64 %a) { 29 ; CHECK-LABEL: f2: 30 ; CHECK: tmll %r2, 65535 31 ; CHECK: jne {{\.L.*}} 32 ; CHECK: br %r14 33 entry: 34 %and = and i64 %a, 65535 35 %cmp = icmp ne i64 %and, 0 36 br i1 %cmp, label %exit, label %store 37 38 store: 39 store i32 1, i32 *@g 40 br label %exit 41 42 exit: 43 ret void 44 } 45 46 ; Check the lowest useful TMLH value, which is the next value up. 47 define void @f3(i64 %a) { 48 ; CHECK-LABEL: f3: 49 ; CHECK: tmlh %r2, 1 50 ; CHECK: jne {{\.L.*}} 51 ; CHECK: br %r14 52 entry: 53 %and = and i64 %a, 65536 54 %cmp = icmp ne i64 %and, 0 55 br i1 %cmp, label %exit, label %store 56 57 store: 58 store i32 1, i32 *@g 59 br label %exit 60 61 exit: 62 ret void 63 } 64 65 ; Check the next value up again, which cannot use TM. 66 define void @f4(i64 %a) { 67 ; CHECK-LABEL: f4: 68 ; CHECK-NOT: {{tm[lh].}} 69 ; CHECK: br %r14 70 entry: 71 %and = and i64 %a, 4294901759 72 %cmp = icmp eq i64 %and, 0 73 br i1 %cmp, label %exit, label %store 74 75 store: 76 store i32 1, i32 *@g 77 br label %exit 78 79 exit: 80 ret void 81 } 82 83 ; Check the high end of the TMLH range. 84 define void @f5(i64 %a) { 85 ; CHECK-LABEL: f5: 86 ; CHECK: tmlh %r2, 65535 87 ; CHECK: je {{\.L.*}} 88 ; CHECK: br %r14 89 entry: 90 %and = and i64 %a, 4294901760 91 %cmp = icmp eq i64 %and, 0 92 br i1 %cmp, label %exit, label %store 93 94 store: 95 store i32 1, i32 *@g 96 br label %exit 97 98 exit: 99 ret void 100 } 101 102 ; Check the lowest useful TMHL value. 103 define void @f6(i64 %a) { 104 ; CHECK-LABEL: f6: 105 ; CHECK: tmhl %r2, 1 106 ; CHECK: je {{\.L.*}} 107 ; CHECK: br %r14 108 entry: 109 %and = and i64 %a, 4294967296 110 %cmp = icmp eq i64 %and, 0 111 br i1 %cmp, label %exit, label %store 112 113 store: 114 store i32 1, i32 *@g 115 br label %exit 116 117 exit: 118 ret void 119 } 120 121 ; Check the next value up again, which cannot use TM. 122 define void @f7(i64 %a) { 123 ; CHECK-LABEL: f7: 124 ; CHECK-NOT: {{tm[lh].}} 125 ; CHECK: br %r14 126 entry: 127 %and = and i64 %a, 4294967297 128 %cmp = icmp ne i64 %and, 0 129 br i1 %cmp, label %exit, label %store 130 131 store: 132 store i32 1, i32 *@g 133 br label %exit 134 135 exit: 136 ret void 137 } 138 139 ; Check the high end of the TMHL range. 140 define void @f8(i64 %a) { 141 ; CHECK-LABEL: f8: 142 ; CHECK: tmhl %r2, 65535 143 ; CHECK: jne {{\.L.*}} 144 ; CHECK: br %r14 145 entry: 146 %and = and i64 %a, 281470681743360 147 %cmp = icmp ne i64 %and, 0 148 br i1 %cmp, label %exit, label %store 149 150 store: 151 store i32 1, i32 *@g 152 br label %exit 153 154 exit: 155 ret void 156 } 157 158 ; Check the lowest useful TMHH value. 159 define void @f9(i64 %a) { 160 ; CHECK-LABEL: f9: 161 ; CHECK: tmhh %r2, 1 162 ; CHECK: jne {{\.L.*}} 163 ; CHECK: br %r14 164 entry: 165 %and = and i64 %a, 281474976710656 166 %cmp = icmp ne i64 %and, 0 167 br i1 %cmp, label %exit, label %store 168 169 store: 170 store i32 1, i32 *@g 171 br label %exit 172 173 exit: 174 ret void 175 } 176 177 ; Check the high end of the TMHH range. 178 define void @f10(i64 %a) { 179 ; CHECK-LABEL: f10: 180 ; CHECK: tmhh %r2, 65535 181 ; CHECK: je {{\.L.*}} 182 ; CHECK: br %r14 183 entry: 184 %and = and i64 %a, 18446462598732840960 185 %cmp = icmp eq i64 %and, 0 186 br i1 %cmp, label %exit, label %store 187 188 store: 189 store i32 1, i32 *@g 190 br label %exit 191 192 exit: 193 ret void 194 } 195 196 ; Check that we can fold an SHL into a TMxx mask. 197 define void @f11(i64 %a) { 198 ; CHECK-LABEL: f11: 199 ; CHECK: tmhl %r2, 32768 200 ; CHECK: jne {{\.L.*}} 201 ; CHECK: br %r14 202 entry: 203 %shl = shl i64 %a, 1 204 %and = and i64 %shl, 281474976710656 205 %cmp = icmp ne i64 %and, 0 206 br i1 %cmp, label %exit, label %store 207 208 store: 209 store i32 1, i32 *@g 210 br label %exit 211 212 exit: 213 ret void 214 } 215 216 ; Check that we can fold an SHR into a TMxx mask. 217 define void @f12(i64 %a) { 218 ; CHECK-LABEL: f12: 219 ; CHECK: tmhh %r2, 256 220 ; CHECK: jne {{\.L.*}} 221 ; CHECK: br %r14 222 entry: 223 %shr = lshr i64 %a, 56 224 %and = and i64 %shr, 1 225 %cmp = icmp ne i64 %and, 0 226 br i1 %cmp, label %exit, label %store 227 228 store: 229 store i32 1, i32 *@g 230 br label %exit 231 232 exit: 233 ret void 234 } 235 236 ; Check a case where TMHH can be used to implement a ult comparison. 237 define void @f13(i64 %a) { 238 ; CHECK-LABEL: f13: 239 ; CHECK: tmhh %r2, 49152 240 ; CHECK: jno {{\.L.*}} 241 ; CHECK: br %r14 242 entry: 243 %cmp = icmp ult i64 %a, 13835058055282163712 244 br i1 %cmp, label %exit, label %store 245 246 store: 247 store i32 1, i32 *@g 248 br label %exit 249 250 exit: 251 ret void 252 } 253 254 ; And again with ule. 255 define void @f14(i64 %a) { 256 ; CHECK-LABEL: f14: 257 ; CHECK: tmhh %r2, 49152 258 ; CHECK: jno {{\.L.*}} 259 ; CHECK: br %r14 260 entry: 261 %cmp = icmp ule i64 %a, 13835058055282163711 262 br i1 %cmp, label %exit, label %store 263 264 store: 265 store i32 1, i32 *@g 266 br label %exit 267 268 exit: 269 ret void 270 } 271 272 ; And again with ugt. 273 define void @f15(i64 %a) { 274 ; CHECK-LABEL: f15: 275 ; CHECK: tmhh %r2, 49152 276 ; CHECK: jo {{\.L.*}} 277 ; CHECK: br %r14 278 entry: 279 %cmp = icmp ugt i64 %a, 13835058055282163711 280 br i1 %cmp, label %exit, label %store 281 282 store: 283 store i32 1, i32 *@g 284 br label %exit 285 286 exit: 287 ret void 288 } 289 290 ; And again with uge. 291 define void @f16(i64 %a) { 292 ; CHECK-LABEL: f16: 293 ; CHECK: tmhh %r2, 49152 294 ; CHECK: jo {{\.L.*}} 295 ; CHECK: br %r14 296 entry: 297 %cmp = icmp uge i64 %a, 13835058055282163712 298 br i1 %cmp, label %exit, label %store 299 300 store: 301 store i32 1, i32 *@g 302 br label %exit 303 304 exit: 305 ret void 306 } 307 308 ; Decrease the constant from f13 to make TMHH invalid. 309 define void @f17(i64 %a) { 310 ; CHECK-LABEL: f17: 311 ; CHECK-NOT: tmhh 312 ; CHECK: llihh {{%r[0-5]}}, 49151 313 ; CHECK-NOT: tmhh 314 ; CHECK: br %r14 315 entry: 316 %cmp = icmp ult i64 %a, 13834776580305453056 317 br i1 %cmp, label %exit, label %store 318 319 store: 320 store i32 1, i32 *@g 321 br label %exit 322 323 exit: 324 ret void 325 } 326 327 ; Check that we don't use TMHH just to test the top bit. 328 define void @f18(i64 %a) { 329 ; CHECK-LABEL: f18: 330 ; CHECK-NOT: tmhh 331 ; CHECK: cgijhe %r2, 0, 332 ; CHECK: br %r14 333 entry: 334 %cmp = icmp ult i64 %a, 9223372036854775808 335 br i1 %cmp, label %exit, label %store 336 337 store: 338 store i32 1, i32 *@g 339 br label %exit 340 341 exit: 342 ret void 343 } 344