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