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: cmpb %sil, %dil 11; CHECK-NEXT: adcb $0, %sil 12; CHECK-NEXT: movl %esi, %eax 13; CHECK-NEXT: retq 14 %cmp = icmp ult i8 %a, %b 15 %cond = zext i1 %cmp to i8 16 %add = add i8 %cond, %b 17 ret i8 %add 18} 19 20define i32 @test2(i32 %a, i32 %b) nounwind { 21; CHECK-LABEL: test2: 22; CHECK: # %bb.0: 23; CHECK-NEXT: cmpl %esi, %edi 24; CHECK-NEXT: adcl $0, %esi 25; CHECK-NEXT: movl %esi, %eax 26; CHECK-NEXT: retq 27 %cmp = icmp ult i32 %a, %b 28 %cond = zext i1 %cmp to i32 29 %add = add i32 %cond, %b 30 ret i32 %add 31} 32 33define i64 @test3(i64 %a, i64 %b) nounwind { 34; CHECK-LABEL: test3: 35; CHECK: # %bb.0: 36; CHECK-NEXT: cmpq %rsi, %rdi 37; CHECK-NEXT: adcq $0, %rsi 38; CHECK-NEXT: movq %rsi, %rax 39; CHECK-NEXT: retq 40 %cmp = icmp ult i64 %a, %b 41 %conv = zext i1 %cmp to i64 42 %add = add i64 %conv, %b 43 ret i64 %add 44} 45 46define i8 @test4(i8 %a, i8 %b) nounwind { 47; CHECK-LABEL: test4: 48; CHECK: # %bb.0: 49; CHECK-NEXT: cmpb %sil, %dil 50; CHECK-NEXT: sbbb $0, %sil 51; CHECK-NEXT: movl %esi, %eax 52; CHECK-NEXT: retq 53 %cmp = icmp ult i8 %a, %b 54 %cond = zext i1 %cmp to i8 55 %sub = sub i8 %b, %cond 56 ret i8 %sub 57} 58 59define i32 @test5(i32 %a, i32 %b) nounwind { 60; CHECK-LABEL: test5: 61; CHECK: # %bb.0: 62; CHECK-NEXT: cmpl %esi, %edi 63; CHECK-NEXT: sbbl $0, %esi 64; CHECK-NEXT: movl %esi, %eax 65; CHECK-NEXT: retq 66 %cmp = icmp ult i32 %a, %b 67 %cond = zext i1 %cmp to i32 68 %sub = sub i32 %b, %cond 69 ret i32 %sub 70} 71 72define i64 @test6(i64 %a, i64 %b) nounwind { 73; CHECK-LABEL: test6: 74; CHECK: # %bb.0: 75; CHECK-NEXT: cmpq %rsi, %rdi 76; CHECK-NEXT: sbbq $0, %rsi 77; CHECK-NEXT: movq %rsi, %rax 78; CHECK-NEXT: retq 79 %cmp = icmp ult i64 %a, %b 80 %conv = zext i1 %cmp to i64 81 %sub = sub i64 %b, %conv 82 ret i64 %sub 83} 84 85define i8 @test7(i8 %a, i8 %b) nounwind { 86; CHECK-LABEL: test7: 87; CHECK: # %bb.0: 88; CHECK-NEXT: cmpb %sil, %dil 89; CHECK-NEXT: adcb $0, %sil 90; CHECK-NEXT: movl %esi, %eax 91; CHECK-NEXT: retq 92 %cmp = icmp ult i8 %a, %b 93 %cond = sext i1 %cmp to i8 94 %sub = sub i8 %b, %cond 95 ret i8 %sub 96} 97 98define i32 @test8(i32 %a, i32 %b) nounwind { 99; CHECK-LABEL: test8: 100; CHECK: # %bb.0: 101; CHECK-NEXT: cmpl %esi, %edi 102; CHECK-NEXT: adcl $0, %esi 103; CHECK-NEXT: movl %esi, %eax 104; CHECK-NEXT: retq 105 %cmp = icmp ult i32 %a, %b 106 %cond = sext i1 %cmp to i32 107 %sub = sub i32 %b, %cond 108 ret i32 %sub 109} 110 111define i64 @test9(i64 %a, i64 %b) nounwind { 112; CHECK-LABEL: test9: 113; CHECK: # %bb.0: 114; CHECK-NEXT: cmpq %rsi, %rdi 115; CHECK-NEXT: adcq $0, %rsi 116; CHECK-NEXT: movq %rsi, %rax 117; CHECK-NEXT: retq 118 %cmp = icmp ult i64 %a, %b 119 %conv = sext i1 %cmp to i64 120 %sub = sub i64 %b, %conv 121 ret i64 %sub 122} 123 124