Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -34993,6 +34993,17 @@ if (SDValue R = checkBoolTestSetCCCombine(EFLAGS, CC)) return R; + + // If this is a test of whether (add X, 1) does not produce a carry + // (COND_AE means CF == 0), that is the same as testing whether (add X, 1) + // is not zero (COND_NE). Prefer COND_NE because that is the recognized form + // for producing INC from the ADD. + if (CC == X86::COND_AE && EFLAGS.getOpcode() == X86ISD::ADD && + isOneConstant(EFLAGS.getOperand(1))) { + CC = X86::COND_NE; + return EFLAGS; + } + return combineSetCCAtomicArith(EFLAGS, CC, DAG, Subtarget); } Index: test/CodeGen/X86/slow-incdec.ll =================================================================== --- test/CodeGen/X86/slow-incdec.ll +++ test/CodeGen/X86/slow-incdec.ll @@ -58,15 +58,25 @@ declare void @other(i32* ) nounwind; define void @cond_ae_to_cond_ne(i32* %p) nounwind { -; CHECK-LABEL: cond_ae_to_cond_ne: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax -; CHECK-NEXT: addl $1, (%eax) -; CHECK-NEXT: jae .LBB4_1 -; CHECK-NEXT: # %bb.2: # %if.end4 -; CHECK-NEXT: jmp other # TAILCALL -; CHECK-NEXT: .LBB4_1: # %return -; CHECK-NEXT: retl +; INCDEC-LABEL: cond_ae_to_cond_ne: +; INCDEC: # %bb.0: # %entry +; INCDEC-NEXT: movl {{[0-9]+}}(%esp), %eax +; INCDEC-NEXT: incl (%eax) +; INCDEC-NEXT: jne .LBB4_1 +; INCDEC-NEXT: # %bb.2: # %if.end4 +; INCDEC-NEXT: jmp other # TAILCALL +; INCDEC-NEXT: .LBB4_1: # %return +; INCDEC-NEXT: retl +; +; ADD-LABEL: cond_ae_to_cond_ne: +; ADD: # %bb.0: # %entry +; ADD-NEXT: movl {{[0-9]+}}(%esp), %eax +; ADD-NEXT: addl $1, (%eax) +; ADD-NEXT: jne .LBB4_1 +; ADD-NEXT: # %bb.2: # %if.end4 +; ADD-NEXT: jmp other # TAILCALL +; ADD-NEXT: .LBB4_1: # %return +; ADD-NEXT: retl entry: %t0 = load i32, i32* %p, align 8 %add_ov = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %t0, i32 1)