@@ -53739,36 +53739,47 @@ static SDValue combineLRINT_LLRINT(SDNode *N, SelectionDAG &DAG,
5373953739// cases.
5374053740static SDValue combinei64TruncSrlBinop(SDValue N, EVT VT, SelectionDAG &DAG,
5374153741 const SDLoc &DL) {
53742- using namespace llvm::SDPatternMatch;
5374353742
53744- SDValue BinopLhs;
53745- APInt BinopConst, SrlConst;
53746- if (VT != MVT::i32 ||
53747- !sd_match(
53748- N,
53749- m_AllOf(m_SpecificVT(MVT::i64),
53750- m_Srl(m_OneUse(m_AnyOf(
53751- m_Add(m_Value(BinopLhs), m_ConstInt(BinopConst)),
53752- m_Or(m_Value(BinopLhs), m_ConstInt(BinopConst)),
53753- m_Xor(m_Value(BinopLhs), m_ConstInt(BinopConst)))),
53754- m_ConstInt(SrlConst)))))
53755- return SDValue();
53743+ SDValue Binop = N.getOperand(0);
53744+ APInt BinopConst = Binop.getConstantOperandAPInt(1);
53745+ APInt SrlConst = N.getConstantOperandAPInt(1);
53746+ unsigned Opcode = Binop.getOpcode();
53747+
53748+ auto CleanUpFn = +[](SDValue Op, EVT CleanUpVT, EVT VT, SelectionDAG &DAG,
53749+ const SDLoc &DL) {
53750+ SDValue CleanUp = DAG.getAnyExtOrTrunc(Op, DL, CleanUpVT);
53751+ return DAG.getAnyExtOrTrunc(CleanUp, DL, VT);
53752+ };
53753+ auto ZeroExtCleanUp = +[](SDValue Op, EVT CleanUpVT, EVT VT,
53754+ SelectionDAG &DAG, const SDLoc &DL) {
53755+ return DAG.getZeroExtendInReg(Op, DL, CleanUpVT);
53756+ };
5375653757
53757- if (SrlConst.ule(32) || BinopConst.countr_zero() < SrlConst.getZExtValue())
53758+ switch (Opcode) {
53759+ default:
5375853760 return SDValue();
53761+ case ISD::ADD:
53762+ if (BinopConst.countr_zero() < SrlConst.getZExtValue())
53763+ return SDValue();
53764+ CleanUpFn = ZeroExtCleanUp;
53765+ [[fallthrough]];
53766+ case ISD::OR:
53767+ case ISD::XOR:
53768+ if (SrlConst.ule(32))
53769+ return SDValue();
53770+ break;
53771+ }
5375953772
5376053773 SDValue BinopLHSSrl =
53761- DAG.getNode(ISD::SRL, DL, MVT::i64, BinopLhs , N.getOperand(1));
53774+ DAG.getNode(ISD::SRL, DL, MVT::i64, Binop.getOperand(0) , N.getOperand(1));
5376253775 SDValue Trunc = DAG.getNode(ISD::TRUNCATE, DL, VT, BinopLHSSrl);
5376353776
5376453777 APInt NewBinopConstVal = BinopConst.lshr(SrlConst).trunc(VT.getSizeInBits());
5376553778 SDValue NewBinopConst = DAG.getConstant(NewBinopConstVal, DL, VT);
53766- SDValue NewBinopNode =
53767- DAG.getNode(N.getOperand(0).getOpcode(), DL, VT, Trunc, NewBinopConst);
53768-
53779+ SDValue NewBinopNode = DAG.getNode(Opcode, DL, VT, Trunc, NewBinopConst);
5376953780 EVT CleanUpVT =
5377053781 EVT::getIntegerVT(*DAG.getContext(), 64 - SrlConst.getZExtValue());
53771- return DAG.getZeroExtendInReg (NewBinopNode, DL, CleanUpVT );
53782+ return CleanUpFn (NewBinopNode, CleanUpVT, VT, DAG, DL );
5377253783}
5377353784
5377453785/// Attempt to pre-truncate inputs to arithmetic ops if it will simplify
@@ -53816,8 +53827,14 @@ static SDValue combineTruncatedArithmetic(SDNode *N, SelectionDAG &DAG,
5381653827 if (!Src.hasOneUse())
5381753828 return SDValue();
5381853829
53819- if (SDValue R = combinei64TruncSrlBinop(Src, VT, DAG, DL))
53820- return R;
53830+ if (VT == MVT::i32 && SrcVT == MVT::i64 && SrcOpcode == ISD::SRL &&
53831+ Src.getOperand(0).getNumOperands() == 2 &&
53832+ isa<ConstantSDNode>(Src.getOperand(1)) &&
53833+ isa<ConstantSDNode>(Src.getOperand(0).getOperand(1))) {
53834+ if (SDValue R = combinei64TruncSrlBinop(Src, VT, DAG, DL))
53835+ return R;
53836+ return SDValue();
53837+ }
5382153838
5382253839 if (!VT.isVector())
5382353840 return SDValue();
0 commit comments