1 ; Test the use of TEST UNDER MASK for 32-bit operations. 2 ; 3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s 4 5 @g = global i32 0 6 7 ; Check the lowest useful TMLL value. 8 define void @f1(i32 %a) { 9 ; CHECK-LABEL: f1: 10 ; CHECK: tmll %r2, 1 11 ; CHECK: je {{\.L.*}} 12 ; CHECK: br %r14 13 entry: 14 %and = and i32 %a, 1 15 %cmp = icmp eq i32 %and, 0 16 br i1 %cmp, label %exit, label %store 17 18 store: 19 store i32 1, i32 *@g 20 br label %exit 21 22 exit: 23 ret void 24 } 25 26 ; Check the high end of the TMLL range. 27 define void @f2(i32 %a) { 28 ; CHECK-LABEL: f2: 29 ; CHECK: tmll %r2, 65535 30 ; CHECK: jne {{\.L.*}} 31 ; CHECK: br %r14 32 entry: 33 %and = and i32 %a, 65535 34 %cmp = icmp ne i32 %and, 0 35 br i1 %cmp, label %exit, label %store 36 37 store: 38 store i32 1, i32 *@g 39 br label %exit 40 41 exit: 42 ret void 43 } 44 45 ; Check the lowest useful TMLH value, which is the next value up. 46 define void @f3(i32 %a) { 47 ; CHECK-LABEL: f3: 48 ; CHECK: tmlh %r2, 1 49 ; CHECK: jne {{\.L.*}} 50 ; CHECK: br %r14 51 entry: 52 %and = and i32 %a, 65536 53 %cmp = icmp ne i32 %and, 0 54 br i1 %cmp, label %exit, label %store 55 56 store: 57 store i32 1, i32 *@g 58 br label %exit 59 60 exit: 61 ret void 62 } 63 64 ; Check the next value up again, which cannot use TM. 65 define void @f4(i32 %a) { 66 ; CHECK-LABEL: f4: 67 ; CHECK-NOT: {{tm[lh].}} 68 ; CHECK: br %r14 69 entry: 70 %and = and i32 %a, 4294901759 71 %cmp = icmp eq i32 %and, 0 72 br i1 %cmp, label %exit, label %store 73 74 store: 75 store i32 1, i32 *@g 76 br label %exit 77 78 exit: 79 ret void 80 } 81 82 ; Check the high end of the TMLH range. 83 define void @f5(i32 %a) { 84 ; CHECK-LABEL: f5: 85 ; CHECK: tmlh %r2, 65535 86 ; CHECK: je {{\.L.*}} 87 ; CHECK: br %r14 88 entry: 89 %and = and i32 %a, 4294901760 90 %cmp = icmp eq i32 %and, 0 91 br i1 %cmp, label %exit, label %store 92 93 store: 94 store i32 1, i32 *@g 95 br label %exit 96 97 exit: 98 ret void 99 } 100 101 ; Check that we can use TMLL for LT comparisons that are equivalent to 102 ; an equality comparison with zero. 103 define void @f6(i32 %a) { 104 ; CHECK-LABEL: f6: 105 ; CHECK: tmll %r2, 240 106 ; CHECK: je {{\.L.*}} 107 ; CHECK: br %r14 108 entry: 109 %and = and i32 %a, 240 110 %cmp = icmp slt i32 %and, 16 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 ; ...same again with LE. 122 define void @f7(i32 %a) { 123 ; CHECK-LABEL: f7: 124 ; CHECK: tmll %r2, 240 125 ; CHECK: je {{\.L.*}} 126 ; CHECK: br %r14 127 entry: 128 %and = and i32 %a, 240 129 %cmp = icmp sle i32 %and, 15 130 br i1 %cmp, label %exit, label %store 131 132 store: 133 store i32 1, i32 *@g 134 br label %exit 135 136 exit: 137 ret void 138 } 139 140 ; Check that we can use TMLL for GE comparisons that are equivalent to 141 ; an inequality comparison with zero. 142 define void @f8(i32 %a) { 143 ; CHECK-LABEL: f8: 144 ; CHECK: tmll %r2, 240 145 ; CHECK: jne {{\.L.*}} 146 ; CHECK: br %r14 147 entry: 148 %and = and i32 %a, 240 149 %cmp = icmp uge i32 %and, 16 150 br i1 %cmp, label %exit, label %store 151 152 store: 153 store i32 1, i32 *@g 154 br label %exit 155 156 exit: 157 ret void 158 } 159 160 ; ...same again with GT. 161 define void @f9(i32 %a) { 162 ; CHECK-LABEL: f9: 163 ; CHECK: tmll %r2, 240 164 ; CHECK: jne {{\.L.*}} 165 ; CHECK: br %r14 166 entry: 167 %and = and i32 %a, 240 168 %cmp = icmp ugt i32 %and, 15 169 br i1 %cmp, label %exit, label %store 170 171 store: 172 store i32 1, i32 *@g 173 br label %exit 174 175 exit: 176 ret void 177 } 178 179 ; Check that we can use TMLL for LT comparisons that effectively 180 ; test whether the top bit is clear. 181 define void @f10(i32 %a) { 182 ; CHECK-LABEL: f10: 183 ; CHECK: tmll %r2, 35 184 ; CHECK: jle {{\.L.*}} 185 ; CHECK: br %r14 186 entry: 187 %and = and i32 %a, 35 188 %cmp = icmp ult i32 %and, 8 189 br i1 %cmp, label %exit, label %store 190 191 store: 192 store i32 1, i32 *@g 193 br label %exit 194 195 exit: 196 ret void 197 } 198 199 ; ...same again with LE. 200 define void @f11(i32 %a) { 201 ; CHECK-LABEL: f11: 202 ; CHECK: tmll %r2, 35 203 ; CHECK: jle {{\.L.*}} 204 ; CHECK: br %r14 205 entry: 206 %and = and i32 %a, 35 207 %cmp = icmp ule i32 %and, 31 208 br i1 %cmp, label %exit, label %store 209 210 store: 211 store i32 1, i32 *@g 212 br label %exit 213 214 exit: 215 ret void 216 } 217 218 ; Check that we can use TMLL for GE comparisons that effectively test 219 ; whether the top bit is set. 220 define void @f12(i32 %a) { 221 ; CHECK-LABEL: f12: 222 ; CHECK: tmll %r2, 140 223 ; CHECK: jnle {{\.L.*}} 224 ; CHECK: br %r14 225 entry: 226 %and = and i32 %a, 140 227 %cmp = icmp uge i32 %and, 128 228 br i1 %cmp, label %exit, label %store 229 230 store: 231 store i32 1, i32 *@g 232 br label %exit 233 234 exit: 235 ret void 236 } 237 238 ; ...same again for GT. 239 define void @f13(i32 %a) { 240 ; CHECK-LABEL: f13: 241 ; CHECK: tmll %r2, 140 242 ; CHECK: jnle {{\.L.*}} 243 ; CHECK: br %r14 244 entry: 245 %and = and i32 %a, 140 246 %cmp = icmp ugt i32 %and, 126 247 br i1 %cmp, label %exit, label %store 248 249 store: 250 store i32 1, i32 *@g 251 br label %exit 252 253 exit: 254 ret void 255 } 256 257 ; Check that we can use TMLL for equality comparisons with the mask. 258 define void @f14(i32 %a) { 259 ; CHECK-LABEL: f14: 260 ; CHECK: tmll %r2, 101 261 ; CHECK: jo {{\.L.*}} 262 ; CHECK: br %r14 263 entry: 264 %and = and i32 %a, 101 265 %cmp = icmp eq i32 %and, 101 266 br i1 %cmp, label %exit, label %store 267 268 store: 269 store i32 1, i32 *@g 270 br label %exit 271 272 exit: 273 ret void 274 } 275 276 ; Check that we can use TMLL for inequality comparisons with the mask. 277 define void @f15(i32 %a) { 278 ; CHECK-LABEL: f15: 279 ; CHECK: tmll %r2, 65519 280 ; CHECK: jno {{\.L.*}} 281 ; CHECK: br %r14 282 entry: 283 %and = and i32 %a, 65519 284 %cmp = icmp ne i32 %and, 65519 285 br i1 %cmp, label %exit, label %store 286 287 store: 288 store i32 1, i32 *@g 289 br label %exit 290 291 exit: 292 ret void 293 } 294 295 ; Check that we can use TMLL for LT comparisons that are equivalent 296 ; to inequality comparisons with the mask. 297 define void @f16(i32 %a) { 298 ; CHECK-LABEL: f16: 299 ; CHECK: tmll %r2, 130 300 ; CHECK: jno {{\.L.*}} 301 ; CHECK: br %r14 302 entry: 303 %and = and i32 %a, 130 304 %cmp = icmp ult i32 %and, 129 305 br i1 %cmp, label %exit, label %store 306 307 store: 308 store i32 1, i32 *@g 309 br label %exit 310 311 exit: 312 ret void 313 } 314 315 ; ...same again with LE. 316 define void @f17(i32 %a) { 317 ; CHECK-LABEL: f17: 318 ; CHECK: tmll %r2, 130 319 ; CHECK: jno {{\.L.*}} 320 ; CHECK: br %r14 321 entry: 322 %and = and i32 %a, 130 323 %cmp = icmp ule i32 %and, 128 324 br i1 %cmp, label %exit, label %store 325 326 store: 327 store i32 1, i32 *@g 328 br label %exit 329 330 exit: 331 ret void 332 } 333 334 ; Check that we can use TMLL for GE comparisons that are equivalent 335 ; to equality comparisons with the mask. 336 define void @f18(i32 %a) { 337 ; CHECK-LABEL: f18: 338 ; CHECK: tmll %r2, 194 339 ; CHECK: jo {{\.L.*}} 340 ; CHECK: br %r14 341 entry: 342 %and = and i32 %a, 194 343 %cmp = icmp uge i32 %and, 193 344 br i1 %cmp, label %exit, label %store 345 346 store: 347 store i32 1, i32 *@g 348 br label %exit 349 350 exit: 351 ret void 352 } 353 354 ; ...same again for GT. 355 define void @f19(i32 %a) { 356 ; CHECK-LABEL: f19: 357 ; CHECK: tmll %r2, 194 358 ; CHECK: jo {{\.L.*}} 359 ; CHECK: br %r14 360 entry: 361 %and = and i32 %a, 194 362 %cmp = icmp ugt i32 %and, 192 363 br i1 %cmp, label %exit, label %store 364 365 store: 366 store i32 1, i32 *@g 367 br label %exit 368 369 exit: 370 ret void 371 } 372 373 ; Check that we can use TMLL for equality comparisons for the low bit 374 ; when the mask has two bits. 375 define void @f20(i32 %a) { 376 ; CHECK-LABEL: f20: 377 ; CHECK: tmll %r2, 20 378 ; CHECK: jl {{\.L.*}} 379 ; CHECK: br %r14 380 entry: 381 %and = and i32 %a, 20 382 %cmp = icmp eq i32 %and, 4 383 br i1 %cmp, label %exit, label %store 384 385 store: 386 store i32 1, i32 *@g 387 br label %exit 388 389 exit: 390 ret void 391 } 392 393 ; Check that we can use TMLL for inequality comparisons for the low bit 394 ; when the mask has two bits. 395 define void @f21(i32 %a) { 396 ; CHECK-LABEL: f21: 397 ; CHECK: tmll %r2, 20 398 ; CHECK: jnl {{\.L.*}} 399 ; CHECK: br %r14 400 entry: 401 %and = and i32 %a, 20 402 %cmp = icmp ne i32 %and, 4 403 br i1 %cmp, label %exit, label %store 404 405 store: 406 store i32 1, i32 *@g 407 br label %exit 408 409 exit: 410 ret void 411 } 412 413 ; Check that we can use TMLL for equality comparisons for the high bit 414 ; when the mask has two bits. 415 define void @f22(i32 %a) { 416 ; CHECK-LABEL: f22: 417 ; CHECK: tmll %r2, 20 418 ; CHECK: jh {{\.L.*}} 419 ; CHECK: br %r14 420 entry: 421 %and = and i32 %a, 20 422 %cmp = icmp eq i32 %and, 16 423 br i1 %cmp, label %exit, label %store 424 425 store: 426 store i32 1, i32 *@g 427 br label %exit 428 429 exit: 430 ret void 431 } 432 433 ; Check that we can use TMLL for inequality comparisons for the high bit 434 ; when the mask has two bits. 435 define void @f23(i32 %a) { 436 ; CHECK-LABEL: f23: 437 ; CHECK: tmll %r2, 20 438 ; CHECK: jnh {{\.L.*}} 439 ; CHECK: br %r14 440 entry: 441 %and = and i32 %a, 20 442 %cmp = icmp ne i32 %and, 16 443 br i1 %cmp, label %exit, label %store 444 445 store: 446 store i32 1, i32 *@g 447 br label %exit 448 449 exit: 450 ret void 451 } 452 453 ; Check that we can fold an SHL into a TMxx mask. 454 define void @f24(i32 %a) { 455 ; CHECK-LABEL: f24: 456 ; CHECK: tmll %r2, 255 457 ; CHECK: jne {{\.L.*}} 458 ; CHECK: br %r14 459 entry: 460 %shl = shl i32 %a, 12 461 %and = and i32 %shl, 1044480 462 %cmp = icmp ne i32 %and, 0 463 br i1 %cmp, label %exit, label %store 464 465 store: 466 store i32 1, i32 *@g 467 br label %exit 468 469 exit: 470 ret void 471 } 472 473 ; Check that we can fold an SHR into a TMxx mask. 474 define void @f25(i32 %a) { 475 ; CHECK-LABEL: f25: 476 ; CHECK: tmlh %r2, 512 477 ; CHECK: jne {{\.L.*}} 478 ; CHECK: br %r14 479 entry: 480 %shr = lshr i32 %a, 25 481 %and = and i32 %shr, 1 482 %cmp = icmp ne i32 %and, 0 483 br i1 %cmp, label %exit, label %store 484 485 store: 486 store i32 1, i32 *@g 487 br label %exit 488 489 exit: 490 ret void 491 } 492