xref: /llvm-project/llvm/test/CodeGen/X86/peep-test-5.ll (revision 4e2b4f97a09500fb6ceb4f077c492fac056a6a0a)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -o - %s -mtriple=x86_64-- | FileCheck %s
3; Example of a decref operation with "immortal" objects.
4; void decref(long* refcount) {
5;  long count = *refcount;
6;  if (count == 1) { free_object() }
7;  else if (count > 1) { *refcount = count - 1; }
8;  else { /* immortal */ }
9; }
10; Resulting assembly should share flags from single CMP instruction for both
11; conditions!
12define void @decref(ptr %p) {
13; CHECK-LABEL: decref:
14; CHECK:       # %bb.0:
15; CHECK-NEXT:    movl (%rdi), %eax
16; CHECK-NEXT:    cmpl $1, %eax
17; CHECK-NEXT:    jne .LBB0_2
18; CHECK-NEXT:  # %bb.1: # %bb_free
19; CHECK-NEXT:    pushq %rax
20; CHECK-NEXT:    .cfi_def_cfa_offset 16
21; CHECK-NEXT:    callq free_object@PLT
22; CHECK-NEXT:    addq $8, %rsp
23; CHECK-NEXT:    .cfi_def_cfa_offset 8
24; CHECK-NEXT:  .LBB0_4: # %end
25; CHECK-NEXT:    retq
26; CHECK-NEXT:  .LBB0_2: # %bb2
27; CHECK-NEXT:    jle .LBB0_4
28; CHECK-NEXT:  # %bb.3: # %bb_dec
29; CHECK-NEXT:    decl %eax
30; CHECK-NEXT:    movl %eax, (%rdi)
31; CHECK-NEXT:    retq
32  %count = load i32, ptr %p, align 4
33  %cmp0 = icmp eq i32 %count, 1
34  br i1 %cmp0, label %bb_free, label %bb2
35
36bb2:
37  %cmp1 = icmp sgt i32 %count, 1
38  br i1 %cmp1, label %bb_dec, label %end
39
40bb_dec:
41  %dec = add nsw i32 %count, -1
42  store i32 %dec, ptr %p, align 4
43  br label %end
44
45bb_free:
46  call void @free_object()
47  br label %end
48
49end:
50  ret void
51}
52
53declare void @free_object()
54