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