SDValue Op1 = N->getOperand(1);
// X86 can't encode an immediate LHS of a sub. See if we can push the
- // negation into a preceding instruction.
- if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op0)) {
- // If the RHS of the sub is a XOR with one use and a constant, invert the
- // immediate. Then add one to the LHS of the sub so we can turn
- // X-Y -> X+~Y+1, saving one register.
- if (Op1->hasOneUse() && Op1.getOpcode() == ISD::XOR &&
- isa<ConstantSDNode>(Op1.getOperand(1))) {
- const APInt &XorC = Op1.getConstantOperandAPInt(1);
- EVT VT = Op0.getValueType();
- SDValue NewXor = DAG.getNode(ISD::XOR, SDLoc(Op1), VT,
- Op1.getOperand(0),
- DAG.getConstant(~XorC, SDLoc(Op1), VT));
- return DAG.getNode(ISD::ADD, SDLoc(N), VT, NewXor,
- DAG.getConstant(C->getAPIntValue() + 1, SDLoc(N), VT));
- }
+ // negation into a preceding instruction. If the RHS of the sub is a XOR with
+ // one use and a constant, invert the immediate, saving one register.
+ // sub(C1, xor(X, C2)) -> add(xor(X, ~C2), C1+1)
+ if (Op1.getOpcode() == ISD::XOR && isa<ConstantSDNode>(Op0) &&
+ isa<ConstantSDNode>(Op1.getOperand(1)) && Op1->hasOneUse()) {
+ SDLoc DL(N);
+ EVT VT = Op0.getValueType();
+ SDValue NewXor = DAG.getNode(ISD::XOR, SDLoc(Op1), VT, Op1.getOperand(0),
+ DAG.getNOT(SDLoc(Op1), Op1.getOperand(1), VT));
+ SDValue NewAdd =
+ DAG.getNode(ISD::ADD, DL, VT, Op0, DAG.getConstant(1, DL, VT));
+ return DAG.getNode(ISD::ADD, DL, VT, NewXor, NewAdd);
}
// Try to synthesize horizontal subs from subs of shuffles.