1; RUN: llc -mcpu=core-avx2 -mtriple=x86_64 -o - %s | FileCheck %s
2
3define i1 @try_cmpxchg(i128* %addr, i128 %desired, i128 %new) {
4; CHECK-LABEL: try_cmpxchg:
5; CHECK: cmpxchg16b
6; CHECK-NOT: cmp
7; CHECK: sete %al
8; CHECK: retq
9  %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
10  %success = extractvalue { i128, i1 } %pair, 1
11  ret i1 %success
12}
13
14define void @cmpxchg_flow(i128* %addr, i128 %desired, i128 %new) {
15; CHECK-LABEL: cmpxchg_flow:
16; CHECK: cmpxchg16b
17; CHECK-NOT: cmp
18; CHECK-NOT: set
19; CHECK: {{jne|jeq}}
20  %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
21  %success = extractvalue { i128, i1 } %pair, 1
22  br i1 %success, label %true, label %false
23
24true:
25  call void @foo()
26  ret void
27
28false:
29  call void @bar()
30  ret void
31}
32
33; Can't use the flags here because cmpxchg16b only sets ZF.
34define i1 @cmpxchg_arithcmp(i128* %addr, i128 %desired, i128 %new) {
35; CHECK-LABEL: cmpxchg_arithcmp:
36; CHECK: cmpxchg16b
37; CHECK: cmpq
38; CHECK: retq
39  %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
40  %oldval = extractvalue { i128, i1 } %pair, 0
41  %success = icmp sge i128 %oldval, %desired
42  ret i1 %success
43}
44
45define i128 @cmpxchg_zext(i128* %addr, i128 %desired, i128 %new) {
46; CHECK-LABEL: cmpxchg_zext:
47; CHECK: cmpxchg16b
48; CHECK-NOT: cmpq
49; CHECK: sete [[BYTE:%[a-z0-9]+]]
50; CHECK: movzbl [[BYTE]], %eax
51  %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
52  %success = extractvalue { i128, i1 } %pair, 1
53  %mask = zext i1 %success to i128
54  ret i128 %mask
55}
56
57
58define i128 @cmpxchg_use_eflags_and_val(i128* %addr, i128 %offset) {
59; CHECK-LABEL: cmpxchg_use_eflags_and_val:
60
61; CHECK: cmpxchg16b
62; CHECK-NOT: cmpq
63; CHECK: jne
64entry:
65  %init = load atomic i128* %addr seq_cst, align 16
66  br label %loop
67
68loop:
69  %old = phi i128 [%init, %entry], [%oldval, %loop]
70  %new = add i128 %old, %offset
71
72  %pair = cmpxchg i128* %addr, i128 %old, i128 %new seq_cst seq_cst
73  %oldval = extractvalue { i128, i1 } %pair, 0
74  %success = extractvalue { i128, i1 } %pair, 1
75
76  br i1 %success, label %done, label %loop
77
78done:
79  ret i128 %old
80}
81
82declare void @foo()
83declare void @bar()
84