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