[clang] [llvm] Add support for flag output operand "=@cc" for SystemZ. (PR #125970)
Ulrich Weigand via llvm-commits
llvm-commits at lists.llvm.org
Mon Jul 7 06:40:54 PDT 2025
================
@@ -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
More information about the llvm-commits
mailing list