xref: /llvm-project/llvm/test/CodeGen/X86/pr37025.ll (revision a4951eca40c070e020aa5d2689c08177fbeb780d)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s
3
4; PR37025
5;
6;#include <stdatomic.h>
7;#include <stdbool.h>
8;
9;void func2();
10;
11;void func(_Atomic(unsigned long) * obj, ptr obj2)
12;{
13;        if (atomic_fetch_sub(obj, 1) == 1 && obj2)
14;                func2();
15;}
16
17define void @test_dec_select(ptr nocapture %0, ptr readnone %1) {
18; CHECK-LABEL: test_dec_select:
19; CHECK:       # %bb.0:
20; CHECK-NEXT:    lock decq (%rdi)
21; CHECK-NEXT:    sete %al
22; CHECK-NEXT:    testq %rsi, %rsi
23; CHECK-NEXT:    setne %cl
24; CHECK-NEXT:    andb %al, %cl
25; CHECK-NEXT:    cmpb $1, %cl
26; CHECK-NEXT:    je func2 # TAILCALL
27; CHECK-NEXT:  # %bb.1:
28; CHECK-NEXT:    retq
29  %3 = atomicrmw sub ptr %0, i64 1 seq_cst
30  %4 = icmp eq i64 %3, 1
31  %5 = icmp ne ptr %1, null
32  %6 = select i1 %4, i1 %5, i1 false
33  br i1 %6, label %7, label %8
34
357: ; preds = %2
36  tail call void @func2()
37  br label %8
38
398: ; preds = %7, %2
40  ret void
41}
42
43define void @test_dec_select_commute(ptr nocapture %0, ptr readnone %1) {
44; CHECK-LABEL: test_dec_select_commute:
45; CHECK:       # %bb.0:
46; CHECK-NEXT:    lock decq (%rdi)
47; CHECK-NEXT:    sete %al
48; CHECK-NEXT:    testq %rsi, %rsi
49; CHECK-NEXT:    setne %cl
50; CHECK-NEXT:    andb %al, %cl
51; CHECK-NEXT:    cmpb $1, %cl
52; CHECK-NEXT:    je func2 # TAILCALL
53; CHECK-NEXT:  # %bb.1:
54; CHECK-NEXT:    retq
55  %3 = atomicrmw sub ptr %0, i64 1 seq_cst
56  %4 = icmp eq i64 %3, 1
57  %5 = icmp ne ptr %1, null
58  %6 = select i1 %5, i1 %4, i1 false
59  br i1 %6, label %7, label %8
60
617: ; preds = %2
62  tail call void @func2()
63  br label %8
64
658: ; preds = %7, %2
66  ret void
67}
68
69define void @test_dec_and(ptr nocapture %0, ptr readnone %1) {
70; CHECK-LABEL: test_dec_and:
71; CHECK:       # %bb.0:
72; CHECK-NEXT:    lock decq (%rdi)
73; CHECK-NEXT:    sete %al
74; CHECK-NEXT:    notb %al
75; CHECK-NEXT:    testq %rsi, %rsi
76; CHECK-NEXT:    sete %cl
77; CHECK-NEXT:    orb %al, %cl
78; CHECK-NEXT:    testb $1, %cl
79; CHECK-NEXT:    je func2 # TAILCALL
80; CHECK-NEXT:  # %bb.1:
81; CHECK-NEXT:    retq
82  %3 = atomicrmw sub ptr %0, i64 1 seq_cst
83  %4 = icmp eq i64 %3, 1
84  %5 = icmp ne ptr %1, null
85  %6 = and i1 %5, %4
86  br i1 %6, label %7, label %8
87
887: ; preds = %2
89  tail call void @func2()
90  br label %8
91
928: ; preds = %7, %2
93  ret void
94}
95
96define void @test_dec_and_commute(ptr nocapture %0, ptr readnone %1) {
97; CHECK-LABEL: test_dec_and_commute:
98; CHECK:       # %bb.0:
99; CHECK-NEXT:    lock decq (%rdi)
100; CHECK-NEXT:    sete %al
101; CHECK-NEXT:    notb %al
102; CHECK-NEXT:    testq %rsi, %rsi
103; CHECK-NEXT:    sete %cl
104; CHECK-NEXT:    orb %al, %cl
105; CHECK-NEXT:    testb $1, %cl
106; CHECK-NEXT:    je func2 # TAILCALL
107; CHECK-NEXT:  # %bb.1:
108; CHECK-NEXT:    retq
109  %3 = atomicrmw sub ptr %0, i64 1 seq_cst
110  %4 = icmp eq i64 %3, 1
111  %5 = icmp ne ptr %1, null
112  %6 = and i1 %4, %5
113  br i1 %6, label %7, label %8
114
1157: ; preds = %2
116  tail call void @func2()
117  br label %8
118
1198: ; preds = %7, %2
120  ret void
121}
122
123declare dso_local void @func2()
124