Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -30274,6 +30274,35 @@ EFLAGS)); } +// transforms (setcc CC, (cmp (zext:N x), const)) to (setcc CC (cmp x, const')) +// where N is some bit width greater than x's; const' has x's bit width; const +// == const' in value +static SDValue combineX86Cmp(SDNode *N, SelectionDAG &DAG, + TargetLowering::DAGCombinerInfo &DCI, + const X86Subtarget &Subtarget) { + if (N->uses().begin() != N->uses().end() && + all_of(N->uses().begin(), N->uses().end(), + [](const SDNode *user) { + X86::CondCode cc = X86::CondCode(user->getConstantOperandVal(0)); + return user->getOpcode() == X86ISD::SETCC && + (cc == X86::COND_E || cc == X86::COND_NE || + cc == X86::COND_NE || cc == X86::COND_NP || + cc == X86::COND_P); + }) && + N->getOperand(0).getOpcode() == ISD::ZERO_EXTEND) { + if (ConstantSDNode *rhs = dyn_cast(N->getOperand(1))) { + const SDValue &innerlhs = N->getOperand(0)->getOperand(0); + uint64_t rhsval = rhs->getZExtValue(); + if (isUIntN(innerlhs.getValueSizeInBits(), rhsval)) { + return DAG.getNode( + X86ISD::CMP, SDLoc(N), innerlhs.getValueType(), innerlhs, + DAG.getConstant(rhsval, SDLoc(rhs), innerlhs.getValueType())); + } + } + } + return SDValue(); +} + // Optimize RES = X86ISD::SETCC CONDCODE, EFLAG_INPUT static SDValue combineX86SetCC(SDNode *N, SelectionDAG &DAG, TargetLowering::DAGCombinerInfo &DCI, @@ -30881,6 +30910,7 @@ case ISD::SIGN_EXTEND: return combineSext(N, DAG, DCI, Subtarget); case ISD::SIGN_EXTEND_INREG: return combineSignExtendInReg(N, DAG, Subtarget); case ISD::SETCC: return combineSetCC(N, DAG, Subtarget); + case X86ISD::CMP: return combineX86Cmp(N, DAG, DCI, Subtarget); case X86ISD::SETCC: return combineX86SetCC(N, DAG, DCI, Subtarget); case X86ISD::BRCOND: return combineBrCond(N, DAG, DCI, Subtarget); case X86ISD::VZEXT: return combineVZext(N, DAG, DCI, Subtarget);