================
@@ -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

Reply via email to