• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=core-avx2 | FileCheck %s
3
4define i1 @try_cmpxchg(i128* %addr, i128 %desired, i128 %new) {
5; CHECK-LABEL: try_cmpxchg:
6; CHECK:       # %bb.0:
7; CHECK-NEXT:    pushq %rbx
8; CHECK-NEXT:    .cfi_def_cfa_offset 16
9; CHECK-NEXT:    .cfi_offset %rbx, -16
10; CHECK-NEXT:    movq %rcx, %rbx
11; CHECK-NEXT:    movq %rsi, %rax
12; CHECK-NEXT:    movq %r8, %rcx
13; CHECK-NEXT:    lock cmpxchg16b (%rdi)
14; CHECK-NEXT:    sete %al
15; CHECK-NEXT:    popq %rbx
16; CHECK-NEXT:    .cfi_def_cfa_offset 8
17; CHECK-NEXT:    retq
18  %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
19  %success = extractvalue { i128, i1 } %pair, 1
20  ret i1 %success
21}
22
23define void @cmpxchg_flow(i128* %addr, i128 %desired, i128 %new) {
24; CHECK-LABEL: cmpxchg_flow:
25; CHECK:       # %bb.0:
26; CHECK-NEXT:    pushq %rbx
27; CHECK-NEXT:    .cfi_def_cfa_offset 16
28; CHECK-NEXT:    .cfi_offset %rbx, -16
29; CHECK-NEXT:    movq %rcx, %rbx
30; CHECK-NEXT:    movq %rsi, %rax
31; CHECK-NEXT:    movq %r8, %rcx
32; CHECK-NEXT:    lock cmpxchg16b (%rdi)
33; CHECK-NEXT:    jne .LBB1_2
34; CHECK-NEXT:  # %bb.1: # %true
35; CHECK-NEXT:    callq foo
36; CHECK-NEXT:    popq %rbx
37; CHECK-NEXT:    .cfi_def_cfa_offset 8
38; CHECK-NEXT:    retq
39; CHECK-NEXT:  .LBB1_2: # %false
40; CHECK-NEXT:    .cfi_def_cfa_offset 16
41; CHECK-NEXT:    callq bar
42; CHECK-NEXT:    popq %rbx
43; CHECK-NEXT:    .cfi_def_cfa_offset 8
44; CHECK-NEXT:    retq
45  %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
46  %success = extractvalue { i128, i1 } %pair, 1
47  br i1 %success, label %true, label %false
48
49true:
50  call void @foo()
51  ret void
52
53false:
54  call void @bar()
55  ret void
56}
57
58; Can't use the flags here because cmpxchg16b only sets ZF.
59define i1 @cmpxchg_arithcmp(i128* %addr, i128 %desired, i128 %new) {
60; CHECK-LABEL: cmpxchg_arithcmp:
61; CHECK:       # %bb.0:
62; CHECK-NEXT:    pushq %rbx
63; CHECK-NEXT:    .cfi_def_cfa_offset 16
64; CHECK-NEXT:    .cfi_offset %rbx, -16
65; CHECK-NEXT:    movq %rcx, %rbx
66; CHECK-NEXT:    movq %rdx, %r9
67; CHECK-NEXT:    movq %rsi, %rax
68; CHECK-NEXT:    movq %r8, %rcx
69; CHECK-NEXT:    lock cmpxchg16b (%rdi)
70; CHECK-NEXT:    cmpq %rsi, %rax
71; CHECK-NEXT:    sbbq %r9, %rdx
72; CHECK-NEXT:    setge %al
73; CHECK-NEXT:    popq %rbx
74; CHECK-NEXT:    .cfi_def_cfa_offset 8
75; CHECK-NEXT:    retq
76  %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
77  %oldval = extractvalue { i128, i1 } %pair, 0
78  %success = icmp sge i128 %oldval, %desired
79  ret i1 %success
80}
81
82define i128 @cmpxchg_zext(i128* %addr, i128 %desired, i128 %new) {
83; CHECK-LABEL: cmpxchg_zext:
84; CHECK:       # %bb.0:
85; CHECK-NEXT:    pushq %rbx
86; CHECK-NEXT:    .cfi_def_cfa_offset 16
87; CHECK-NEXT:    .cfi_offset %rbx, -16
88; CHECK-NEXT:    movq %rcx, %rbx
89; CHECK-NEXT:    movq %rsi, %rax
90; CHECK-NEXT:    xorl %esi, %esi
91; CHECK-NEXT:    movq %r8, %rcx
92; CHECK-NEXT:    lock cmpxchg16b (%rdi)
93; CHECK-NEXT:    sete %sil
94; CHECK-NEXT:    movq %rsi, %rax
95; CHECK-NEXT:    xorl %edx, %edx
96; CHECK-NEXT:    popq %rbx
97; CHECK-NEXT:    .cfi_def_cfa_offset 8
98; CHECK-NEXT:    retq
99  %pair = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst
100  %success = extractvalue { i128, i1 } %pair, 1
101  %mask = zext i1 %success to i128
102  ret i128 %mask
103}
104
105
106define i128 @cmpxchg_use_eflags_and_val(i128* %addr, i128 %offset) {
107; CHECK-LABEL: cmpxchg_use_eflags_and_val:
108; CHECK:       # %bb.0: # %entry
109; CHECK-NEXT:    pushq %rbx
110; CHECK-NEXT:    .cfi_def_cfa_offset 16
111; CHECK-NEXT:    .cfi_offset %rbx, -16
112; CHECK-NEXT:    movq %rdx, %r8
113; CHECK-NEXT:    xorl %eax, %eax
114; CHECK-NEXT:    xorl %edx, %edx
115; CHECK-NEXT:    xorl %ecx, %ecx
116; CHECK-NEXT:    xorl %ebx, %ebx
117; CHECK-NEXT:    lock cmpxchg16b (%rdi)
118; CHECK-NEXT:    .p2align 4, 0x90
119; CHECK-NEXT:  .LBB4_1: # %loop
120; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
121; CHECK-NEXT:    movq %rdx, %r9
122; CHECK-NEXT:    movq %rax, %r10
123; CHECK-NEXT:    movq %rax, %rbx
124; CHECK-NEXT:    addq %rsi, %rbx
125; CHECK-NEXT:    movq %rdx, %rcx
126; CHECK-NEXT:    adcq %r8, %rcx
127; CHECK-NEXT:    lock cmpxchg16b (%rdi)
128; CHECK-NEXT:    jne .LBB4_1
129; CHECK-NEXT:  # %bb.2: # %done
130; CHECK-NEXT:    movq %r10, %rax
131; CHECK-NEXT:    movq %r9, %rdx
132; CHECK-NEXT:    popq %rbx
133; CHECK-NEXT:    .cfi_def_cfa_offset 8
134; CHECK-NEXT:    retq
135entry:
136  %init = load atomic i128, i128* %addr seq_cst, align 16
137  br label %loop
138
139loop:
140  %old = phi i128 [%init, %entry], [%oldval, %loop]
141  %new = add i128 %old, %offset
142
143  %pair = cmpxchg i128* %addr, i128 %old, i128 %new seq_cst seq_cst
144  %oldval = extractvalue { i128, i1 } %pair, 0
145  %success = extractvalue { i128, i1 } %pair, 1
146
147  br i1 %success, label %done, label %loop
148
149done:
150  ret i128 %old
151}
152
153declare void @foo()
154declare void @bar()
155