forked from OSchip/llvm-project
[X86] Lower ISD::UADDO to use the Z flag instead of C flag when the RHS is a constant 1 to encourage INC formation.
Summary: Add an additional combine to combineCarryThroughADD to reverse it back to the C flag to avoid regressions. I believe this catches the cases that D57547 got. Reviewers: RKSimon, spatel Reviewed By: spatel Subscribers: javed.absar, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D57637 llvm-svn: 352984
This commit is contained in:
parent
365e164fcc
commit
950ca192f6
|
@ -20030,7 +20030,7 @@ getX86XALUOOp(X86::CondCode &Cond, SDValue Op, SelectionDAG &DAG) {
|
|||
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 @@ static SDValue combineCarryThroughADD(SDValue EFLAGS, SelectionDAG &DAG) {
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,9 +42,7 @@ define void @test_0(i64*, i64*) {
|
|||
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
|
||||
|
|
|
@ -77,9 +77,9 @@ define <8 x i16> @combine_constfold_undef_v8i16() {
|
|||
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
|
||||
|
|
|
@ -691,8 +691,8 @@ define i64 @test4(i64 %a, i64 %b) nounwind {
|
|||
; 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 @@ define i64 @test4(i64 %a, i64 %b) nounwind {
|
|||
; 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 @@ define i64 @test4(i64 %a, i64 %b) nounwind {
|
|||
; 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 @@ define i64 @test4(i64 %a, i64 %b) nounwind {
|
|||
; 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 @@ define i64 @test4(i64 %a, i64 %b) nounwind {
|
|||
; 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
|
||||
|
|
|
@ -58,15 +58,25 @@ declare {i32, i1} @llvm.uadd.with.overflow.i32(i32, i32)
|
|||
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 void @external_b()
|
|||
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)
|
||||
|
|
|
@ -366,8 +366,8 @@ define zeroext i1 @uaddoi64(i64 %v1, i64 %v2, i64* %res) {
|
|||
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 @uaddoinci8(i8 %v1, i8* %res) {
|
|||
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 @uaddoinci16(i16 %v1, i16* %res) {
|
|||
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 @uaddoinci32(i32 %v1, i32* %res) {
|
|||
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
|
||||
;
|
||||
|
|
Loading…
Reference in New Issue