[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:52 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)
----------------
uweigand wrote:
We probably do not need to check operand 2 here - we only support `CCMASK_TM_ALL_0` and `CCMASK_TM_SOME_1` here, and for these, in-memory vs. in-register TM behave the same.
https://github.com/llvm/llvm-project/pull/125970
More information about the llvm-commits
mailing list