/// The all-ones vector constant can be materialized using a pcmpeq instruction
/// that is commonly recognized as an idiom (has no register dependency), so
/// that's better/smaller than loading a splat 1 constant.
-static SDValue combineIncDecVector(SDNode *N, SelectionDAG &DAG) {
+static SDValue combineIncDecVector(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI) {
assert((N->getOpcode() == ISD::ADD || N->getOpcode() == ISD::SUB) &&
"Unexpected opcode for increment/decrement transform");
+ // Delay this until legalize ops to avoid interfering with early DAG combines
+ // that may expect canonical adds.
+ // FIXME: We may want to consider moving this to custom lowering or all the
+ // way to isel, but lets start here.
+ if (DCI.isBeforeLegalizeOps())
+ return SDValue();
+
// Pseudo-legality check: getOnesVector() expects one of these types, so bail
// out and wait for legalization if we have an unsupported vector length.
EVT VT = N->getValueType(0);
}
static SDValue combineAdd(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget &Subtarget) {
const SDNodeFlags Flags = N->getFlags();
if (Flags.hasVectorReduction()) {
HADDBuilder);
}
- if (SDValue V = combineIncDecVector(N, DAG))
+ if (SDValue V = combineIncDecVector(N, DAG, DCI))
return V;
return combineAddOrSubToADCOrSBB(N, DAG);
}
static SDValue combineSub(SDNode *N, SelectionDAG &DAG,
+ TargetLowering::DAGCombinerInfo &DCI,
const X86Subtarget &Subtarget) {
SDValue Op0 = N->getOperand(0);
SDValue Op1 = N->getOperand(1);
HSUBBuilder);
}
- if (SDValue V = combineIncDecVector(N, DAG))
+ if (SDValue V = combineIncDecVector(N, DAG, DCI))
return V;
// Try to create PSUBUS if SUB's argument is max/min
case ISD::BITCAST: return combineBitcast(N, DAG, DCI, Subtarget);
case X86ISD::CMOV: return combineCMov(N, DAG, DCI, Subtarget);
case X86ISD::CMP: return combineCMP(N, DAG);
- case ISD::ADD: return combineAdd(N, DAG, Subtarget);
- case ISD::SUB: return combineSub(N, DAG, Subtarget);
+ case ISD::ADD: return combineAdd(N, DAG, DCI, Subtarget);
+ case ISD::SUB: return combineSub(N, DAG, DCI, Subtarget);
case X86ISD::ADD:
case X86ISD::SUB: return combineX86AddSub(N, DAG, DCI);
case X86ISD::SBB: return combineSBB(N, DAG);
; X86-NEXT: adcl {{[0-9]+}}(%esp), %edi
; X86-NEXT: adcl {{[0-9]+}}(%esp), %edx
; X86-NEXT: adcl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT: subl $-1, %esi
-; X86-NEXT: sbbl $-1, %edi
-; X86-NEXT: sbbl $-1, %edx
-; X86-NEXT: sbbl $-1, %ecx
+; X86-NEXT: addl $1, %esi
+; X86-NEXT: adcl $0, %edi
+; X86-NEXT: adcl $0, %edx
+; X86-NEXT: adcl $0, %ecx
; X86-NEXT: movl %esi, (%eax)
; X86-NEXT: movl %edi, 4(%eax)
; X86-NEXT: movl %edx, 8(%eax)