Skip to content

Commit df6e831

Browse files
committed
Use single ISel opcode for register-register and register-immediate CB
1 parent 563ae0f commit df6e831

File tree

5 files changed

+93
-60
lines changed

5 files changed

+93
-60
lines changed

llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,9 @@ class AArch64DAGToDAGISel : public SelectionDAGISel {
507507

508508
bool SelectAllActivePredicate(SDValue N);
509509
bool SelectAnyPredicate(SDValue N);
510+
511+
template <int Bits>
512+
bool SelectCmpBranchUImm6Operand(SDNode *P, SDValue N, SDValue &Imm);
510513
};
511514

512515
class AArch64DAGToDAGISelLegacy : public SelectionDAGISelLegacy {
@@ -7489,3 +7492,57 @@ bool AArch64DAGToDAGISel::SelectSMETileSlice(SDValue N, unsigned MaxSize,
74897492
Offset = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i64);
74907493
return true;
74917494
}
7495+
7496+
template <int Bits>
7497+
bool AArch64DAGToDAGISel::SelectCmpBranchUImm6Operand(SDNode *P, SDValue N,
7498+
SDValue &Imm) {
7499+
ConstantSDNode *C = dyn_cast<ConstantSDNode>(P->getOperand(1));
7500+
if (!C)
7501+
return false;
7502+
7503+
AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(C->getZExtValue());
7504+
if (auto *CN = dyn_cast<ConstantSDNode>(N)) {
7505+
// Check conservatively if the immediate fits the valid range [0, 64).
7506+
// Immediate variants for GE and HS definitely need to be decremented
7507+
// when lowering the pseudos later, so an immediate of 1 would become 0.
7508+
// For the inverse conditions LT and LO we don't know for sure if they
7509+
// will need a decrement but should the decision be made to reverse the
7510+
// branch condition, we again end up with the need to decrement.
7511+
// The same argument holds for LE, LS, GT and HI and possibly
7512+
// incremented immediates. This can lead to slightly less optimal
7513+
// codegen, e.g. we never codegen the legal case
7514+
// cblt w0, #63, A
7515+
// because we could end up with the illegal case
7516+
// cbge w0, #64, B
7517+
// should the decision to reverse the branch direction be made. For the
7518+
// lower bound cases this is no problem since we can express comparisons
7519+
// against 0 with either tbz/tnbz or using wzr/xzr.
7520+
uint64_t LowerBound = 0, UpperBound = 64;
7521+
switch (CC) {
7522+
case AArch64CC::GE:
7523+
case AArch64CC::HS:
7524+
case AArch64CC::LT:
7525+
case AArch64CC::LO:
7526+
LowerBound = 1;
7527+
break;
7528+
case AArch64CC::LE:
7529+
case AArch64CC::LS:
7530+
case AArch64CC::GT:
7531+
case AArch64CC::HI:
7532+
UpperBound = 63;
7533+
break;
7534+
default:
7535+
break;
7536+
}
7537+
7538+
if (CN->getAPIntValue().uge(LowerBound) &&
7539+
CN->getAPIntValue().ult(UpperBound)) {
7540+
SDLoc DL(N);
7541+
Imm = CurDAG->getTargetConstant(CN->getZExtValue(), DL,
7542+
Bits == 32 ? MVT::i32 : MVT::i64);
7543+
return true;
7544+
}
7545+
}
7546+
7547+
return false;
7548+
}

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 5 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2983,8 +2983,7 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const {
29832983
MAKE_CASE(AArch64ISD::CTTZ_ELTS)
29842984
MAKE_CASE(AArch64ISD::CALL_ARM64EC_TO_X64)
29852985
MAKE_CASE(AArch64ISD::URSHR_I_PRED)
2986-
MAKE_CASE(AArch64ISD::CBRR)
2987-
MAKE_CASE(AArch64ISD::CBRI)
2986+
MAKE_CASE(AArch64ISD::CB)
29882987
}
29892988
#undef MAKE_CASE
29902989
return nullptr;
@@ -10600,49 +10599,10 @@ SDValue AArch64TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
1060010599
if (Subtarget->hasCMPBR() &&
1060110600
AArch64CC::isValidCBCond(changeIntCCToAArch64CC(CC)) &&
1060210601
ProduceNonFlagSettingCondBr) {
10603-
AArch64CC::CondCode ACC = changeIntCCToAArch64CC(CC);
10604-
unsigned Opc = AArch64ISD::CBRR;
10605-
if (auto *Imm = dyn_cast<ConstantSDNode>(RHS)) {
10606-
// Check conservatively if the immediate fits the valid range [0, 64).
10607-
// Immediate variants for GE and HS definitely need to be decremented
10608-
// when lowering the pseudos later, so an immediate of 1 would become 0.
10609-
// For the inverse conditions LT and LO we don't know for sure if they
10610-
// will need a decrement but should the decision be made to reverse the
10611-
// branch condition, we again end up with the need to decrement.
10612-
// The same argument holds for LE, LS, GT and HI and possibly
10613-
// incremented immediates. This can lead to slightly less optimal
10614-
// codegen, e.g. we never codegen the legal case
10615-
// cblt w0, #63, A
10616-
// because we could end up with the illegal case
10617-
// cbge w0, #64, B
10618-
// should the decision to reverse the branch direction be made. For the
10619-
// lower bound cases this is no problem since we can express comparisons
10620-
// against 0 with either tbz/tnbz or using wzr/xzr.
10621-
uint64_t LowerBound = 0, UpperBound = 64;
10622-
switch (ACC) {
10623-
case AArch64CC::GE:
10624-
case AArch64CC::HS:
10625-
case AArch64CC::LT:
10626-
case AArch64CC::LO:
10627-
LowerBound = 1;
10628-
break;
10629-
case AArch64CC::LE:
10630-
case AArch64CC::LS:
10631-
case AArch64CC::GT:
10632-
case AArch64CC::HI:
10633-
UpperBound = 63;
10634-
break;
10635-
default:
10636-
break;
10637-
}
10638-
10639-
if (Imm->getAPIntValue().uge(LowerBound) &&
10640-
Imm->getAPIntValue().ult(UpperBound))
10641-
Opc = AArch64ISD::CBRI;
10642-
}
10643-
10644-
SDValue Cond = DAG.getTargetConstant(ACC, dl, MVT::i32);
10645-
return DAG.getNode(Opc, dl, MVT::Other, Chain, Cond, LHS, RHS, Dest);
10602+
SDValue Cond =
10603+
DAG.getTargetConstant(changeIntCCToAArch64CC(CC), dl, MVT::i32);
10604+
return DAG.getNode(AArch64ISD::CB, dl, MVT::Other, Chain, Cond, LHS, RHS,
10605+
Dest);
1064610606
}
1064710607

1064810608
SDValue CCVal;

llvm/lib/Target/AArch64/AArch64ISelLowering.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -531,8 +531,7 @@ enum NodeType : unsigned {
531531
SME_ZA_STR,
532532

533533
// Compare-and-branch
534-
CBRR,
535-
CBRI,
534+
CB,
536535
};
537536

538537
} // end namespace AArch64ISD

llvm/lib/Target/AArch64/AArch64InstrFormats.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,20 @@ def uimm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 64; }]> {
400400
let ParserMatchClass = UImm6Operand;
401401
}
402402

403+
def CmpBranchUImm6Operand_32b
404+
: Operand<i32>,
405+
ComplexPattern<i32, 1, "SelectCmpBranchUImm6Operand<32>"> {
406+
let ParserMatchClass = UImm6Operand;
407+
let WantsParent = true;
408+
}
409+
410+
def CmpBranchUImm6Operand_64b
411+
: Operand<i64>,
412+
ComplexPattern<i64, 1, "SelectCmpBranchUImm6Operand<64>"> {
413+
let ParserMatchClass = UImm6Operand;
414+
let WantsParent = true;
415+
}
416+
403417
def UImm6Plus1Operand : AsmOperandClass {
404418
let Name = "UImm6P1";
405419
let DiagnosticType = "InvalidImm1_64";

llvm/lib/Target/AArch64/AArch64InstrInfo.td

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -518,8 +518,9 @@ def SDT_AArch64TBL : SDTypeProfile<1, 2, [
518518
SDTCisVec<0>, SDTCisSameAs<0, 1>, SDTCisInt<2>
519519
]>;
520520

521-
def SDT_AArch64cbrr : SDTypeProfile<0, 4, [SDTCisVT<0, i32>, SDTCisInt<1>, SDTCisSameAs<1, 2>, SDTCisVT<3, OtherVT>]>;
522-
def SDT_AArch64cbri : SDTypeProfile<0, 4, [SDTCisVT<0, i32>, SDTCisInt<1>, SDTCisInt<2>, SDTCisVT<3, OtherVT>]>;
521+
def SDT_AArch64cb : SDTypeProfile<0, 4,
522+
[SDTCisVT<0, i32>, SDTCisInt<1>, SDTCisInt<2>,
523+
SDTCisVT<3, OtherVT>]>;
523524

524525
// non-extending masked load fragment.
525526
def nonext_masked_load :
@@ -697,8 +698,7 @@ def topbitsallzero64: PatLeaf<(i64 GPR64:$src), [{
697698
}]>;
698699

699700
// Node definitions.
700-
def AArch64CBrr : SDNode<"AArch64ISD::CBRR", SDT_AArch64cbrr, [SDNPHasChain]>;
701-
def AArch64CBri : SDNode<"AArch64ISD::CBRI", SDT_AArch64cbri, [SDNPHasChain]>;
701+
def AArch64CB : SDNode<"AArch64ISD::CB", SDT_AArch64cb, [SDNPHasChain]>;
702702
def AArch64adrp : SDNode<"AArch64ISD::ADRP", SDTIntUnaryOp, []>;
703703
def AArch64adr : SDNode<"AArch64ISD::ADR", SDTIntUnaryOp, []>;
704704
def AArch64addlow : SDNode<"AArch64ISD::ADDlow", SDTIntBinOp, []>;
@@ -10552,15 +10552,18 @@ let Predicates = [HasCMPBR] in {
1055210552
def CBWPri : CmpBranchImmediatePseudo<GPR32, uimm6_32b>;
1055310553
def CBXPri : CmpBranchImmediatePseudo<GPR64, uimm6_64b>;
1055410554

10555-
def : Pat<(AArch64CBrr i32:$Cond, GPR32:$Rn, GPR32:$Rt, bb:$Target),
10556-
(CBWPrr ccode:$Cond, GPR32:$Rn, GPR32:$Rt, am_brcmpcond:$Target)>;
10557-
def : Pat<(AArch64CBrr i32:$Cond, GPR64:$Rn, GPR64:$Rt, bb:$Target),
10558-
(CBXPrr ccode:$Cond, GPR64:$Rn, GPR64:$Rt, am_brcmpcond:$Target)>;
10559-
def : Pat<(AArch64CBri i32:$Cond, GPR32:$Rn, i32:$Imm, bb:$Target),
10560-
(CBWPri ccode:$Cond, GPR32:$Rn, uimm6_32b:$Imm, am_brcmpcond:$Target)>;
10561-
def : Pat<(AArch64CBri i32:$Cond, GPR64:$Rn, i64:$Imm, bb:$Target),
10562-
(CBXPri ccode:$Cond, GPR64:$Rn, uimm6_64b:$Imm, am_brcmpcond:$Target)>;
10563-
10555+
def : Pat<(AArch64CB i32:$Cond, GPR32:$Rn, CmpBranchUImm6Operand_32b:$Imm,
10556+
bb:$Target),
10557+
(CBWPri i32:$Cond, GPR32:$Rn, uimm6_32b:$Imm,
10558+
am_brcmpcond:$Target)>;
10559+
def : Pat<(AArch64CB i32:$Cond, GPR64:$Rn, CmpBranchUImm6Operand_64b:$Imm,
10560+
bb:$Target),
10561+
(CBXPri i32:$Cond, GPR64:$Rn, uimm6_64b:$Imm,
10562+
am_brcmpcond:$Target)>;
10563+
def : Pat<(AArch64CB i32:$Cond, GPR32:$Rn, GPR32:$Rt, bb:$Target),
10564+
(CBWPrr ccode:$Cond, GPR32:$Rn, GPR32:$Rt, am_brcmpcond:$Target)>;
10565+
def : Pat<(AArch64CB i32:$Cond, GPR64:$Rn, GPR64:$Rt, bb:$Target),
10566+
(CBXPrr ccode:$Cond, GPR64:$Rn, GPR64:$Rt, am_brcmpcond:$Target)>;
1056410567
} // HasCMPBR
1056510568

1056610569

0 commit comments

Comments
 (0)