Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / SystemZ / cmpxchg-06.ll
blob0aff13aa59b59ca8afd30e396dfbb8e8dfc1cc51
1 ; Test 128-bit compare and swap.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z10
4 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z13
6 ; Check CDSG without a displacement.
7 define i128 @f1(i128 %cmp, i128 %swap, ptr %src) {
8 ; CHECK-LABEL: f1:
9 ; CHECK-DAG: lg %r1, 8(%r4)
10 ; CHECK-DAG: lg %r0, 0(%r4)
11 ; CHECK-DAG: lg %r13, 8(%r3)
12 ; CHECK-DAG: lg %r12, 0(%r3)
13 ; CHECK:     cdsg %r12, %r0, 0(%r5)
14 ; CHECK-DAG: stg %r13, 8(%r2)
15 ; CHECK-DAG: stg %r12, 0(%r2)
16 ; CHECK:     br %r14
17   %pairval = cmpxchg ptr %src, i128 %cmp, i128 %swap seq_cst seq_cst
18   %val = extractvalue { i128, i1 } %pairval, 0
19   ret i128 %val
22 ; Check the high end of the aligned CDSG range.
23 define i128 @f2(i128 %cmp, i128 %swap, ptr %src) {
24 ; CHECK-LABEL: f2:
25 ; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 524272(%r5)
26 ; CHECK: br %r14
27   %ptr = getelementptr i128, ptr %src, i128 32767
28   %pairval = cmpxchg ptr %ptr, i128 %cmp, i128 %swap seq_cst seq_cst
29   %val = extractvalue { i128, i1 } %pairval, 0
30   ret i128 %val
33 ; Check the next doubleword up, which needs separate address logic.
34 ; Other sequences besides this one would be OK.
35 define i128 @f3(i128 %cmp, i128 %swap, ptr %src) {
36 ; CHECK-LABEL: f3:
37 ; CHECK: agfi %r5, 524288
38 ; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 0(%r5)
39 ; CHECK: br %r14
40   %ptr = getelementptr i128, ptr %src, i128 32768
41   %pairval = cmpxchg ptr %ptr, i128 %cmp, i128 %swap seq_cst seq_cst
42   %val = extractvalue { i128, i1 } %pairval, 0
43   ret i128 %val
46 ; Check the high end of the negative aligned CDSG range.
47 define i128 @f4(i128 %cmp, i128 %swap, ptr %src) {
48 ; CHECK-LABEL: f4:
49 ; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, -16(%r5)
50 ; CHECK: br %r14
51   %ptr = getelementptr i128, ptr %src, i128 -1
52   %pairval = cmpxchg ptr %ptr, i128 %cmp, i128 %swap seq_cst seq_cst
53   %val = extractvalue { i128, i1 } %pairval, 0
54   ret i128 %val
57 ; Check the low end of the CDSG range.
58 define i128 @f5(i128 %cmp, i128 %swap, ptr %src) {
59 ; CHECK-LABEL: f5:
60 ; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, -524288(%r5)
61 ; CHECK: br %r14
62   %ptr = getelementptr i128, ptr %src, i128 -32768
63   %pairval = cmpxchg ptr %ptr, i128 %cmp, i128 %swap seq_cst seq_cst
64   %val = extractvalue { i128, i1 } %pairval, 0
65   ret i128 %val
68 ; Check the next doubleword down, which needs separate address logic.
69 ; Other sequences besides this one would be OK.
70 define i128 @f6(i128 %cmp, i128 %swap, ptr %src) {
71 ; CHECK-LABEL: f6:
72 ; CHECK: agfi %r5, -524304
73 ; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 0(%r5)
74 ; CHECK: br %r14
75   %ptr = getelementptr i128, ptr %src, i128 -32769
76   %pairval = cmpxchg ptr %ptr, i128 %cmp, i128 %swap seq_cst seq_cst
77   %val = extractvalue { i128, i1 } %pairval, 0
78   ret i128 %val
81 ; Check that CDSG does not allow an index.
82 define i128 @f7(i128 %cmp, i128 %swap, i64 %src, i64 %index) {
83 ; CHECK-LABEL: f7:
84 ; CHECK: agr %r5, %r6
85 ; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 0(%r5)
86 ; CHECK: br %r14
87   %add1 = add i64 %src, %index
88   %ptr = inttoptr i64 %add1 to ptr
89   %pairval = cmpxchg ptr %ptr, i128 %cmp, i128 %swap seq_cst seq_cst
90   %val = extractvalue { i128, i1 } %pairval, 0
91   ret i128 %val
94 ; Check that a constant %cmp value is loaded into a register first.
95 define i128 @f8(i128 %swap, ptr %ptr) {
96 ; CHECK-LABEL: f8:
97 ; CHECK: lghi {{%r[0-9]+}}, 1001
98 ; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 0(%r4)
99 ; CHECK: br %r14
100   %pairval = cmpxchg ptr %ptr, i128 1001, i128 %swap seq_cst seq_cst
101   %val = extractvalue { i128, i1 } %pairval, 0
102   ret i128 %val
105 ; Check that a constant %swap value is loaded into a register first.
106 define i128 @f9(i128 %cmp, ptr %ptr) {
107 ; CHECK-LABEL: f9:
108 ; CHECK: lghi {{%r[0-9]+}}, 1002
109 ; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 0(%r4)
110 ; CHECK: br %r14
111   %pairval = cmpxchg ptr %ptr, i128 %cmp, i128 1002 seq_cst seq_cst
112   %val = extractvalue { i128, i1 } %pairval, 0
113   ret i128 %val
116 ; Check generating the comparison result.
117 ; CHECK-LABEL: f10
118 ; CHECK-DAG: lg %r1, 8(%r3)
119 ; CHECK-DAG: lg %r0, 0(%r3)
120 ; CHECK-DAG: lg %r13, 8(%r2)
121 ; CHECK-DAG: lg %r12, 0(%r2)
122 ; CHECK-Z13: lhi %r2, 0
123 ; CHECK:     cdsg %r12, %r0, 0(%r4)
124 ; CHECK-Z10-NEXT: ipm %r2
125 ; CHECK-Z10-NEXT: afi %r2, -268435456
126 ; CHECK-Z10-NEXT: srl %r2, 31
127 ; CHECK-Z13-NEXT: lochie %r2, 1
128 ; CHECK: br %r14
129 define i32 @f10(i128 %cmp, i128 %swap, ptr %src) {
130   %pairval = cmpxchg ptr %src, i128 %cmp, i128 %swap seq_cst seq_cst
131   %val = extractvalue { i128, i1 } %pairval, 1
132   %res = zext i1 %val to i32
133   ret i32 %res
136 declare void @g()
138 ; Check using the comparison result for a branch.
139 ; CHECK-LABEL: f11
140 ; CHECK-DAG: lg %r1, 8(%r3)
141 ; CHECK-DAG: lg %r0, 0(%r3)
142 ; CHECK-DAG: lg %r13, 8(%r2)
143 ; CHECK-DAG: lg %r12, 0(%r2)
144 ; CHECK:     cdsg %r12, %r0, 0(%r4)
145 ; CHECK-NEXT: jl [[LABEL:\.[^ ]*]]
146 ; CHECK: jg g
147 ; CHECK: [[LABEL]]:
148 ; CHECK: br %r14
149 define void @f11(i128 %cmp, i128 %swap, ptr %src) {
150   %pairval = cmpxchg ptr %src, i128 %cmp, i128 %swap seq_cst seq_cst
151   %cond = extractvalue { i128, i1 } %pairval, 1
152   br i1 %cond, label %call, label %exit
154 call:
155   tail call void @g()
156   br label %exit
158 exit:
159   ret void
162 ; ... and the same with the inverted direction.
163 ; CHECK-LABEL: f12
164 ; CHECK-DAG: lg %r1, 8(%r3)
165 ; CHECK-DAG: lg %r0, 0(%r3)
166 ; CHECK-DAG: lg %r13, 8(%r2)
167 ; CHECK-DAG: lg %r12, 0(%r2)
168 ; CHECK:     cdsg %r12, %r0, 0(%r4)
169 ; CHECK-NEXT: jl [[LABEL:\.[^ ]*]]
170 ; CHECK: br %r14
171 ; CHECK: [[LABEL]]:
172 ; CHECK: jg g
173 define void @f12(i128 %cmp, i128 %swap, ptr %src) {
174   %pairval = cmpxchg ptr %src, i128 %cmp, i128 %swap seq_cst seq_cst
175   %cond = extractvalue { i128, i1 } %pairval, 1
176   br i1 %cond, label %exit, label %call
178 call:
179   tail call void @g()
180   br label %exit
182 exit:
183   ret void