1# RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve2 -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: whilewr_b8_s64 6alignment: 2 7tracksRegLiveness: true 8registers: 9 - { id: 0, class: gpr64 } 10 - { id: 1, class: gpr64 } 11 - { id: 2, class: ppr } 12 - { id: 3, class: ppr } 13 - { id: 4, class: gpr32 } 14 - { id: 5, class: gpr32 } 15liveins: 16 - { reg: '$x0', virtual-reg: '%0' } 17 - { reg: '$x1', virtual-reg: '%1' } 18frameInfo: 19 maxCallFrameSize: 0 20body: | 21 bb.0.entry: 22 liveins: $x0, $x1 23 24 ; Here we check the expected sequence with subsequent tests 25 ; just asserting there is no PTEST instruction. 26 ; 27 ; CHECK-LABEL: name: whilewr_b8_s64 28 ; CHECK: %3:ppr = WHILEWR_PXX_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:gpr64 = COPY $x1 32 %0:gpr64 = COPY $x0 33 %2:ppr = PTRUE_B 31, implicit $vg 34 %3:ppr = WHILEWR_PXX_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: whilewr_b16_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: ppr } 52 - { id: 5, class: ppr } 53 - { id: 6, class: gpr32 } 54 - { id: 7, class: gpr32 } 55liveins: 56 - { reg: '$x0', virtual-reg: '%0' } 57 - { reg: '$x1', virtual-reg: '%1' } 58frameInfo: 59 maxCallFrameSize: 0 60body: | 61 bb.0.entry: 62 liveins: $x0, $x1 63 64 ; CHECK-LABEL: name: whilewr_b16_s64 65 ; CHECK-NOT: PTEST 66 %1:gpr64 = COPY $x1 67 %0:gpr64 = COPY $x0 68 %2:ppr = PTRUE_H 31, implicit $vg 69 %4:ppr = WHILEWR_PXX_H %0, %1, implicit-def dead $nzcv 70 PTEST_PP %2, %4, implicit-def $nzcv 71 %6:gpr32 = COPY $wzr 72 %7:gpr32 = CSINCWr %6, $wzr, 0, implicit $nzcv 73 $w0 = COPY %7 74 RET_ReallyLR implicit $w0 75 76... 77--- 78name: whilewr_b32_s64 79alignment: 2 80tracksRegLiveness: true 81registers: 82 - { id: 0, class: gpr64 } 83 - { id: 1, class: gpr64 } 84 - { id: 2, class: ppr } 85 - { id: 3, class: ppr } 86 - { id: 4, class: ppr } 87 - { id: 5, class: ppr } 88 - { id: 6, class: gpr32 } 89 - { id: 7, class: gpr32 } 90liveins: 91 - { reg: '$x0', virtual-reg: '%0' } 92 - { reg: '$x1', virtual-reg: '%1' } 93frameInfo: 94 maxCallFrameSize: 0 95body: | 96 bb.0.entry: 97 liveins: $x0, $x1 98 99 ; CHECK-LABEL: name: whilewr_b32_s64 100 ; CHECK-NOT: PTEST 101 %1:gpr64 = COPY $x1 102 %0:gpr64 = COPY $x0 103 %2:ppr = PTRUE_S 31, implicit $vg 104 %4:ppr = WHILEWR_PXX_S %0, %1, implicit-def dead $nzcv 105 PTEST_PP %2, %4, implicit-def $nzcv 106 %6:gpr32 = COPY $wzr 107 %7:gpr32 = CSINCWr %6, $wzr, 0, implicit $nzcv 108 $w0 = COPY %7 109 RET_ReallyLR implicit $w0 110 111... 112--- 113name: whilewr_b64_s64 114alignment: 2 115tracksRegLiveness: true 116registers: 117 - { id: 0, class: gpr64 } 118 - { id: 1, class: gpr64 } 119 - { id: 2, class: ppr } 120 - { id: 3, class: ppr } 121 - { id: 4, class: ppr } 122 - { id: 5, class: ppr } 123 - { id: 6, class: gpr32 } 124 - { id: 7, class: gpr32 } 125liveins: 126 - { reg: '$x0', virtual-reg: '%0' } 127 - { reg: '$x1', virtual-reg: '%1' } 128frameInfo: 129 maxCallFrameSize: 0 130body: | 131 bb.0.entry: 132 liveins: $x0, $x1 133 134 ; CHECK-LABEL: name: whilewr_b64_s64 135 ; CHECK-NOT: PTEST 136 %1:gpr64 = COPY $x1 137 %0:gpr64 = COPY $x0 138 %2:ppr = PTRUE_D 31, implicit $vg 139 %4:ppr = WHILEWR_PXX_D %0, %1, implicit-def dead $nzcv 140 PTEST_PP %2, %4, implicit-def $nzcv 141 %6:gpr32 = COPY $wzr 142 %7:gpr32 = CSINCWr %6, $wzr, 0, implicit $nzcv 143 $w0 = COPY %7 144 RET_ReallyLR implicit $w0 145 146... 147--- 148name: whilewr_b8_s64_keep_ptest_not_all_active 149alignment: 2 150tracksRegLiveness: true 151registers: 152 - { id: 0, class: gpr64 } 153 - { id: 1, class: gpr64 } 154 - { id: 2, class: ppr } 155 - { id: 3, class: ppr } 156 - { id: 4, class: gpr32 } 157 - { id: 5, class: gpr32 } 158liveins: 159 - { reg: '$x0', virtual-reg: '%0' } 160 - { reg: '$x1', virtual-reg: '%1' } 161frameInfo: 162 maxCallFrameSize: 0 163body: | 164 bb.0.entry: 165 liveins: $x0, $x1 166 167 ; PTEST is not redundant when it's Pg operand is not an all active predicate 168 ; of element size matching the WHILEGE, which is the implicitly predicate 169 ; used by WHILE when calculating the condition codes. 170 ; 171 ; CHECK-LABEL: name: whilewr_b8_s64_keep_ptest_not_all_active 172 ; CHECK: %3:ppr = WHILEWR_PXX_B %0, %1, implicit-def dead $nzcv 173 ; CHECK-NEXT: PTEST_PP killed %2, killed %3, implicit-def $nzcv 174 ; CHECK-NEXT: %4:gpr32 = COPY $wzr 175 ; CHECK-NEXT: %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 176 %1:gpr64 = COPY $x1 177 %0:gpr64 = COPY $x0 178 %2:ppr = PTRUE_B 0, implicit $vg 179 %3:ppr = WHILEWR_PXX_B %0, %1, implicit-def dead $nzcv 180 PTEST_PP killed %2, killed %3, implicit-def $nzcv 181 %4:gpr32 = COPY $wzr 182 %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 183 $w0 = COPY %5 184 RET_ReallyLR implicit $w0 185 186... 187--- 188name: whilewr_b8_s64_keep_ptest_of_halfs 189alignment: 2 190tracksRegLiveness: true 191registers: 192 - { id: 0, class: gpr64 } 193 - { id: 1, class: gpr64 } 194 - { id: 2, class: ppr } 195 - { id: 3, class: ppr } 196 - { id: 4, class: gpr32 } 197 - { id: 5, class: gpr32 } 198liveins: 199 - { reg: '$x0', virtual-reg: '%0' } 200 - { reg: '$x1', virtual-reg: '%1' } 201frameInfo: 202 maxCallFrameSize: 0 203body: | 204 bb.0.entry: 205 liveins: $x0, $x1 206 207 ; PTEST is not redundant when it's Pg operand is not an all active predicate 208 ; of element size matching the WHILEGE, which is the implicitly predicate 209 ; used by WHILE when calculating the condition codes. 210 ; 211 ; CHECK-LABEL: name: whilewr_b8_s64_keep_ptest_of_halfs 212 ; CHECK: %3:ppr = WHILEWR_PXX_B %0, %1, implicit-def dead $nzcv 213 ; CHECK-NEXT: PTEST_PP killed %2, killed %3, implicit-def $nzcv 214 ; CHECK-NEXT: %4:gpr32 = COPY $wzr 215 ; CHECK-NEXT: %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 216 %1:gpr64 = COPY $x1 217 %0:gpr64 = COPY $x0 218 %2:ppr = PTRUE_H 31, implicit $vg 219 %3:ppr = WHILEWR_PXX_B %0, %1, implicit-def dead $nzcv 220 PTEST_PP killed %2, killed %3, implicit-def $nzcv 221 %4:gpr32 = COPY $wzr 222 %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 223 $w0 = COPY %5 224 RET_ReallyLR implicit $w0 225 226... 227--- 228name: whilewr_b8_s64_keep_ptest_of_words 229alignment: 2 230tracksRegLiveness: true 231registers: 232 - { id: 0, class: gpr64 } 233 - { id: 1, class: gpr64 } 234 - { id: 2, class: ppr } 235 - { id: 3, class: ppr } 236 - { id: 4, class: gpr32 } 237 - { id: 5, class: gpr32 } 238liveins: 239 - { reg: '$x0', virtual-reg: '%0' } 240 - { reg: '$x1', virtual-reg: '%1' } 241frameInfo: 242 maxCallFrameSize: 0 243body: | 244 bb.0.entry: 245 liveins: $x0, $x1 246 247 ; PTEST is not redundant when it's Pg operand is not an all active predicate 248 ; of element size matching the WHILEGE, which is the implicitly predicate 249 ; used by WHILE when calculating the condition codes. 250 ; 251 ; CHECK-LABEL: name: whilewr_b8_s64_keep_ptest_of_words 252 ; CHECK: %3:ppr = WHILEWR_PXX_B %0, %1, implicit-def dead $nzcv 253 ; CHECK-NEXT: PTEST_PP killed %2, killed %3, implicit-def $nzcv 254 ; CHECK-NEXT: %4:gpr32 = COPY $wzr 255 ; CHECK-NEXT: %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 256 %1:gpr64 = COPY $x1 257 %0:gpr64 = COPY $x0 258 %2:ppr = PTRUE_S 31, implicit $vg 259 %3:ppr = WHILEWR_PXX_B %0, %1, implicit-def dead $nzcv 260 PTEST_PP killed %2, killed %3, implicit-def $nzcv 261 %4:gpr32 = COPY $wzr 262 %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 263 $w0 = COPY %5 264 RET_ReallyLR implicit $w0 265 266... 267--- 268name: whilewr_b8_s64_keep_ptest_of_doublewords 269alignment: 2 270tracksRegLiveness: true 271registers: 272 - { id: 0, class: gpr64 } 273 - { id: 1, class: gpr64 } 274 - { id: 2, class: ppr } 275 - { id: 3, class: ppr } 276 - { id: 4, class: gpr32 } 277 - { id: 5, class: gpr32 } 278liveins: 279 - { reg: '$x0', virtual-reg: '%0' } 280 - { reg: '$x1', virtual-reg: '%1' } 281frameInfo: 282 maxCallFrameSize: 0 283body: | 284 bb.0.entry: 285 liveins: $x0, $x1 286 287 ; PTEST is not redundant when it's Pg operand is not an all active predicate 288 ; of element size matching the WHILEGE, which is the implicitly predicate 289 ; used by WHILE when calculating the condition codes. 290 ; 291 ; CHECK-LABEL: name: whilewr_b8_s64_keep_ptest_of_doublewords 292 ; CHECK: %3:ppr = WHILEWR_PXX_B %0, %1, implicit-def dead $nzcv 293 ; CHECK-NEXT: PTEST_PP killed %2, killed %3, implicit-def $nzcv 294 ; CHECK-NEXT: %4:gpr32 = COPY $wzr 295 ; CHECK-NEXT: %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 296 %1:gpr64 = COPY $x1 297 %0:gpr64 = COPY $x0 298 %2:ppr = PTRUE_D 31, implicit $vg 299 %3:ppr = WHILEWR_PXX_B %0, %1, implicit-def dead $nzcv 300 PTEST_PP killed %2, killed %3, implicit-def $nzcv 301 %4:gpr32 = COPY $wzr 302 %5:gpr32 = CSINCWr %4, $wzr, 0, implicit $nzcv 303 $w0 = COPY %5 304 RET_ReallyLR implicit $w0 305 306... 307