forked from OSchip/llvm-project
X86: Add a bunch of peeps for add and sub of SETB.
"b + ((a < b) ? 1 : 0)" compiles into cmpl %esi, %edi adcl $0, %esi instead of cmpl %esi, %edi sbbl %eax, %eax andl $1, %eax addl %esi, %eax This saves a register, a false dependency on %eax (Intel's CPUs still don't ignore it) and it's shorter. llvm-svn: 131070
This commit is contained in:
parent
b21c52eac8
commit
d724a590e5
|
@ -214,6 +214,30 @@ def : Pat<(i64 (sext (i8 (X86setcc_c X86_COND_B, EFLAGS)))),
|
|||
def : Pat<(and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1),
|
||||
(SETBr)>;
|
||||
|
||||
// (add OP, SETB) -> (adc OP, 0)
|
||||
def : Pat<(add (and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1), GR8:$op),
|
||||
(ADC8ri GR8:$op, 0)>;
|
||||
def : Pat<(add (and (i32 (X86setcc_c X86_COND_B, EFLAGS)), 1), GR32:$op),
|
||||
(ADC32ri8 GR32:$op, 0)>;
|
||||
def : Pat<(add (and (i64 (X86setcc_c X86_COND_B, EFLAGS)), 1), GR64:$op),
|
||||
(ADC64ri8 GR64:$op, 0)>;
|
||||
|
||||
// (sub OP, SETB) -> (sbb OP, 0)
|
||||
def : Pat<(sub GR8:$op, (and (i8 (X86setcc_c X86_COND_B, EFLAGS)), 1)),
|
||||
(SBB8ri GR8:$op, 0)>;
|
||||
def : Pat<(sub GR32:$op, (and (i32 (X86setcc_c X86_COND_B, EFLAGS)), 1)),
|
||||
(SBB32ri8 GR32:$op, 0)>;
|
||||
def : Pat<(sub GR64:$op, (and (i64 (X86setcc_c X86_COND_B, EFLAGS)), 1)),
|
||||
(SBB64ri8 GR64:$op, 0)>;
|
||||
|
||||
// (sub OP, SETCC_CARRY) -> (adc OP, 0)
|
||||
def : Pat<(sub GR8:$op, (i8 (X86setcc_c X86_COND_B, EFLAGS))),
|
||||
(ADC8ri GR8:$op, 0)>;
|
||||
def : Pat<(sub GR32:$op, (i32 (X86setcc_c X86_COND_B, EFLAGS))),
|
||||
(ADC32ri8 GR32:$op, 0)>;
|
||||
def : Pat<(sub GR64:$op, (i64 (X86setcc_c X86_COND_B, EFLAGS))),
|
||||
(ADC64ri8 GR64:$op, 0)>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// String Pseudo Instructions
|
||||
//
|
||||
|
|
|
@ -4,9 +4,9 @@
|
|||
define i32 @test1(i32 %sum, i32 %x) nounwind readnone ssp {
|
||||
entry:
|
||||
; CHECK: test1:
|
||||
; CHECK: sbbl %ecx, %ecx
|
||||
; CHECK: cmpl %ecx, %eax
|
||||
; CHECK-NOT: addl
|
||||
; CHECK: subl %ecx, %eax
|
||||
; CHECK: adcl $0, %eax
|
||||
%add4 = add i32 %x, %sum
|
||||
%cmp = icmp ult i32 %add4, %x
|
||||
%inc = zext i1 %cmp to i32
|
||||
|
@ -18,8 +18,7 @@ entry:
|
|||
; CHECK: test2:
|
||||
; CHECK: movl
|
||||
; CHECK-NEXT: addl
|
||||
; CHECK-NEXT: sbbl
|
||||
; CHECK-NEXT: subl
|
||||
; CHECK-NEXT: adcl $0
|
||||
; CHECK-NEXT: ret
|
||||
define i32 @test2(i32 %sum, i32 %x) nounwind readnone ssp {
|
||||
entry:
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
; RUN: llc -march=x86-64 < %s | FileCheck %s
|
||||
|
||||
define i8 @test1(i8 %a, i8 %b) nounwind {
|
||||
%cmp = icmp ult i8 %a, %b
|
||||
%cond = zext i1 %cmp to i8
|
||||
%add = add i8 %cond, %b
|
||||
ret i8 %add
|
||||
; CHECK: test1:
|
||||
; CHECK: adcb $0
|
||||
}
|
||||
|
||||
define i32 @test2(i32 %a, i32 %b) nounwind {
|
||||
%cmp = icmp ult i32 %a, %b
|
||||
%cond = zext i1 %cmp to i32
|
||||
%add = add i32 %cond, %b
|
||||
ret i32 %add
|
||||
; CHECK: test2:
|
||||
; CHECK: adcl $0
|
||||
}
|
||||
|
||||
define i64 @test3(i64 %a, i64 %b) nounwind {
|
||||
%cmp = icmp ult i64 %a, %b
|
||||
%conv = zext i1 %cmp to i64
|
||||
%add = add i64 %conv, %b
|
||||
ret i64 %add
|
||||
; CHECK: test3:
|
||||
; CHECK: adcq $0
|
||||
}
|
||||
|
||||
define i8 @test4(i8 %a, i8 %b) nounwind {
|
||||
%cmp = icmp ult i8 %a, %b
|
||||
%cond = zext i1 %cmp to i8
|
||||
%sub = sub i8 %b, %cond
|
||||
ret i8 %sub
|
||||
; CHECK: test4:
|
||||
; CHECK: sbbb $0
|
||||
}
|
||||
|
||||
define i32 @test5(i32 %a, i32 %b) nounwind {
|
||||
%cmp = icmp ult i32 %a, %b
|
||||
%cond = zext i1 %cmp to i32
|
||||
%sub = sub i32 %b, %cond
|
||||
ret i32 %sub
|
||||
; CHECK: test5:
|
||||
; CHECK: sbbl $0
|
||||
}
|
||||
|
||||
define i64 @test6(i64 %a, i64 %b) nounwind {
|
||||
%cmp = icmp ult i64 %a, %b
|
||||
%conv = zext i1 %cmp to i64
|
||||
%sub = sub i64 %b, %conv
|
||||
ret i64 %sub
|
||||
; CHECK: test6:
|
||||
; CHECK: sbbq $0
|
||||
}
|
||||
|
||||
define i8 @test7(i8 %a, i8 %b) nounwind {
|
||||
%cmp = icmp ult i8 %a, %b
|
||||
%cond = sext i1 %cmp to i8
|
||||
%sub = sub i8 %b, %cond
|
||||
ret i8 %sub
|
||||
; CHECK: test7:
|
||||
; CHECK: adcb $0
|
||||
}
|
||||
|
||||
define i32 @test8(i32 %a, i32 %b) nounwind {
|
||||
%cmp = icmp ult i32 %a, %b
|
||||
%cond = sext i1 %cmp to i32
|
||||
%sub = sub i32 %b, %cond
|
||||
ret i32 %sub
|
||||
; CHECK: test8:
|
||||
; CHECK: adcl $0
|
||||
}
|
||||
|
||||
define i64 @test9(i64 %a, i64 %b) nounwind {
|
||||
%cmp = icmp ult i64 %a, %b
|
||||
%conv = sext i1 %cmp to i64
|
||||
%sub = sub i64 %b, %conv
|
||||
ret i64 %sub
|
||||
; CHECK: test9:
|
||||
; CHECK: adcq $0
|
||||
}
|
Loading…
Reference in New Issue