@@ -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+
1623816318static 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