1# RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve -run-pass=peephole-opt -verify-machineinstrs %s -o - | FileCheck %s 2 3# Test instruction sequences where PTEST is redundant and thus gets removed. 4--- 5name: whilels_b8_s32 6alignment: 2 7tracksRegLiveness: true 8registers: 9 - { id: 0, class: gpr32 } 10 - { id: 1, class: gpr32 } 11 - { id: 2, class: ppr } 12 - { id: 3, class: ppr } 13 - { id: 4, class: gpr32 } 14 - { id: 5, class: gpr32 } 15liveins: 16 - { reg: '$w0', virtual-reg: '%0' } 17 - { reg: '$w1', virtual-reg: '%1' } 18frameInfo: 19 maxCallFrameSize: 0 20body: | 21 bb.0.entry: 22 liveins: $w0, $w1 23 24 ; Here we check the expected sequence with subsequent tests 25 ; just asserting there is no PTEST instruction. 26 ; 27 ; CHECK-LABEL: name: whilels_b8_s32 28 ; CHECK: %3:ppr = WHILELS_PWW_B %0, %1, implicit-def $nzcv 29 ; CHECK-NEXT: %4:gpr32 = COPY $wzr 30 ; CHECK-NEXT: %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 31 %1:gpr32 = COPY $w1 32 %0:gpr32 = COPY $w0 33 %2:ppr = PTRUE_B 31, implicit $vg 34 %3:ppr = WHILELS_PWW_B %0, %1, implicit-def dead $nzcv 35 PTEST_PP killed %2, killed %3, implicit-def $nzcv 36 %4:gpr32 = COPY $wzr 37 %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 38 $w0 = COPY %5 39 RET_ReallyLR implicit $w0 40 41... 42--- 43name: whilels_b8_s64 44alignment: 2 45tracksRegLiveness: true 46registers: 47 - { id: 0, class: gpr64 } 48 - { id: 1, class: gpr64 } 49 - { id: 2, class: ppr } 50 - { id: 3, class: ppr } 51 - { id: 4, class: gpr32 } 52 - { id: 5, class: gpr32 } 53liveins: 54 - { reg: '$x0', virtual-reg: '%0' } 55 - { reg: '$x1', virtual-reg: '%1' } 56frameInfo: 57 maxCallFrameSize: 0 58body: | 59 bb.0.entry: 60 liveins: $x0, $x1 61 62 ; CHECK-LABEL: name: whilels_b8_s64 63 ; CHECK-NOT: PTEST 64 %1:gpr64 = COPY $x1 65 %0:gpr64 = COPY $x0 66 %2:ppr = PTRUE_B 31, implicit $vg 67 %3:ppr = WHILELS_PXX_B %0, %1, implicit-def dead $nzcv 68 PTEST_PP killed %2, killed %3, implicit-def $nzcv 69 %4:gpr32 = COPY $wzr 70 %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 71 $w0 = COPY %5 72 RET_ReallyLR implicit $w0 73 74... 75--- 76name: whilels_b16_s32 77alignment: 2 78tracksRegLiveness: true 79registers: 80 - { id: 0, class: gpr32 } 81 - { id: 1, class: gpr32 } 82 - { id: 2, class: ppr } 83 - { id: 3, class: ppr } 84 - { id: 4, class: ppr } 85 - { id: 5, class: ppr } 86 - { id: 6, class: gpr32 } 87 - { id: 7, class: gpr32 } 88liveins: 89 - { reg: '$w0', virtual-reg: '%0' } 90 - { reg: '$w1', virtual-reg: '%1' } 91frameInfo: 92 maxCallFrameSize: 0 93body: | 94 bb.0.entry: 95 liveins: $w0, $w1 96 97 ; CHECK-LABEL: name: whilels_b16_s32 98 ; CHECK-NOT: PTEST 99 %1:gpr32 = COPY $w1 100 %0:gpr32 = COPY $w0 101 %2:ppr = PTRUE_H 31, implicit $vg 102 %4:ppr = WHILELS_PWW_H %0, %1, implicit-def dead $nzcv 103 PTEST_PP %2, %4, implicit-def $nzcv 104 %6:gpr32 = COPY $wzr 105 %7:gpr32 = CSINCWr %6, $wzr, 0, implicit $nzcv 106 $w0 = COPY %7 107 RET_ReallyLR implicit $w0 108 109... 110--- 111name: whilels_b16_s64 112alignment: 2 113tracksRegLiveness: true 114registers: 115 - { id: 0, class: gpr64 } 116 - { id: 1, class: gpr64 } 117 - { id: 2, class: ppr } 118 - { id: 3, class: ppr } 119 - { id: 4, class: ppr } 120 - { id: 5, class: ppr } 121 - { id: 6, class: gpr32 } 122 - { id: 7, class: gpr32 } 123liveins: 124 - { reg: '$x0', virtual-reg: '%0' } 125 - { reg: '$x1', virtual-reg: '%1' } 126frameInfo: 127 maxCallFrameSize: 0 128body: | 129 bb.0.entry: 130 liveins: $x0, $x1 131 132 ; CHECK-LABEL: name: whilels_b16_s64 133 ; CHECK-NOT: PTEST 134 %1:gpr64 = COPY $x1 135 %0:gpr64 = COPY $x0 136 %2:ppr = PTRUE_H 31, implicit $vg 137 %4:ppr = WHILELS_PXX_H %0, %1, implicit-def dead $nzcv 138 PTEST_PP %2, %4, implicit-def $nzcv 139 %6:gpr32 = COPY $wzr 140 %7:gpr32 = CSINCWr %6, $wzr, 0, implicit $nzcv 141 $w0 = COPY %7 142 RET_ReallyLR implicit $w0 143 144... 145--- 146name: whilels_b32_s32 147alignment: 2 148tracksRegLiveness: true 149registers: 150 - { id: 0, class: gpr32 } 151 - { id: 1, class: gpr32 } 152 - { id: 2, class: ppr } 153 - { id: 3, class: ppr } 154 - { id: 4, class: ppr } 155 - { id: 5, class: ppr } 156 - { id: 6, class: gpr32 } 157 - { id: 7, class: gpr32 } 158liveins: 159 - { reg: '$w0', virtual-reg: '%0' } 160 - { reg: '$w1', virtual-reg: '%1' } 161frameInfo: 162 maxCallFrameSize: 0 163body: | 164 bb.0.entry: 165 liveins: $w0, $w1 166 167 ; CHECK-LABEL: name: whilels_b32_s32 168 ; CHECK-NOT: PTEST 169 %1:gpr32 = COPY $w1 170 %0:gpr32 = COPY $w0 171 %2:ppr = PTRUE_S 31, implicit $vg 172 %4:ppr = WHILELS_PWW_S %0, %1, implicit-def dead $nzcv 173 PTEST_PP %2, %4, implicit-def $nzcv 174 %6:gpr32 = COPY $wzr 175 %7:gpr32 = CSINCWr %6, $wzr, 0, implicit $nzcv 176 $w0 = COPY %7 177 RET_ReallyLR implicit $w0 178 179... 180--- 181name: whilels_b32_s64 182alignment: 2 183tracksRegLiveness: true 184registers: 185 - { id: 0, class: gpr64 } 186 - { id: 1, class: gpr64 } 187 - { id: 2, class: ppr } 188 - { id: 3, class: ppr } 189 - { id: 4, class: ppr } 190 - { id: 5, class: ppr } 191 - { id: 6, class: gpr32 } 192 - { id: 7, class: gpr32 } 193liveins: 194 - { reg: '$x0', virtual-reg: '%0' } 195 - { reg: '$x1', virtual-reg: '%1' } 196frameInfo: 197 maxCallFrameSize: 0 198body: | 199 bb.0.entry: 200 liveins: $x0, $x1 201 202 ; CHECK-LABEL: name: whilels_b32_s64 203 ; CHECK-NOT: PTEST 204 %1:gpr64 = COPY $x1 205 %0:gpr64 = COPY $x0 206 %2:ppr = PTRUE_S 31, implicit $vg 207 %4:ppr = WHILELS_PXX_S %0, %1, implicit-def dead $nzcv 208 PTEST_PP %2, %4, implicit-def $nzcv 209 %6:gpr32 = COPY $wzr 210 %7:gpr32 = CSINCWr %6, $wzr, 0, implicit $nzcv 211 $w0 = COPY %7 212 RET_ReallyLR implicit $w0 213 214... 215--- 216name: whilels_b64_s32 217alignment: 2 218tracksRegLiveness: true 219registers: 220 - { id: 0, class: gpr32 } 221 - { id: 1, class: gpr32 } 222 - { id: 2, class: ppr } 223 - { id: 3, class: ppr } 224 - { id: 4, class: ppr } 225 - { id: 5, class: ppr } 226 - { id: 6, class: gpr32 } 227 - { id: 7, class: gpr32 } 228liveins: 229 - { reg: '$w0', virtual-reg: '%0' } 230 - { reg: '$w1', virtual-reg: '%1' } 231frameInfo: 232 maxCallFrameSize: 0 233body: | 234 bb.0.entry: 235 liveins: $w0, $w1 236 237 ; CHECK-LABEL: name: whilels_b64_s32 238 ; CHECK-NOT: PTEST 239 %1:gpr32 = COPY $w1 240 %0:gpr32 = COPY $w0 241 %2:ppr = PTRUE_D 31, implicit $vg 242 %4:ppr = WHILELS_PWW_D %0, %1, implicit-def dead $nzcv 243 PTEST_PP %2, %4, implicit-def $nzcv 244 %6:gpr32 = COPY $wzr 245 %7:gpr32 = CSINCWr %6, $wzr, 0, implicit $nzcv 246 $w0 = COPY %7 247 RET_ReallyLR implicit $w0 248 249... 250--- 251name: whilels_b64_s64 252alignment: 2 253tracksRegLiveness: true 254registers: 255 - { id: 0, class: gpr64 } 256 - { id: 1, class: gpr64 } 257 - { id: 2, class: ppr } 258 - { id: 3, class: ppr } 259 - { id: 4, class: ppr } 260 - { id: 5, class: ppr } 261 - { id: 6, class: gpr32 } 262 - { id: 7, class: gpr32 } 263liveins: 264 - { reg: '$x0', virtual-reg: '%0' } 265 - { reg: '$x1', virtual-reg: '%1' } 266frameInfo: 267 maxCallFrameSize: 0 268body: | 269 bb.0.entry: 270 liveins: $x0, $x1 271 272 ; CHECK-LABEL: name: whilels_b64_s64 273 ; CHECK-NOT: PTEST 274 %1:gpr64 = COPY $x1 275 %0:gpr64 = COPY $x0 276 %2:ppr = PTRUE_D 31, implicit $vg 277 %4:ppr = WHILELS_PXX_D %0, %1, implicit-def dead $nzcv 278 PTEST_PP %2, %4, implicit-def $nzcv 279 %6:gpr32 = COPY $wzr 280 %7:gpr32 = CSINCWr %6, $wzr, 0, implicit $nzcv 281 $w0 = COPY %7 282 RET_ReallyLR implicit $w0 283 284... 285--- 286name: whilels_b32_s32_keep_ptest_not_all_active 287alignment: 2 288tracksRegLiveness: true 289registers: 290 - { id: 0, class: gpr32 } 291 - { id: 1, class: gpr32 } 292 - { id: 2, class: ppr } 293 - { id: 3, class: ppr } 294 - { id: 4, class: gpr32 } 295 - { id: 5, class: gpr32 } 296liveins: 297 - { reg: '$w0', virtual-reg: '%0' } 298 - { reg: '$w1', virtual-reg: '%1' } 299frameInfo: 300 maxCallFrameSize: 0 301body: | 302 bb.0.entry: 303 liveins: $w0, $w1 304 305 ; PTEST is not redundant when it's Pg operand is not an all active predicate 306 ; of element size matching the WHILELS, which is the implicitly predicate 307 ; used by WHILE when calculating the condition codes. 308 ; 309 ; CHECK-LABEL: name: whilels_b32_s32_keep_ptest_not_all_active 310 ; CHECK: %3:ppr = WHILELS_PWW_S %0, %1, implicit-def dead $nzcv 311 ; CHECK-NEXT: PTEST_PP killed %2, killed %3, implicit-def $nzcv 312 ; CHECK-NEXT: %4:gpr32 = COPY $wzr 313 ; CHECK-NEXT: %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 314 %1:gpr32 = COPY $w1 315 %0:gpr32 = COPY $w0 316 %2:ppr = PTRUE_S 5, implicit $vg 317 %3:ppr = WHILELS_PWW_S %0, %1, implicit-def dead $nzcv 318 PTEST_PP killed %2, killed %3, implicit-def $nzcv 319 %4:gpr32 = COPY $wzr 320 %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 321 $w0 = COPY %5 322 RET_ReallyLR implicit $w0 323 324... 325--- 326name: whilels_b32_s32_keep_ptest_of_bytes 327alignment: 2 328tracksRegLiveness: true 329registers: 330 - { id: 0, class: gpr32 } 331 - { id: 1, class: gpr32 } 332 - { id: 2, class: ppr } 333 - { id: 3, class: ppr } 334 - { id: 4, class: gpr32 } 335 - { id: 5, class: gpr32 } 336liveins: 337 - { reg: '$w0', virtual-reg: '%0' } 338 - { reg: '$w1', virtual-reg: '%1' } 339frameInfo: 340 maxCallFrameSize: 0 341body: | 342 bb.0.entry: 343 liveins: $w0, $w1 344 345 ; PTEST is not redundant when it's Pg operand is not an all active predicate 346 ; of element size matching the WHILELS, which is the implicitly predicate 347 ; used by WHILE when calculating the condition codes. 348 ; 349 ; CHECK-LABEL: name: whilels_b32_s32_keep_ptest_of_bytes 350 ; CHECK: %3:ppr = WHILELS_PWW_S %0, %1, implicit-def dead $nzcv 351 ; CHECK-NEXT: PTEST_PP killed %2, killed %3, implicit-def $nzcv 352 ; CHECK-NEXT: %4:gpr32 = COPY $wzr 353 ; CHECK-NEXT: %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 354 %1:gpr32 = COPY $w1 355 %0:gpr32 = COPY $w0 356 %2:ppr = PTRUE_B 31, implicit $vg 357 %3:ppr = WHILELS_PWW_S %0, %1, implicit-def dead $nzcv 358 PTEST_PP killed %2, killed %3, implicit-def $nzcv 359 %4:gpr32 = COPY $wzr 360 %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 361 $w0 = COPY %5 362 RET_ReallyLR implicit $w0 363 364... 365--- 366name: whilels_b32_s32_keep_ptest_of_halfs 367alignment: 2 368tracksRegLiveness: true 369registers: 370 - { id: 0, class: gpr32 } 371 - { id: 1, class: gpr32 } 372 - { id: 2, class: ppr } 373 - { id: 3, class: ppr } 374 - { id: 4, class: gpr32 } 375 - { id: 5, class: gpr32 } 376liveins: 377 - { reg: '$w0', virtual-reg: '%0' } 378 - { reg: '$w1', virtual-reg: '%1' } 379frameInfo: 380 maxCallFrameSize: 0 381body: | 382 bb.0.entry: 383 liveins: $w0, $w1 384 385 ; PTEST is not redundant when it's Pg operand is not an all active predicate 386 ; of element size matching the WHILELS, which is the implicitly predicate 387 ; used by WHILE when calculating the condition codes. 388 ; 389 ; CHECK-LABEL: name: whilels_b32_s32_keep_ptest_of_halfs 390 ; CHECK: %3:ppr = WHILELS_PWW_S %0, %1, implicit-def dead $nzcv 391 ; CHECK-NEXT: PTEST_PP killed %2, killed %3, implicit-def $nzcv 392 ; CHECK-NEXT: %4:gpr32 = COPY $wzr 393 ; CHECK-NEXT: %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 394 %1:gpr32 = COPY $w1 395 %0:gpr32 = COPY $w0 396 %2:ppr = PTRUE_H 31, implicit $vg 397 %3:ppr = WHILELS_PWW_S %0, %1, implicit-def dead $nzcv 398 PTEST_PP killed %2, killed %3, implicit-def $nzcv 399 %4:gpr32 = COPY $wzr 400 %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 401 $w0 = COPY %5 402 RET_ReallyLR implicit $w0 403 404... 405--- 406name: whilels_b32_s32_keep_ptest_of_doublewords 407alignment: 2 408tracksRegLiveness: true 409registers: 410 - { id: 0, class: gpr32 } 411 - { id: 1, class: gpr32 } 412 - { id: 2, class: ppr } 413 - { id: 3, class: ppr } 414 - { id: 4, class: gpr32 } 415 - { id: 5, class: gpr32 } 416liveins: 417 - { reg: '$w0', virtual-reg: '%0' } 418 - { reg: '$w1', virtual-reg: '%1' } 419frameInfo: 420 maxCallFrameSize: 0 421body: | 422 bb.0.entry: 423 liveins: $w0, $w1 424 425 ; PTEST is not redundant when it's Pg operand is not an all active predicate 426 ; of element size matching the WHILELS, which is the implicitly predicate 427 ; used by WHILE when calculating the condition codes. 428 ; 429 ; CHECK-LABEL: name: whilels_b32_s32_keep_ptest_of_doublewords 430 ; CHECK: %3:ppr = WHILELS_PWW_S %0, %1, implicit-def dead $nzcv 431 ; CHECK-NEXT: PTEST_PP killed %2, killed %3, implicit-def $nzcv 432 ; CHECK-NEXT: %4:gpr32 = COPY $wzr 433 ; CHECK-NEXT: %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 434 %1:gpr32 = COPY $w1 435 %0:gpr32 = COPY $w0 436 %2:ppr = PTRUE_D 31, implicit $vg 437 %3:ppr = WHILELS_PWW_S %0, %1, implicit-def dead $nzcv 438 PTEST_PP killed %2, killed %3, implicit-def $nzcv 439 %4:gpr32 = COPY $wzr 440 %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 441 $w0 = COPY %5 442 RET_ReallyLR implicit $w0 443 444... 445