================ @@ -8695,6 +8730,106 @@ SDValue SystemZTargetLowering::combineSETCC( } static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask) { + // CCMask for ICmp is equal to 0, 1, 2 or 3. + const auto CCMaskForICmpEQCCVal = [](unsigned CC) { + assert(CC < 4 && "CC out of range"); + return 1 << (3 - CC); + }; + // Convert CCVal to CCMask based on CCMask and update it. + const auto convertCCValToCCMask = [&](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 = CCMaskForICmpEQCCVal(CCVal); + if (Invert) + CCMask ^= SystemZ::CCMASK_ANY; + return true; + } else if (CCMask == SystemZ::CCMASK_CMP_LT) { + // CC in range [0, CCVal). + CCMask = ((~0U << (4 - CCVal)) & SystemZ::CCMASK_ANY); + return true; + } else if (CCMask == SystemZ::CCMASK_CMP_GT) { + // CC in range (CCVal, 3]. + CCMask = (~(~0U << (3 - CCVal))) & 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; + CCReg = IPM->getOperand(0); + return true; + }; + + auto *CCNode = CCReg.getNode(); + if (!CCNode) + return false; + + // Optimize (TM (IPM (CC))) + if (CCNode->getOpcode() == SystemZISD::TM) { + bool Invert = false; + if (CCValid != SystemZ::CCMASK_TM) + return false; + if (CCMask == SystemZ::CCMASK_TM_SOME_1) + Invert = !Invert; + else if (CCMask != SystemZ::CCMASK_TM_ALL_0) + return false; + auto *N = CCNode->getOperand(0).getNode(); + auto *TMOp1Const = dyn_cast<ConstantSDNode>(CCNode->getOperand(1)); + auto *TMOp2Const = dyn_cast<ConstantSDNode>(CCNode->getOperand(2)); + if (!N || !TMOp1Const || !TMOp2Const || TMOp2Const->getZExtValue() != 0) + return false; + auto TMConstVal = TMOp1Const->getZExtValue(); + if (N->getOpcode() == SystemZISD::IPM) { + if (TMConstVal == (1 << SystemZ::IPM_CC)) + CCMask = SystemZ::CCMASK_CMP_GE; + else if (TMConstVal == (1 << (SystemZ::IPM_CC + 1))) + CCMask = SystemZ::CCMASK_CMP_LE; + else + return false; + if (Invert) + CCMask ^= CCValid; + // Return the updated CCReg link. + CCReg = N->getOperand(0); + return true; + } else if (N->getOpcode() == SystemZISD::SELECT_CCMASK) { + if (TMConstVal != 1) + return false; ---------------- uweigand wrote:
However, this branch doesn't look right. For one, this code does not even appear to look at the CCMask of the inner SELECT_CCMASK at all - that can't be right. Can you elaborate which transformation specifically this code is supposed to enable? 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