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;
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;
}
}
}
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
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
; 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
; 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
; 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
; 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
; 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
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)
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)
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
;
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
;
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
;
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
;