Richard Sandiford | 35b9be2 | 2013-08-28 10:31:43 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 11 | ; CHECK: ber %r14 |
Richard Sandiford | 35b9be2 | 2013-08-28 10:31:43 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 30 | ; CHECK: bner %r14 |
Richard Sandiford | 35b9be2 | 2013-08-28 10:31:43 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 49 | ; CHECK: bner %r14 |
Richard Sandiford | 35b9be2 | 2013-08-28 10:31:43 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 86 | ; CHECK: ber %r14 |
Richard Sandiford | 35b9be2 | 2013-08-28 10:31:43 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 106 | ; CHECK: ber %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 125 | ; CHECK: ber %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 145 | ; CHECK: bner %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 164 | ; CHECK: bner %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 184 | ; CHECK: bler %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 203 | ; CHECK: bler %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 223 | ; CHECK: bnler %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 242 | ; CHECK: bnler %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 261 | ; CHECK: bor %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 280 | ; CHECK: bnor %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 300 | ; CHECK: bnor %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 319 | ; CHECK: bnor %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 339 | ; CHECK: bor %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 358 | ; CHECK: bor %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 378 | ; CHECK: blr %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 398 | ; CHECK: bnlr %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 418 | ; CHECK: bhr %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 438 | ; CHECK: bnhr %r14 |
Richard Sandiford | 113c870 | 2013-09-03 15:38:35 +0000 | [diff] [blame] | 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 | } |
Richard Sandiford | 030c165 | 2013-09-13 09:09:50 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 457 | ; CHECK: bner %r14 |
Richard Sandiford | 030c165 | 2013-09-13 09:09:50 +0000 | [diff] [blame] | 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 |
Ulrich Weigand | 2eb027d | 2016-04-07 16:11:44 +0000 | [diff] [blame] | 477 | ; CHECK: bner %r14 |
Richard Sandiford | 030c165 | 2013-09-13 09:09:50 +0000 | [diff] [blame] | 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 | } |