Index: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp @@ -20030,7 +20030,7 @@ break; case ISD::UADDO: BaseOp = X86ISD::ADD; - Cond = X86::COND_B; + Cond = isOneConstant(RHS) ? X86::COND_E : X86::COND_B; break; case ISD::SSUBO: BaseOp = X86ISD::SUB; @@ -35058,6 +35058,12 @@ return SDValue(SubCommute.getNode(), CarryOp1.getResNo()); } } + // If this is a check of the z flag of an add with 1, switch to the + // C flag. + if (CarryCC == X86::COND_E && + CarryOp1.getOpcode() == X86ISD::ADD && + isOneConstant(CarryOp1.getOperand(1))) + return CarryOp1; } } } Index: llvm/trunk/test/CodeGen/X86/codegen-prepare-uaddo.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/codegen-prepare-uaddo.ll +++ llvm/trunk/test/CodeGen/X86/codegen-prepare-uaddo.ll @@ -42,9 +42,7 @@ define void @test_1(i64*, i64*) { ; CHECK-LABEL: test_1: ; CHECK: # %bb.0: -; CHECK-NEXT: incq (%rdi) -; CHECK-NEXT: sete %al -; CHECK-NEXT: addb $-1, %al +; CHECK-NEXT: addq $1, (%rdi) ; CHECK-NEXT: adcq $0, (%rsi) ; CHECK-NEXT: retq %3 = load i64, i64* %0, align 8 Index: llvm/trunk/test/CodeGen/X86/combine-add-usat.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/combine-add-usat.ll +++ llvm/trunk/test/CodeGen/X86/combine-add-usat.ll @@ -77,9 +77,9 @@ define i32 @combine_constant_i32(i32 %a0) { ; CHECK-LABEL: combine_constant_i32: ; CHECK: # %bb.0: -; CHECK-NEXT: addl $1, %edi +; CHECK-NEXT: incl %edi ; CHECK-NEXT: movl $-1, %eax -; CHECK-NEXT: cmovael %edi, %eax +; CHECK-NEXT: cmovnel %edi, %eax ; CHECK-NEXT: retq %1 = call i32 @llvm.uadd.sat.i32(i32 1, i32 %a0) ret i32 %1 Index: llvm/trunk/test/CodeGen/X86/scheduler-backtracking.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/scheduler-backtracking.ll +++ llvm/trunk/test/CodeGen/X86/scheduler-backtracking.ll @@ -691,8 +691,8 @@ ; ILP: # %bb.0: ; ILP-NEXT: xorl %ecx, %ecx ; ILP-NEXT: xorl %edx, %edx -; ILP-NEXT: addq $1, %rsi -; ILP-NEXT: setb %dl +; ILP-NEXT: incq %rsi +; ILP-NEXT: sete %dl ; ILP-NEXT: movl $2, %eax ; ILP-NEXT: cmpq %rdi, %rsi ; ILP-NEXT: sbbq $0, %rdx @@ -708,8 +708,8 @@ ; HYBRID: # %bb.0: ; HYBRID-NEXT: xorl %eax, %eax ; HYBRID-NEXT: xorl %ecx, %ecx -; HYBRID-NEXT: addq $1, %rsi -; HYBRID-NEXT: setb %cl +; HYBRID-NEXT: incq %rsi +; HYBRID-NEXT: sete %cl ; HYBRID-NEXT: cmpq %rdi, %rsi ; HYBRID-NEXT: sbbq $0, %rcx ; HYBRID-NEXT: movl $0, %ecx @@ -725,8 +725,8 @@ ; BURR: # %bb.0: ; BURR-NEXT: xorl %eax, %eax ; BURR-NEXT: xorl %ecx, %ecx -; BURR-NEXT: addq $1, %rsi -; BURR-NEXT: setb %cl +; BURR-NEXT: incq %rsi +; BURR-NEXT: sete %cl ; BURR-NEXT: cmpq %rdi, %rsi ; BURR-NEXT: sbbq $0, %rcx ; BURR-NEXT: movl $0, %ecx @@ -741,8 +741,8 @@ ; SRC-LABEL: test4: ; SRC: # %bb.0: ; SRC-NEXT: xorl %eax, %eax -; SRC-NEXT: addq $1, %rsi -; SRC-NEXT: setb %al +; SRC-NEXT: incq %rsi +; SRC-NEXT: sete %al ; SRC-NEXT: xorl %ecx, %ecx ; SRC-NEXT: cmpq %rdi, %rsi ; SRC-NEXT: sbbq $0, %rax @@ -760,8 +760,8 @@ ; LIN-NEXT: movl $2, %eax ; LIN-NEXT: xorl %ecx, %ecx ; LIN-NEXT: xorl %edx, %edx -; LIN-NEXT: addq $1, %rsi -; LIN-NEXT: setb %dl +; LIN-NEXT: incq %rsi +; LIN-NEXT: sete %dl ; LIN-NEXT: cmpq %rdi, %rsi ; LIN-NEXT: sbbq $0, %rdx ; LIN-NEXT: movl $0, %edx Index: llvm/trunk/test/CodeGen/X86/slow-incdec.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/slow-incdec.ll +++ llvm/trunk/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) @@ -91,19 +101,33 @@ declare {i8, i1} @llvm.uadd.with.overflow.i8(i8, i8) define void @test_tail_call(i32* %ptr) nounwind { -; CHECK-LABEL: test_tail_call: -; CHECK: # %bb.0: # %entry -; CHECK-NEXT: movl {{[0-9]+}}(%esp), %eax -; CHECK-NEXT: addl $1, (%eax) -; CHECK-NEXT: setae %al -; CHECK-NEXT: addb $1, a -; CHECK-NEXT: setb d -; CHECK-NEXT: testb %al, %al -; CHECK-NEXT: jne .LBB5_2 -; CHECK-NEXT: # %bb.1: # %then -; CHECK-NEXT: jmp external_a # TAILCALL -; CHECK-NEXT: .LBB5_2: # %else -; CHECK-NEXT: jmp external_b # TAILCALL +; INCDEC-LABEL: test_tail_call: +; INCDEC: # %bb.0: # %entry +; INCDEC-NEXT: movl {{[0-9]+}}(%esp), %eax +; INCDEC-NEXT: incl (%eax) +; INCDEC-NEXT: setne %al +; INCDEC-NEXT: incb a +; INCDEC-NEXT: sete d +; INCDEC-NEXT: testb %al, %al +; INCDEC-NEXT: jne .LBB5_2 +; INCDEC-NEXT: # %bb.1: # %then +; INCDEC-NEXT: jmp external_a # TAILCALL +; INCDEC-NEXT: .LBB5_2: # %else +; INCDEC-NEXT: jmp external_b # TAILCALL +; +; ADD-LABEL: test_tail_call: +; ADD: # %bb.0: # %entry +; ADD-NEXT: movl {{[0-9]+}}(%esp), %eax +; ADD-NEXT: addl $1, (%eax) +; ADD-NEXT: setne %al +; ADD-NEXT: addb $1, a +; ADD-NEXT: sete d +; ADD-NEXT: testb %al, %al +; ADD-NEXT: jne .LBB5_2 +; ADD-NEXT: # %bb.1: # %then +; ADD-NEXT: jmp external_a # TAILCALL +; ADD-NEXT: .LBB5_2: # %else +; ADD-NEXT: jmp external_b # TAILCALL entry: %val = load i32, i32* %ptr %add_ov = call {i32, i1} @llvm.uadd.with.overflow.i32(i32 %val, i32 1) Index: llvm/trunk/test/CodeGen/X86/xaluo.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/xaluo.ll +++ llvm/trunk/test/CodeGen/X86/xaluo.ll @@ -366,8 +366,8 @@ define zeroext i1 @uaddoinci8(i8 %v1, i8* %res) { ; SDAG-LABEL: uaddoinci8: ; SDAG: ## %bb.0: -; SDAG-NEXT: addb $1, %dil -; SDAG-NEXT: setb %al +; SDAG-NEXT: incb %dil +; SDAG-NEXT: sete %al ; SDAG-NEXT: movb %dil, (%rsi) ; SDAG-NEXT: retq ; @@ -389,8 +389,8 @@ define zeroext i1 @uaddoinci16(i16 %v1, i16* %res) { ; SDAG-LABEL: uaddoinci16: ; SDAG: ## %bb.0: -; SDAG-NEXT: addw $1, %di -; SDAG-NEXT: setb %al +; SDAG-NEXT: incw %di +; SDAG-NEXT: sete %al ; SDAG-NEXT: movw %di, (%rsi) ; SDAG-NEXT: retq ; @@ -412,8 +412,8 @@ define zeroext i1 @uaddoinci32(i32 %v1, i32* %res) { ; SDAG-LABEL: uaddoinci32: ; SDAG: ## %bb.0: -; SDAG-NEXT: addl $1, %edi -; SDAG-NEXT: setb %al +; SDAG-NEXT: incl %edi +; SDAG-NEXT: sete %al ; SDAG-NEXT: movl %edi, (%rsi) ; SDAG-NEXT: retq ; @@ -435,8 +435,8 @@ define zeroext i1 @uaddoinci64(i64 %v1, i64* %res) { ; SDAG-LABEL: uaddoinci64: ; SDAG: ## %bb.0: -; SDAG-NEXT: addq $1, %rdi -; SDAG-NEXT: setb %al +; SDAG-NEXT: incq %rdi +; SDAG-NEXT: sete %al ; SDAG-NEXT: movq %rdi, (%rsi) ; SDAG-NEXT: retq ;