================ @@ -8701,95 +8734,341 @@ SDValue SystemZTargetLowering::combineSETCC( return SDValue(); } -static bool combineCCMask(SDValue &CCReg, int &CCValid, int &CCMask) { +static std::pair<SDValue, int> findCCUse(const SDValue &Val) { + auto *N = Val.getNode(); + if (!N) + return std::make_pair(SDValue(), SystemZ::CCMASK_NONE); + switch (N->getOpcode()) { + default: + return std::make_pair(SDValue(), SystemZ::CCMASK_NONE); + case SystemZISD::IPM: + if (N->getOperand(0).getOpcode() == SystemZISD::CLC || + N->getOperand(0).getOpcode() == SystemZ::CLST || + N->getOperand(0).getOpcode() == SystemZISD::STRCMP) + return std::make_pair(N->getOperand(0), SystemZ::CCMASK_ICMP); + return std::make_pair(N->getOperand(0), SystemZ::CCMASK_ANY); + case ISD::SHL: + case ISD::SRA: + case ISD::SRL: + return findCCUse(N->getOperand(0)); + case SystemZISD::SELECT_CCMASK: { + SDValue Op4CCReg = N->getOperand(4); + auto *Op4CCNode = Op4CCReg.getNode(); + auto *CCValid = dyn_cast<ConstantSDNode>(N->getOperand(2)); + if (!CCValid || !Op4CCNode) + return std::make_pair(SDValue(), SystemZ::CCMASK_NONE); + int CCValidVal = CCValid->getZExtValue(); + if (Op4CCNode->getOpcode() == SystemZISD::ICMP || + Op4CCNode->getOpcode() == SystemZISD::TM) { + auto [OpCC, OpCCValid] = findCCUse(Op4CCNode->getOperand(0)); + if (OpCC != SDValue()) + return std::make_pair(OpCC, OpCCValid); + } + auto [OpCC, OpCCValid] = findCCUse(Op4CCReg); + return OpCC != SDValue() ? std::make_pair(OpCC, OpCCValid) + : std::make_pair(Op4CCReg, CCValidVal); + } + case ISD::ADD: + case ISD::AND: + case ISD::OR: + case ISD::XOR: + auto [Op0CC, Op0CCValid] = findCCUse(N->getOperand(0)); + if (Op0CC != SDValue()) + return std::make_pair(Op0CC, Op0CCValid); + return findCCUse(N->getOperand(1)); + } +} + +SmallVector<SDValue, 4> +SystemZTargetLowering::simplifyAssumingCCVal(SDValue &Val, SDValue &CC, + DAGCombinerInfo &DCI) const { + const auto isValidBinaryOperation = [](const SDValue &Op, SDValue &Op0, + SDValue &Op1, unsigned &Opcode) { + auto *N = Op.getNode(); + if (!N) + return false; + Opcode = N->getOpcode(); + if (Opcode != ISD::ADD && Opcode != ISD::AND && Opcode != ISD::OR && + Opcode != ISD::XOR) + return false; + Op0 = N->getOperand(0); + Op1 = N->getOperand(1); + return true; + }; + if (isa<ConstantSDNode>(Val)) { + return {Val, Val, Val, Val}; + } + auto *N = Val.getNode(), *CCNode = CC.getNode(); + if (!N || !CCNode) + return {}; + SelectionDAG &DAG = DCI.DAG; + SDLoc DL(N); + if (N->getOpcode() == SystemZISD::IPM) { + SmallVector<SDValue, 4> ShiftedCCVals; ---------------- uweigand wrote:
However, here it is critical that we verify the operand of `IPM` is actually `CCNode`, or else we mistakenly accept wrong code. 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