Skip to content

Commit 15a05c0

Browse files
[AArch64][SVE] Add PTEST_FIRST pseudo instruction (#157489)
The pseudo is created when the condition of a ptest is FIRST_ACTIVE. This allows optimizePTestInstr to be extended to handle whilecc intrinsics that return a predicate pair, where it is necessary to identify the condition code used to remove a ptest on the first result of the pair. (See #156478)
1 parent 17abebe commit 15a05c0

File tree

4 files changed

+17
-6
lines changed

4 files changed

+17
-6
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22306,10 +22306,14 @@ static SDValue getPTest(SelectionDAG &DAG, EVT VT, SDValue Pg, SDValue Op,
2230622306
Op = DAG.getNode(AArch64ISD::REINTERPRET_CAST, DL, MVT::nxv16i1, Op);
2230722307
}
2230822308

22309+
unsigned PTest = AArch64ISD::PTEST;
22310+
if (Cond == AArch64CC::ANY_ACTIVE)
22311+
PTest = AArch64ISD::PTEST_ANY;
22312+
else if (Cond == AArch64CC::FIRST_ACTIVE)
22313+
PTest = AArch64ISD::PTEST_FIRST;
22314+
2230922315
// Set condition code (CC) flags.
22310-
SDValue Test = DAG.getNode(
22311-
Cond == AArch64CC::ANY_ACTIVE ? AArch64ISD::PTEST_ANY : AArch64ISD::PTEST,
22312-
DL, MVT::i32, Pg, Op);
22316+
SDValue Test = DAG.getNode(PTest, DL, MVT::i32, Pg, Op);
2231322317

2231422318
// Convert CC to integer based on requested condition.
2231522319
// NOTE: Cond is inverted to promote CSEL's removal when it feeds a compare.

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,6 +1299,7 @@ bool AArch64InstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,
12991299
break;
13001300
case AArch64::PTEST_PP:
13011301
case AArch64::PTEST_PP_ANY:
1302+
case AArch64::PTEST_PP_FIRST:
13021303
SrcReg = MI.getOperand(0).getReg();
13031304
SrcReg2 = MI.getOperand(1).getReg();
13041305
if (MI.getOperand(2).getSubReg())
@@ -1691,7 +1692,8 @@ bool AArch64InstrInfo::optimizeCompareInstr(
16911692
}
16921693

16931694
if (CmpInstr.getOpcode() == AArch64::PTEST_PP ||
1694-
CmpInstr.getOpcode() == AArch64::PTEST_PP_ANY)
1695+
CmpInstr.getOpcode() == AArch64::PTEST_PP_ANY ||
1696+
CmpInstr.getOpcode() == AArch64::PTEST_PP_FIRST)
16951697
return optimizePTestInstr(&CmpInstr, SrcReg, SrcReg2, MRI);
16961698

16971699
if (SrcReg2 != 0)

llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ def SDT_AArch64PTest : SDTypeProfile<1, 2, [
412412
]>;
413413
def AArch64ptest : SDNode<"AArch64ISD::PTEST", SDT_AArch64PTest>;
414414
def AArch64ptest_any : SDNode<"AArch64ISD::PTEST_ANY", SDT_AArch64PTest>;
415+
def AArch64ptest_first : SDNode<"AArch64ISD::PTEST_FIRST", SDT_AArch64PTest>;
415416

416417
def SDT_AArch64DUP_PRED : SDTypeProfile<1, 3,
417418
[SDTCisVec<0>, SDTCisSameAs<0, 3>, SDTCisVec<1>, SDTCVecEltisVT<1,i1>, SDTCisSameNumEltsAs<0, 1>]>;
@@ -1071,7 +1072,7 @@ let Predicates = [HasSVE_or_SME] in {
10711072
defm BRKB_PPmP : sve_int_break_m<0b101, "brkb", int_aarch64_sve_brkb>;
10721073
defm BRKBS_PPzP : sve_int_break_z<0b110, "brkbs", null_frag>;
10731074

1074-
defm PTEST_PP : sve_int_ptest<0b010000, "ptest", AArch64ptest, AArch64ptest_any>;
1075+
defm PTEST_PP : sve_int_ptest<0b010000, "ptest", AArch64ptest, AArch64ptest_any, AArch64ptest_first>;
10751076
defm PFALSE : sve_int_pfalse<0b000000, "pfalse">;
10761077
defm PFIRST : sve_int_pfirst<0b00000, "pfirst", int_aarch64_sve_pfirst>;
10771078
defm PNEXT : sve_int_pnext<0b00110, "pnext", int_aarch64_sve_pnext>;

llvm/lib/Target/AArch64/SVEInstrFormats.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -893,13 +893,17 @@ class sve_int_ptest<bits<6> opc, string asm, SDPatternOperator op>
893893
}
894894

895895
multiclass sve_int_ptest<bits<6> opc, string asm, SDPatternOperator op,
896-
SDPatternOperator op_any> {
896+
SDPatternOperator op_any, SDPatternOperator op_first> {
897897
def NAME : sve_int_ptest<opc, asm, op>;
898898

899899
let hasNoSchedulingInfo = 1, isCompare = 1, Defs = [NZCV] in {
900900
def _ANY : Pseudo<(outs), (ins PPRAny:$Pg, PPR8:$Pn),
901901
[(set NZCV, (op_any (nxv16i1 PPRAny:$Pg), (nxv16i1 PPR8:$Pn)))]>,
902902
PseudoInstExpansion<(!cast<Instruction>(NAME) PPRAny:$Pg, PPR8:$Pn)>;
903+
904+
def _FIRST : Pseudo<(outs), (ins PPRAny:$Pg, PPR8:$Pn),
905+
[(set NZCV, (op_first (nxv16i1 PPRAny:$Pg), (nxv16i1 PPR8:$Pn)))]>,
906+
PseudoInstExpansion<(!cast<Instruction>(NAME) PPRAny:$Pg, PPR8:$Pn)>;
903907
}
904908
}
905909

0 commit comments

Comments
 (0)