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 7 define 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 20 define 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 33 define 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 46 define 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 59 define 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 72 define 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 85 define 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 98 define 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 111 define 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