diff --git a/llvm/lib/Target/AArch64/SVEInstrFormats.td b/llvm/lib/Target/AArch64/SVEInstrFormats.td --- a/llvm/lib/Target/AArch64/SVEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SVEInstrFormats.td @@ -627,6 +627,8 @@ let Constraints = "$Pdn = $_Pdn"; let Defs = [NZCV]; + let isPTestLike = 1; + let ElementSize = pprty.ElementSize; } multiclass sve_int_pfirst opc, string asm, SDPatternOperator op> { diff --git a/llvm/test/CodeGen/AArch64/sve-ptest-removal-pfirst.mir b/llvm/test/CodeGen/AArch64/sve-ptest-removal-pfirst.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-ptest-removal-pfirst.mir @@ -0,0 +1,24 @@ +# RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve -run-pass=peephole-opt -verify-machineinstrs %s -o - | FileCheck %s + +# Test instruction sequences where PTEST is redundant and thus gets removed. +--- +# CHECK-LABEL: name:{{\s*}} pnext_nxv16i8 +name: pnext_nxv16i8 +tracksRegLiveness: true +body: | + bb.0: + liveins: $p0, $p1 + %0:ppr_3b = COPY $p0 + %1:ppr_3b = COPY $p1 + + ; CHECK: %2:ppr = PFIRST_B %0, %1, implicit-def $nzcv + ; CHECK-NEXT: %3:gpr32 = COPY $wzr + ; CHECK-NEXT: %4:gpr32 = CSINCWr %3, $wzr, 0, implicit $nzcv + %2:ppr = PFIRST_B %0, %1, implicit-def dead $nzcv + PTEST_PP %0, killed %2, implicit-def $nzcv + + %3:gpr32 = COPY $wzr + %4:gpr32 = CSINCWr %3, $wzr, 0, implicit $nzcv + $w0 = COPY %4 + RET_ReallyLR implicit $w0 +... diff --git a/llvm/test/CodeGen/AArch64/sve-ptest-removal-pnext.mir b/llvm/test/CodeGen/AArch64/sve-ptest-removal-pnext.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/sve-ptest-removal-pnext.mir @@ -0,0 +1,88 @@ +# RUN: llc -mtriple=aarch64--linux-gnu -mattr=+sve -run-pass=peephole-opt -verify-machineinstrs %s -o - | FileCheck %s + +# Test instruction sequences where PTEST is redundant and thus gets removed. +--- +# CHECK-LABEL: name:{{\s*}} pnext_nxv2i64 +name: pnext_nxv2i64 +tracksRegLiveness: true +body: | + bb.0: + liveins: $p0, $p1 + %0:ppr_3b = COPY $p0 + %1:ppr_3b = COPY $p1 + + ; CHECK: %2:ppr = PNEXT_D %0, %1, implicit-def $nzcv + ; CHECK-NEXT: %3:gpr32 = COPY $wzr + ; CHECK-NEXT: %4:gpr32 = CSINCWr %3, $wzr, 0, implicit $nzcv + %2:ppr = PNEXT_D %0, %1, implicit-def dead $nzcv + PTEST_PP %0, killed %2, implicit-def $nzcv + + %3:gpr32 = COPY $wzr + %4:gpr32 = CSINCWr %3, $wzr, 0, implicit $nzcv + $w0 = COPY %4 + RET_ReallyLR implicit $w0 +... +--- +# CHECK-LABEL: name:{{\s*}} pnext_nxv4i32 +name: pnext_nxv4i32 +tracksRegLiveness: true +body: | + bb.0: + liveins: $p0, $p1 + %0:ppr_3b = COPY $p0 + %1:ppr_3b = COPY $p1 + + ; CHECK: %2:ppr = PNEXT_S %0, %1, implicit-def $nzcv + ; CHECK-NEXT: %3:gpr32 = COPY $wzr + ; CHECK-NEXT: %4:gpr32 = CSINCWr %3, $wzr, 0, implicit $nzcv + %2:ppr = PNEXT_S %0, %1, implicit-def dead $nzcv + PTEST_PP %0, killed %2, implicit-def $nzcv + + %3:gpr32 = COPY $wzr + %4:gpr32 = CSINCWr %3, $wzr, 0, implicit $nzcv + $w0 = COPY %4 + RET_ReallyLR implicit $w0 +... +--- +# CHECK-LABEL: name:{{\s*}} pnext_nxv8i16 +name: pnext_nxv8i16 +tracksRegLiveness: true +body: | + bb.0: + liveins: $p0, $p1 + %0:ppr_3b = COPY $p0 + %1:ppr_3b = COPY $p1 + + ; CHECK: %2:ppr = PNEXT_H %0, %1, implicit-def $nzcv + ; CHECK-NEXT: %3:gpr32 = COPY $wzr + ; CHECK-NEXT: %4:gpr32 = CSINCWr %3, $wzr, 0, implicit $nzcv + %2:ppr = PNEXT_H %0, %1, implicit-def dead $nzcv + PTEST_PP %0, killed %2, implicit-def $nzcv + + %3:gpr32 = COPY $wzr + %4:gpr32 = CSINCWr %3, $wzr, 0, implicit $nzcv + $w0 = COPY %4 + RET_ReallyLR implicit $w0 +... +--- +# CHECK-LABEL: name:{{\s*}} pnext_nxv16i8 +name: pnext_nxv16i8 +tracksRegLiveness: true +body: | + bb.0: + liveins: $p0, $p1 + %0:ppr_3b = COPY $p0 + %1:ppr_3b = COPY $p1 + + ; CHECK: %2:ppr = PNEXT_B %0, %1, implicit-def $nzcv + ; CHECK-NEXT: %3:gpr32 = COPY $wzr + ; CHECK-NEXT: %4:gpr32 = CSINCWr %3, $wzr, 0, implicit $nzcv + %2:ppr = PNEXT_B %0, %1, implicit-def dead $nzcv + PTEST_PP %0, killed %2, implicit-def $nzcv + + %3:gpr32 = COPY $wzr + %4:gpr32 = CSINCWr %3, $wzr, 0, implicit $nzcv + $w0 = COPY %4 + RET_ReallyLR implicit $w0 + +...