Skip to content

Commit a664e75

Browse files
authored
[RISCV] Refactor DAG-to-DAG Selection: Port lowering code for qc.insb/qc.insbi to RISCVISelLowering.cpp (#157618)
This is a follow-up to #154135 and does similar changes for `qc.insb/qc.insbi`.
1 parent b5daf76 commit a664e75

File tree

3 files changed

+86
-99
lines changed

3 files changed

+86
-99
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 0 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -677,95 +677,6 @@ bool RISCVDAGToDAGISel::trySignedBitfieldExtract(SDNode *Node) {
677677
return false;
678678
}
679679

680-
bool RISCVDAGToDAGISel::trySignedBitfieldInsertInMask(SDNode *Node) {
681-
// Supported only in Xqcibm for now.
682-
if (!Subtarget->hasVendorXqcibm())
683-
return false;
684-
685-
using namespace SDPatternMatch;
686-
687-
SDValue X;
688-
APInt MaskImm;
689-
if (!sd_match(Node, m_Or(m_OneUse(m_Value(X)), m_ConstInt(MaskImm))))
690-
return false;
691-
692-
unsigned ShAmt, Width;
693-
if (!MaskImm.isShiftedMask(ShAmt, Width) || MaskImm.isSignedIntN(12))
694-
return false;
695-
696-
// If Zbs is enabled and it is a single bit set we can use BSETI which
697-
// can be compressed to C_BSETI when Xqcibm in enabled.
698-
if (Width == 1 && Subtarget->hasStdExtZbs())
699-
return false;
700-
701-
// If C1 is a shifted mask (but can't be formed as an ORI),
702-
// use a bitfield insert of -1.
703-
// Transform (or x, C1)
704-
// -> (qc.insbi x, -1, width, shift)
705-
SDLoc DL(Node);
706-
MVT VT = Node->getSimpleValueType(0);
707-
708-
SDValue Ops[] = {X, CurDAG->getSignedTargetConstant(-1, DL, VT),
709-
CurDAG->getTargetConstant(Width, DL, VT),
710-
CurDAG->getTargetConstant(ShAmt, DL, VT)};
711-
SDNode *BitIns = CurDAG->getMachineNode(RISCV::QC_INSBI, DL, VT, Ops);
712-
ReplaceNode(Node, BitIns);
713-
return true;
714-
}
715-
716-
// Generate a QC_INSB/QC_INSBI from 'or (and X, MaskImm), OrImm' iff the value
717-
// being inserted only sets known zero bits.
718-
bool RISCVDAGToDAGISel::tryBitfieldInsertOpFromOrAndImm(SDNode *Node) {
719-
// Supported only in Xqcibm for now.
720-
if (!Subtarget->hasVendorXqcibm())
721-
return false;
722-
723-
using namespace SDPatternMatch;
724-
725-
SDValue And;
726-
APInt MaskImm, OrImm;
727-
if (!sd_match(Node, m_Or(m_OneUse(m_And(m_Value(And), m_ConstInt(MaskImm))),
728-
m_ConstInt(OrImm))))
729-
return false;
730-
731-
// Compute the Known Zero for the AND as this allows us to catch more general
732-
// cases than just looking for AND with imm.
733-
KnownBits Known = CurDAG->computeKnownBits(Node->getOperand(0));
734-
735-
// The bits being inserted must only set those bits that are known to be zero.
736-
if (!OrImm.isSubsetOf(Known.Zero)) {
737-
// FIXME: It's okay if the OrImm sets NotKnownZero bits to 1, but we don't
738-
// currently handle this case.
739-
return false;
740-
}
741-
742-
unsigned ShAmt, Width;
743-
// The KnownZero mask must be a shifted mask (e.g., 1110..011, 11100..00).
744-
if (!Known.Zero.isShiftedMask(ShAmt, Width))
745-
return false;
746-
747-
// QC_INSB(I) dst, src, #width, #shamt.
748-
SDLoc DL(Node);
749-
MVT VT = Node->getSimpleValueType(0);
750-
SDValue ImmNode;
751-
auto Opc = RISCV::QC_INSB;
752-
753-
int32_t LIImm = OrImm.getSExtValue() >> ShAmt;
754-
755-
if (isInt<5>(LIImm)) {
756-
Opc = RISCV::QC_INSBI;
757-
ImmNode = CurDAG->getSignedTargetConstant(LIImm, DL, MVT::i32);
758-
} else {
759-
ImmNode = selectImm(CurDAG, DL, MVT::i32, LIImm, *Subtarget);
760-
}
761-
762-
SDValue Ops[] = {And, ImmNode, CurDAG->getTargetConstant(Width, DL, VT),
763-
CurDAG->getTargetConstant(ShAmt, DL, VT)};
764-
SDNode *BitIns = CurDAG->getMachineNode(Opc, DL, VT, Ops);
765-
ReplaceNode(Node, BitIns);
766-
return true;
767-
}
768-
769680
bool RISCVDAGToDAGISel::trySignedBitfieldInsertInSign(SDNode *Node) {
770681
// Only supported with XAndesPerf at the moment.
771682
if (!Subtarget->hasVendorXAndesPerf())
@@ -1384,12 +1295,6 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
13841295
return;
13851296
}
13861297
case ISD::OR: {
1387-
if (trySignedBitfieldInsertInMask(Node))
1388-
return;
1389-
1390-
if (tryBitfieldInsertOpFromOrAndImm(Node))
1391-
return;
1392-
13931298
if (tryShrinkShlLogicImm(Node))
13941299
return;
13951300

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ class RISCVDAGToDAGISel : public SelectionDAGISel {
7676
bool tryShrinkShlLogicImm(SDNode *Node);
7777
bool trySignedBitfieldExtract(SDNode *Node);
7878
bool trySignedBitfieldInsertInSign(SDNode *Node);
79-
bool trySignedBitfieldInsertInMask(SDNode *Node);
80-
bool tryBitfieldInsertOpFromOrAndImm(SDNode *Node);
8179
bool tryUnsignedBitfieldExtract(SDNode *Node, const SDLoc &DL, MVT VT,
8280
SDValue X, unsigned Msb, unsigned Lsb);
8381
bool tryUnsignedBitfieldInsertInZero(SDNode *Node, const SDLoc &DL, MVT VT,

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16203,7 +16203,6 @@ static SDValue combineXorToBitfieldInsert(SDNode *N, SelectionDAG &DAG,
1620316203
return SDValue();
1620416204

1620516205
using namespace SDPatternMatch;
16206-
1620716206
SDValue Base, Inserted;
1620816207
APInt CMask;
1620916208
if (!sd_match(N, m_Xor(m_Value(Base),
@@ -16214,7 +16213,6 @@ static SDValue combineXorToBitfieldInsert(SDNode *N, SelectionDAG &DAG,
1621416213

1621516214
if (N->getValueType(0) != MVT::i32)
1621616215
return SDValue();
16217-
1621816216
unsigned Width, ShAmt;
1621916217
if (!CMask.isShiftedMask(ShAmt, Width))
1622016218
return SDValue();
@@ -16235,10 +16233,96 @@ static SDValue combineXorToBitfieldInsert(SDNode *N, SelectionDAG &DAG,
1623516233
return DAG.getNode(RISCVISD::QC_INSB, DL, MVT::i32, Ops);
1623616234
}
1623716235

16236+
static SDValue combineOrToBitfieldInsert(SDNode *N, SelectionDAG &DAG,
16237+
const RISCVSubtarget &Subtarget) {
16238+
if (!Subtarget.hasVendorXqcibm())
16239+
return SDValue();
16240+
16241+
using namespace SDPatternMatch;
16242+
16243+
SDValue X;
16244+
APInt MaskImm;
16245+
if (!sd_match(N, m_Or(m_OneUse(m_Value(X)), m_ConstInt(MaskImm))))
16246+
return SDValue();
16247+
16248+
unsigned ShAmt, Width;
16249+
if (!MaskImm.isShiftedMask(ShAmt, Width) || MaskImm.isSignedIntN(12))
16250+
return SDValue();
16251+
16252+
if (N->getValueType(0) != MVT::i32)
16253+
return SDValue();
16254+
16255+
// If Zbs is enabled and it is a single bit set we can use BSETI which
16256+
// can be compressed to C_BSETI when Xqcibm in enabled.
16257+
if (Width == 1 && Subtarget.hasStdExtZbs())
16258+
return SDValue();
16259+
16260+
// If C1 is a shifted mask (but can't be formed as an ORI),
16261+
// use a bitfield insert of -1.
16262+
// Transform (or x, C1)
16263+
// -> (qc.insbi x, -1, width, shift)
16264+
SDLoc DL(N);
16265+
16266+
SDValue Ops[] = {X, DAG.getSignedConstant(-1, DL, MVT::i32),
16267+
DAG.getConstant(Width, DL, MVT::i32),
16268+
DAG.getConstant(ShAmt, DL, MVT::i32)};
16269+
return DAG.getNode(RISCVISD::QC_INSB, DL, MVT::i32, Ops);
16270+
}
16271+
16272+
// Generate a QC_INSB/QC_INSBI from 'or (and X, MaskImm), OrImm' iff the value
16273+
// being inserted only sets known zero bits.
16274+
static SDValue combineOrAndToBitfieldInsert(SDNode *N, SelectionDAG &DAG,
16275+
const RISCVSubtarget &Subtarget) {
16276+
// Supported only in Xqcibm for now.
16277+
if (!Subtarget.hasVendorXqcibm())
16278+
return SDValue();
16279+
16280+
using namespace SDPatternMatch;
16281+
16282+
SDValue Inserted;
16283+
APInt MaskImm, OrImm;
16284+
if (!sd_match(
16285+
N, m_SpecificVT(MVT::i32, m_Or(m_OneUse(m_And(m_Value(Inserted),
16286+
m_ConstInt(MaskImm))),
16287+
m_ConstInt(OrImm)))))
16288+
return SDValue();
16289+
16290+
// Compute the Known Zero for the AND as this allows us to catch more general
16291+
// cases than just looking for AND with imm.
16292+
KnownBits Known = DAG.computeKnownBits(N->getOperand(0));
16293+
16294+
// The bits being inserted must only set those bits that are known to be
16295+
// zero.
16296+
if (!OrImm.isSubsetOf(Known.Zero)) {
16297+
// FIXME: It's okay if the OrImm sets NotKnownZero bits to 1, but we don't
16298+
// currently handle this case.
16299+
return SDValue();
16300+
}
16301+
16302+
unsigned ShAmt, Width;
16303+
// The KnownZero mask must be a shifted mask (e.g., 1110..011, 11100..00).
16304+
if (!Known.Zero.isShiftedMask(ShAmt, Width))
16305+
return SDValue();
16306+
16307+
// QC_INSB(I) dst, src, #width, #shamt.
16308+
SDLoc DL(N);
16309+
16310+
SDValue ImmNode =
16311+
DAG.getSignedConstant(OrImm.getSExtValue() >> ShAmt, DL, MVT::i32);
16312+
16313+
SDValue Ops[] = {Inserted, ImmNode, DAG.getConstant(Width, DL, MVT::i32),
16314+
DAG.getConstant(ShAmt, DL, MVT::i32)};
16315+
return DAG.getNode(RISCVISD::QC_INSB, DL, MVT::i32, Ops);
16316+
}
16317+
1623816318
static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
1623916319
const RISCVSubtarget &Subtarget) {
1624016320
SelectionDAG &DAG = DCI.DAG;
1624116321

16322+
if (SDValue V = combineOrToBitfieldInsert(N, DAG, Subtarget))
16323+
return V;
16324+
if (SDValue V = combineOrAndToBitfieldInsert(N, DAG, Subtarget))
16325+
return V;
1624216326
if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
1624316327
return V;
1624416328
if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))

0 commit comments

Comments
 (0)