================ @@ -8030,7 +8077,431 @@ SDValue SystemZTargetLowering::combineBSWAP( return SDValue(); } +// Combine IPM sequence for flag output operands. +static bool combineSRL_IPM_CCMask(SDValue &CCReg, int &CCValid, int &CCMask) { + // Convert CCVal to CCMask and update it along with CCValid. + const auto convertCCValToCCMask = [&CCMask, &CCValid](int CCVal) { + bool Invert = false; + if (CCMask == SystemZ::CCMASK_CMP_NE) + Invert = !Invert; + if (CCMask == SystemZ::CCMASK_CMP_EQ || CCMask == SystemZ::CCMASK_CMP_NE) { + CCMask = CCMaskForSystemZCCVal(CCVal); + if (Invert) + CCMask ^= SystemZ::CCMASK_ANY; + CCValid = SystemZ::CCMASK_ANY; + return true; + } else if (CCMask == SystemZ::CCMASK_CMP_LT) { + // CC in range [0, CCVal). + CCMask = ((~0U << (4 - CCVal)) & SystemZ::CCMASK_ANY); + CCValid = SystemZ::CCMASK_ANY; + return true; + } else if (CCMask == SystemZ::CCMASK_CMP_GT) { + // CC in range (CCVal, 3]. + CCMask = (~(~0U << (3 - CCVal))) & SystemZ::CCMASK_ANY; + CCValid = SystemZ::CCMASK_ANY; + return true; + } + return false; + }; + // Check (SRL (IPM (CC))) and update CCReg to combine. + const auto isSRL_IPM_CCSequence = [&CCReg](SDNode *N) { + if (!N || N->getOpcode() != ISD::SRL) + return false; + auto *SRLCount = dyn_cast<ConstantSDNode>(N->getOperand(1)); + if (!SRLCount || SRLCount->getZExtValue() != SystemZ::IPM_CC) + return false; + auto *IPM = N->getOperand(0).getNode(); + if (!IPM || IPM->getOpcode() != SystemZISD::IPM) + return false; + auto *IPMOp0 = IPM->getOperand(0).getNode(); + if (!IPMOp0 || IPMOp0->getNumOperands() < 2) + return false; + auto *RN = dyn_cast<RegisterSDNode>(IPMOp0->getOperand(1)); + // Check if operand 1 is SystemZ::CC. Also, it avoids srl/ipm/tbegin and + // srl/ipm/tend kind of sequences. + if (!RN || !RN->getReg().isPhysical() || RN->getReg() != SystemZ::CC) + return false; + // Return the updated CCReg link. + CCReg = IPM->getOperand(0); + return true; + }; + // Check if N has SystemZ::CC operand. + const auto isCCOperand = [](SDNode *N) { + if (!N || N->getNumOperands() < 2) + return false; + auto *RN = dyn_cast<RegisterSDNode>(N->getOperand(1)); + if (!RN || !RN->getReg().isPhysical() || RN->getReg() != SystemZ::CC) + return false; + return true; + }; + + auto *CCNode = CCReg.getNode(); + if (!CCNode) + return false; + + int RestoreCCValid = CCValid; + // Optimize (TM (IPM (CC))) + if (CCNode->getOpcode() == SystemZISD::TM) { + bool Invert = false; + if (CCMask == SystemZ::CCMASK_TM_SOME_1) + Invert = !Invert; + auto *N = CCNode->getOperand(0).getNode(); + auto Shift = dyn_cast<ConstantSDNode>(CCNode->getOperand(1)); + if (!N || !Shift) + return false; + if (N->getOpcode() == SystemZISD::IPM) { + auto ShiftVal = Shift->getZExtValue(); + if (ShiftVal == (1 << SystemZ::IPM_CC)) + CCMask = SystemZ::CCMASK_CMP_GE; + if (Invert) + CCMask ^= CCValid; + // Return the updated CCReg link. + CCReg = N->getOperand(0); + return true; + } else if (N->getOpcode() == ISD::XOR) { + // Optimize (TM (XOR (OP1 OP2))). + auto *XOROp1 = N->getOperand(0).getNode(); + auto *XOROp2 = N->getOperand(1).getNode(); + if (!XOROp1 || !XOROp2) + return false; + // OP1. (SELECT_CCMASK (ICMP (SRL (IPM (CC))))). + // OP2. (SRL (IPM (CC))). + if (XOROp1->getOpcode() == SystemZISD::SELECT_CCMASK && + isSRL_IPM_CCSequence(XOROp2)) { + auto *CCValid1 = dyn_cast<ConstantSDNode>(XOROp1->getOperand(2)); + auto *CCMask1 = dyn_cast<ConstantSDNode>(XOROp1->getOperand(3)); + SDValue XORReg = XOROp1->getOperand(4); + if (!CCValid1 || !CCMask1) + return false; + int CCValidVal = CCValid1->getZExtValue(); + int CCMaskVal = CCMask1->getZExtValue(); + if (combineSRL_IPM_CCMask(XORReg, CCValidVal, CCMaskVal)) { ---------------- uweigand wrote:
Do we really need this recursion here? It seems to me there should be some way to successively simplify subexpressions. The common code combiner logic should iterate already, no? https://github.com/llvm/llvm-project/pull/125970 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits