1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
3
4; These tests use cmp+adc/sbb in place of test+set+add/sub. Should this transform
5; be enabled by micro-architecture rather than as part of generic lowering/isel?
6
7define i8 @test1(i8 %a, i8 %b) nounwind {
8; CHECK-LABEL: test1:
9; CHECK:       # %bb.0:
10; CHECK-NEXT:    movl %esi, %eax
11; CHECK-NEXT:    cmpb %al, %dil
12; CHECK-NEXT:    adcb $0, %al
13; CHECK-NEXT:    # kill: def $al killed $al killed $eax
14; CHECK-NEXT:    retq
15  %cmp = icmp ult i8 %a, %b
16  %cond = zext i1 %cmp to i8
17  %add = add i8 %cond, %b
18  ret i8 %add
19}
20
21define i32 @test2(i32 %a, i32 %b) nounwind {
22; CHECK-LABEL: test2:
23; CHECK:       # %bb.0:
24; CHECK-NEXT:    movl %esi, %eax
25; CHECK-NEXT:    cmpl %esi, %edi
26; CHECK-NEXT:    adcl $0, %eax
27; CHECK-NEXT:    retq
28  %cmp = icmp ult i32 %a, %b
29  %cond = zext i1 %cmp to i32
30  %add = add i32 %cond, %b
31  ret i32 %add
32}
33
34define i64 @test3(i64 %a, i64 %b) nounwind {
35; CHECK-LABEL: test3:
36; CHECK:       # %bb.0:
37; CHECK-NEXT:    movq %rsi, %rax
38; CHECK-NEXT:    cmpq %rsi, %rdi
39; CHECK-NEXT:    adcq $0, %rax
40; CHECK-NEXT:    retq
41  %cmp = icmp ult i64 %a, %b
42  %conv = zext i1 %cmp to i64
43  %add = add i64 %conv, %b
44  ret i64 %add
45}
46
47define i8 @test4(i8 %a, i8 %b) nounwind {
48; CHECK-LABEL: test4:
49; CHECK:       # %bb.0:
50; CHECK-NEXT:    movl %esi, %eax
51; CHECK-NEXT:    cmpb %al, %dil
52; CHECK-NEXT:    sbbb $0, %al
53; CHECK-NEXT:    # kill: def $al killed $al killed $eax
54; CHECK-NEXT:    retq
55  %cmp = icmp ult i8 %a, %b
56  %cond = zext i1 %cmp to i8
57  %sub = sub i8 %b, %cond
58  ret i8 %sub
59}
60
61define i32 @test5(i32 %a, i32 %b) nounwind {
62; CHECK-LABEL: test5:
63; CHECK:       # %bb.0:
64; CHECK-NEXT:    movl %esi, %eax
65; CHECK-NEXT:    cmpl %esi, %edi
66; CHECK-NEXT:    sbbl $0, %eax
67; CHECK-NEXT:    retq
68  %cmp = icmp ult i32 %a, %b
69  %cond = zext i1 %cmp to i32
70  %sub = sub i32 %b, %cond
71  ret i32 %sub
72}
73
74define i64 @test6(i64 %a, i64 %b) nounwind {
75; CHECK-LABEL: test6:
76; CHECK:       # %bb.0:
77; CHECK-NEXT:    movq %rsi, %rax
78; CHECK-NEXT:    cmpq %rsi, %rdi
79; CHECK-NEXT:    sbbq $0, %rax
80; CHECK-NEXT:    retq
81  %cmp = icmp ult i64 %a, %b
82  %conv = zext i1 %cmp to i64
83  %sub = sub i64 %b, %conv
84  ret i64 %sub
85}
86
87define i8 @test7(i8 %a, i8 %b) nounwind {
88; CHECK-LABEL: test7:
89; CHECK:       # %bb.0:
90; CHECK-NEXT:    movl %esi, %eax
91; CHECK-NEXT:    cmpb %al, %dil
92; CHECK-NEXT:    adcb $0, %al
93; CHECK-NEXT:    # kill: def $al killed $al killed $eax
94; CHECK-NEXT:    retq
95  %cmp = icmp ult i8 %a, %b
96  %cond = sext i1 %cmp to i8
97  %sub = sub i8 %b, %cond
98  ret i8 %sub
99}
100
101define i32 @test8(i32 %a, i32 %b) nounwind {
102; CHECK-LABEL: test8:
103; CHECK:       # %bb.0:
104; CHECK-NEXT:    movl %esi, %eax
105; CHECK-NEXT:    cmpl %esi, %edi
106; CHECK-NEXT:    adcl $0, %eax
107; CHECK-NEXT:    retq
108  %cmp = icmp ult i32 %a, %b
109  %cond = sext i1 %cmp to i32
110  %sub = sub i32 %b, %cond
111  ret i32 %sub
112}
113
114define i64 @test9(i64 %a, i64 %b) nounwind {
115; CHECK-LABEL: test9:
116; CHECK:       # %bb.0:
117; CHECK-NEXT:    movq %rsi, %rax
118; CHECK-NEXT:    cmpq %rsi, %rdi
119; CHECK-NEXT:    adcq $0, %rax
120; CHECK-NEXT:    retq
121  %cmp = icmp ult i64 %a, %b
122  %conv = sext i1 %cmp to i64
123  %sub = sub i64 %b, %conv
124  ret i64 %sub
125}
126
127