Skip to content

Commit 6d3a477

Browse files
[LLVM][CodeGen][AArch64] Improve PTEST removal by looking through copies.
The general predicates of the PTEST and PTEST_like instructions may belong to different register classes. This can lead to the insertion of a COPY instruction, making them appear different. However, for the purpose of PTEST removal, such copies are irrelevant, and we can look through them to improve the likelihood of finding a match.
1 parent 715d144 commit 6d3a477

File tree

2 files changed

+11
-4
lines changed

2 files changed

+11
-4
lines changed

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,13 +1491,22 @@ AArch64InstrInfo::canRemovePTestInstr(MachineInstr *PTest, MachineInstr *Mask,
14911491
if ((Mask == Pred) && PTest->getOpcode() == AArch64::PTEST_PP_ANY)
14921492
return PredOpcode;
14931493

1494+
auto PTestLikeMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg());
1495+
1496+
// If the PTEST like instruction's general predicate is not `Mask`, attempt
1497+
// to look through a copy and try again. This is because some instructions
1498+
// take a predicate whose register class is a subset of its result class.
1499+
if (Mask != PTestLikeMask && PTestLikeMask->isFullCopy() &&
1500+
PTestLikeMask->getOperand(1).getReg().isVirtual())
1501+
PTestLikeMask =
1502+
MRI->getUniqueVRegDef(PTestLikeMask->getOperand(1).getReg());
1503+
14941504
// For PTEST(PTRUE_ALL, PTEST_LIKE), the PTEST is redundant if the
14951505
// the element size matches and either the PTEST_LIKE instruction uses
14961506
// the same all active mask or the condition is "any".
14971507
if (isPTrueOpcode(MaskOpcode) && Mask->getOperand(1).getImm() == 31 &&
14981508
getElementSizeForOpcode(MaskOpcode) ==
14991509
getElementSizeForOpcode(PredOpcode)) {
1500-
auto PTestLikeMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg());
15011510
if (Mask == PTestLikeMask || PTest->getOpcode() == AArch64::PTEST_PP_ANY)
15021511
return PredOpcode;
15031512
}
@@ -1524,7 +1533,6 @@ AArch64InstrInfo::canRemovePTestInstr(MachineInstr *PTest, MachineInstr *Mask,
15241533
// active flag, whereas the PTEST instruction with the same mask doesn't.
15251534
// For PTEST_ANY this doesn't apply as the flags in this case would be
15261535
// identical regardless of element size.
1527-
auto PTestLikeMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg());
15281536
uint64_t PredElementSize = getElementSizeForOpcode(PredOpcode);
15291537
if (Mask == PTestLikeMask && (PredElementSize == AArch64::ElementSizeB ||
15301538
PTest->getOpcode() == AArch64::PTEST_PP_ANY))

llvm/test/CodeGen/AArch64/sve-ptest-removal-cmpeq.mir

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -689,8 +689,7 @@ body: |
689689
; CHECK-NEXT: [[COPY1:%[0-9]+]]:zpr = COPY $z1
690690
; CHECK-NEXT: [[PTRUE_B:%[0-9]+]]:ppr = PTRUE_B 31, implicit $vg
691691
; CHECK-NEXT: [[COPY2:%[0-9]+]]:ppr_3b = COPY [[PTRUE_B]]
692-
; CHECK-NEXT: [[CMPEQ_PPzZZ_B:%[0-9]+]]:ppr = CMPEQ_PPzZZ_B [[COPY2]], [[COPY]], [[COPY1]], implicit-def dead $nzcv
693-
; CHECK-NEXT: PTEST_PP [[PTRUE_B]], killed [[CMPEQ_PPzZZ_B]], implicit-def $nzcv
692+
; CHECK-NEXT: [[CMPEQ_PPzZZ_B:%[0-9]+]]:ppr = CMPEQ_PPzZZ_B [[COPY2]], [[COPY]], [[COPY1]], implicit-def $nzcv
694693
; CHECK-NEXT: [[COPY3:%[0-9]+]]:gpr32 = COPY $wzr
695694
; CHECK-NEXT: [[CSINCWr:%[0-9]+]]:gpr32 = CSINCWr [[COPY3]], $wzr, 0, implicit $nzcv
696695
; CHECK-NEXT: $w0 = COPY [[CSINCWr]]

0 commit comments

Comments
 (0)