1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s 3 4define i32 @test_add_1_cmov_slt(i64* %p, i32 %a0, i32 %a1) #0 { 5; CHECK-LABEL: test_add_1_cmov_slt: 6; CHECK: # BB#0: # %entry 7; CHECK-NEXT: lock incq (%rdi) 8; CHECK-NEXT: cmovgl %edx, %esi 9; CHECK-NEXT: movl %esi, %eax 10; CHECK-NEXT: retq 11entry: 12 %tmp0 = atomicrmw add i64* %p, i64 1 seq_cst 13 %tmp1 = icmp slt i64 %tmp0, 0 14 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a1 15 ret i32 %tmp2 16} 17 18define i32 @test_add_1_cmov_sge(i64* %p, i32 %a0, i32 %a1) #0 { 19; CHECK-LABEL: test_add_1_cmov_sge: 20; CHECK: # BB#0: # %entry 21; CHECK-NEXT: lock incq (%rdi) 22; CHECK-NEXT: cmovlel %edx, %esi 23; CHECK-NEXT: movl %esi, %eax 24; CHECK-NEXT: retq 25entry: 26 %tmp0 = atomicrmw add i64* %p, i64 1 seq_cst 27 %tmp1 = icmp sge i64 %tmp0, 0 28 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a1 29 ret i32 %tmp2 30} 31 32define i32 @test_sub_1_cmov_sle(i64* %p, i32 %a0, i32 %a1) #0 { 33; CHECK-LABEL: test_sub_1_cmov_sle: 34; CHECK: # BB#0: # %entry 35; CHECK-NEXT: lock decq (%rdi) 36; CHECK-NEXT: cmovgel %edx, %esi 37; CHECK-NEXT: movl %esi, %eax 38; CHECK-NEXT: retq 39entry: 40 %tmp0 = atomicrmw sub i64* %p, i64 1 seq_cst 41 %tmp1 = icmp sle i64 %tmp0, 0 42 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a1 43 ret i32 %tmp2 44} 45 46define i32 @test_sub_1_cmov_sgt(i64* %p, i32 %a0, i32 %a1) #0 { 47; CHECK-LABEL: test_sub_1_cmov_sgt: 48; CHECK: # BB#0: # %entry 49; CHECK-NEXT: lock decq (%rdi) 50; CHECK-NEXT: cmovll %edx, %esi 51; CHECK-NEXT: movl %esi, %eax 52; CHECK-NEXT: retq 53entry: 54 %tmp0 = atomicrmw sub i64* %p, i64 1 seq_cst 55 %tmp1 = icmp sgt i64 %tmp0, 0 56 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a1 57 ret i32 %tmp2 58} 59 60; FIXME: (setcc slt x, 0) gets combined into shr early. 61define i8 @test_add_1_setcc_slt(i64* %p) #0 { 62; CHECK-LABEL: test_add_1_setcc_slt: 63; CHECK: # BB#0: # %entry 64; CHECK-NEXT: movl $1, %eax 65; CHECK-NEXT: lock xaddq %rax, (%rdi) 66; CHECK-NEXT: shrq $63, %rax 67; CHECK-NEXT: # kill: %AL<def> %AL<kill> %RAX<kill> 68; CHECK-NEXT: retq 69entry: 70 %tmp0 = atomicrmw add i64* %p, i64 1 seq_cst 71 %tmp1 = icmp slt i64 %tmp0, 0 72 %tmp2 = zext i1 %tmp1 to i8 73 ret i8 %tmp2 74} 75 76define i8 @test_sub_1_setcc_sgt(i64* %p) #0 { 77; CHECK-LABEL: test_sub_1_setcc_sgt: 78; CHECK: # BB#0: # %entry 79; CHECK-NEXT: lock decq (%rdi) 80; CHECK-NEXT: setge %al 81; CHECK-NEXT: retq 82entry: 83 %tmp0 = atomicrmw sub i64* %p, i64 1 seq_cst 84 %tmp1 = icmp sgt i64 %tmp0, 0 85 %tmp2 = zext i1 %tmp1 to i8 86 ret i8 %tmp2 87} 88 89define i32 @test_add_1_brcond_sge(i64* %p, i32 %a0, i32 %a1) #0 { 90; CHECK-LABEL: test_add_1_brcond_sge: 91; CHECK: # BB#0: # %entry 92; CHECK-NEXT: lock incq (%rdi) 93; CHECK-NEXT: jle .LBB6_2 94; CHECK-NEXT: # BB#1: # %t 95; CHECK-NEXT: movl %esi, %eax 96; CHECK-NEXT: retq 97; CHECK-NEXT: .LBB6_2: # %f 98; CHECK-NEXT: movl %edx, %eax 99; CHECK-NEXT: retq 100entry: 101 %tmp0 = atomicrmw add i64* %p, i64 1 seq_cst 102 %tmp1 = icmp sge i64 %tmp0, 0 103 br i1 %tmp1, label %t, label %f 104t: 105 ret i32 %a0 106f: 107 ret i32 %a1 108} 109 110; Also make sure we don't muck with condition codes that we should ignore. 111; No need to test unsigned comparisons, as they should all be simplified. 112 113define i32 @test_add_1_cmov_sle(i64* %p, i32 %a0, i32 %a1) #0 { 114; CHECK-LABEL: test_add_1_cmov_sle: 115; CHECK: # BB#0: # %entry 116; CHECK-NEXT: movl $1, %eax 117; CHECK-NEXT: lock xaddq %rax, (%rdi) 118; CHECK-NEXT: testq %rax, %rax 119; CHECK-NEXT: cmovgl %edx, %esi 120; CHECK-NEXT: movl %esi, %eax 121; CHECK-NEXT: retq 122entry: 123 %tmp0 = atomicrmw add i64* %p, i64 1 seq_cst 124 %tmp1 = icmp sle i64 %tmp0, 0 125 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a1 126 ret i32 %tmp2 127} 128 129define i32 @test_add_1_cmov_sgt(i64* %p, i32 %a0, i32 %a1) #0 { 130; CHECK-LABEL: test_add_1_cmov_sgt: 131; CHECK: # BB#0: # %entry 132; CHECK-NEXT: movl $1, %eax 133; CHECK-NEXT: lock xaddq %rax, (%rdi) 134; CHECK-NEXT: testq %rax, %rax 135; CHECK-NEXT: cmovlel %edx, %esi 136; CHECK-NEXT: movl %esi, %eax 137; CHECK-NEXT: retq 138entry: 139 %tmp0 = atomicrmw add i64* %p, i64 1 seq_cst 140 %tmp1 = icmp sgt i64 %tmp0, 0 141 %tmp2 = select i1 %tmp1, i32 %a0, i32 %a1 142 ret i32 %tmp2 143} 144 145; Test a result being used by more than just the comparison. 146 147define i8 @test_add_1_setcc_sgt_reuse(i64* %p, i64* %p2) #0 { 148; CHECK-LABEL: test_add_1_setcc_sgt_reuse: 149; CHECK: # BB#0: # %entry 150; CHECK-NEXT: movl $1, %ecx 151; CHECK-NEXT: lock xaddq %rcx, (%rdi) 152; CHECK-NEXT: testq %rcx, %rcx 153; CHECK-NEXT: setg %al 154; CHECK-NEXT: movq %rcx, (%rsi) 155; CHECK-NEXT: retq 156entry: 157 %tmp0 = atomicrmw add i64* %p, i64 1 seq_cst 158 %tmp1 = icmp sgt i64 %tmp0, 0 159 %tmp2 = zext i1 %tmp1 to i8 160 store i64 %tmp0, i64* %p2 161 ret i8 %tmp2 162} 163 164define i8 @test_sub_2_setcc_sgt(i64* %p) #0 { 165; CHECK-LABEL: test_sub_2_setcc_sgt: 166; CHECK: # BB#0: # %entry 167; CHECK-NEXT: movq $-2, %rax 168; CHECK-NEXT: lock xaddq %rax, (%rdi) 169; CHECK-NEXT: testq %rax, %rax 170; CHECK-NEXT: setg %al 171; CHECK-NEXT: retq 172entry: 173 %tmp0 = atomicrmw sub i64* %p, i64 2 seq_cst 174 %tmp1 = icmp sgt i64 %tmp0, 0 175 %tmp2 = zext i1 %tmp1 to i8 176 ret i8 %tmp2 177} 178 179attributes #0 = { nounwind } 180