@@ -15628,11 +15628,80 @@ SDValue convertTwoLoadsAndCmpToVCMPEQUB(SelectionDAG &DAG, SDNode *N,
1562815628 CC == ISD::SETNE ? ISD::SETEQ : ISD::SETNE);
1562915629}
1563015630
15631+ // Detect whether there is a pattern like (setcc (and X, 1), 0, eq).
15632+ // If it is , return true; otherwise return false.
15633+ static bool canConvertSETCCToXori(SDNode *N) {
15634+ assert(N->getOpcode() == ISD::SETCC && "Should be SETCC SDNode here.");
15635+
15636+ ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
15637+ if (CC != ISD::SETEQ)
15638+ return false;
15639+
15640+ SDValue LHS = N->getOperand(0);
15641+ SDValue RHS = N->getOperand(1);
15642+
15643+ // Check the `SDValue &V` is from `and` with `1`.
15644+ auto IsAndWithOne = [](SDValue &V) {
15645+ if (V.getOpcode() == ISD::AND) {
15646+ for (const SDValue &Op : V->ops())
15647+ if (auto *C = dyn_cast<ConstantSDNode>(Op))
15648+ if (C->isOne())
15649+ return true;
15650+ }
15651+ return false;
15652+ };
15653+
15654+ // Check whether the SETCC compare with zero.
15655+ auto IsCompareWithZero = [](SDValue &V) {
15656+ if (auto *C = dyn_cast<ConstantSDNode>(V))
15657+ if (C->isZero())
15658+ return true;
15659+ return false;
15660+ };
15661+
15662+ return (IsAndWithOne(LHS) && IsCompareWithZero(RHS)) ||
15663+ (IsAndWithOne(RHS) && IsCompareWithZero(LHS));
15664+ }
15665+
15666+ // You must check whether the `SDNode* N` can be converted to Xori using
15667+ // the function `static bool canConvertSETCCToXori(SDNode *N)`
15668+ // before calling the function; otherwise, it may produce incorrect results.
15669+ static SDValue ConvertSETCCToXori(SDNode *N, SelectionDAG &DAG) {
15670+
15671+ assert(N->getOpcode() == ISD::SETCC && "Should be SETCC SDNode here.");
15672+ SDValue LHS = N->getOperand(0);
15673+ SDValue RHS = N->getOperand(1);
15674+ SDLoc DL(N);
15675+
15676+ ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
15677+ assert((CC == ISD::SETEQ) && "CC must be ISD::SETEQ.");
15678+ // Rewrite it as XORI (and X, 1), 1.
15679+ auto MakeXor1 = [&](SDValue V) {
15680+ EVT VT = V.getValueType();
15681+ SDValue One = DAG.getConstant(1, DL, VT);
15682+ SDValue Xor = DAG.getNode(ISD::XOR, DL, VT, V, One);
15683+ return DAG.getNode(ISD::TRUNCATE, DL, MVT::i1, Xor);
15684+ };
15685+
15686+ if (LHS.getOpcode() == ISD::AND && RHS.getOpcode() != ISD::AND)
15687+ return MakeXor1(LHS);
15688+
15689+ if (RHS.getOpcode() == ISD::AND && LHS.getOpcode() != ISD::AND)
15690+ return MakeXor1(RHS);
15691+
15692+ llvm_unreachable("Should not reach here.");
15693+ }
15694+
1563115695SDValue PPCTargetLowering::combineSetCC(SDNode *N,
1563215696 DAGCombinerInfo &DCI) const {
1563315697 assert(N->getOpcode() == ISD::SETCC &&
1563415698 "Should be called with a SETCC node");
1563515699
15700+ // Check if the pattern (setcc (and X, 1), 0, eq) is present.
15701+ // If it is, rewrite it as XORI (and X, 1), 1.
15702+ if (canConvertSETCCToXori(N))
15703+ return ConvertSETCCToXori(N, DCI.DAG);
15704+
1563615705 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
1563715706 if (CC == ISD::SETNE || CC == ISD::SETEQ) {
1563815707 SDValue LHS = N->getOperand(0);
0 commit comments