================
@@ -8694,66 +8726,455 @@ SDValue SystemZTargetLowering::combineSETCC(
   return SDValue();
 }
 
+// Combine IPM sequence for flag output operands.
 static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask) {
-  // We have a SELECT_CCMASK or BR_CCMASK comparing the condition code
-  // set by the CCReg instruction using the CCValid / CCMask masks,
-  // If the CCReg instruction is itself a ICMP testing the condition
-  // code set by some other instruction, see whether we can directly
-  // use that condition code.
-
-  // Verify that we have an ICMP against some constant.
-  if (CCValid != SystemZ::CCMASK_ICMP)
-    return false;
-  auto *ICmp = CCReg.getNode();
-  if (ICmp->getOpcode() != SystemZISD::ICMP)
+  // 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 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;
-  auto *CompareLHS = ICmp->getOperand(0).getNode();
-  auto *CompareRHS = dyn_cast<ConstantSDNode>(ICmp->getOperand(1));
-  if (!CompareRHS)
+  };
+  // 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;
+  };
+  // Check if select_cc has already been combined and uses the same ipm/cc
+  // as CCOp and return evaluated mask CCMaskVal. (SELECT_CCMASK (CC)).
+  const auto isSameCCIPMOp = [](SDValue &CCOp, SDNode *N, int &CCValidVal,
+                                int &CCMaskVal) {
+    if (!N || N->getOpcode() != SystemZISD::SELECT_CCMASK)
+      return false;
+    auto *CCValidNode = dyn_cast<ConstantSDNode>(N->getOperand(2));
+    auto *CCMaskNode = dyn_cast<ConstantSDNode>(N->getOperand(3));
+    if (!CCValidNode || !CCMaskNode)
+      return false;
+
+    CCValidVal = CCValidNode->getZExtValue();
+    // Already been combined.
+    if (CCValidVal != SystemZ::CCMASK_ANY)
+      return false;
+    CCMaskVal = CCMaskNode->getZExtValue();
+    SDValue CCRegOp = N->getOperand(4);
+    auto *CCOpNode = CCOp.getNode(), *CCRegOpNode = CCRegOp.getNode();
+    // Uses the same ipm/cc.
+    return CCOpNode && CCRegOpNode && CCOpNode == CCRegOpNode;
+  };
+  auto *CCNode = CCReg.getNode();
+  if (!CCNode)
     return false;
 
-  // Optimize the case where CompareLHS is a SELECT_CCMASK.
-  if (CompareLHS->getOpcode() == SystemZISD::SELECT_CCMASK) {
-    // Verify that we have an appropriate mask for a EQ or NE comparison.
+  // Optimize (TM (IPM (CC)))
----------------
uweigand wrote:

Adding a case to optimize (TM (IPM)) in addition to (ICMP (IPM)) does make 
sense in general.  However, you need to take care that the optimization is 
correct for *all possible* inputs to TM, not just the ones the come up in the 
"good case" you're looking at.  That doesn't appear to be the case here.

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