blob: 7da2ea0fde81c92d22392d4fae9441f9e6d5f066 [file] [log] [blame]
Ulrich Weiganda11f63a2017-08-04 18:57:58 +00001; Test 64-bit compare and swap.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
4
5; Check CDSG without a displacement.
6define i128 @f1(i128 %cmp, i128 %swap, i128 *%src) {
7; CHECK-LABEL: f1:
8; CHECK-DAG: lg %r1, 8(%r4)
9; CHECK-DAG: lg %r0, 0(%r4)
10; CHECK-DAG: lg %r13, 8(%r3)
11; CHECK-DAG: lg %r12, 0(%r3)
12; CHECK: cdsg %r12, %r0, 0(%r5)
13; CHECK-DAG: stg %r13, 8(%r2)
14; CHECK-DAG: stg %r12, 0(%r2)
15; CHECK: br %r14
16 %pairval = cmpxchg i128 *%src, i128 %cmp, i128 %swap seq_cst seq_cst
17 %val = extractvalue { i128, i1 } %pairval, 0
18 ret i128 %val
19}
20
21; Check the high end of the aligned CDSG range.
22define i128 @f2(i128 %cmp, i128 %swap, i128 *%src) {
23; CHECK-LABEL: f2:
24; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 524272(%r5)
25; CHECK: br %r14
26 %ptr = getelementptr i128, i128 *%src, i128 32767
27 %pairval = cmpxchg i128 *%ptr, i128 %cmp, i128 %swap seq_cst seq_cst
28 %val = extractvalue { i128, i1 } %pairval, 0
29 ret i128 %val
30}
31
32; Check the next doubleword up, which needs separate address logic.
33; Other sequences besides this one would be OK.
34define i128 @f3(i128 %cmp, i128 %swap, i128 *%src) {
35; CHECK-LABEL: f3:
36; CHECK: agfi %r5, 524288
37; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 0(%r5)
38; CHECK: br %r14
39 %ptr = getelementptr i128, i128 *%src, i128 32768
40 %pairval = cmpxchg i128 *%ptr, i128 %cmp, i128 %swap seq_cst seq_cst
41 %val = extractvalue { i128, i1 } %pairval, 0
42 ret i128 %val
43}
44
45; Check the high end of the negative aligned CDSG range.
46define i128 @f4(i128 %cmp, i128 %swap, i128 *%src) {
47; CHECK-LABEL: f4:
48; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, -16(%r5)
49; CHECK: br %r14
50 %ptr = getelementptr i128, i128 *%src, i128 -1
51 %pairval = cmpxchg i128 *%ptr, i128 %cmp, i128 %swap seq_cst seq_cst
52 %val = extractvalue { i128, i1 } %pairval, 0
53 ret i128 %val
54}
55
56; Check the low end of the CDSG range.
57define i128 @f5(i128 %cmp, i128 %swap, i128 *%src) {
58; CHECK-LABEL: f5:
59; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, -524288(%r5)
60; CHECK: br %r14
61 %ptr = getelementptr i128, i128 *%src, i128 -32768
62 %pairval = cmpxchg i128 *%ptr, i128 %cmp, i128 %swap seq_cst seq_cst
63 %val = extractvalue { i128, i1 } %pairval, 0
64 ret i128 %val
65}
66
67; Check the next doubleword down, which needs separate address logic.
68; Other sequences besides this one would be OK.
69define i128 @f6(i128 %cmp, i128 %swap, i128 *%src) {
70; CHECK-LABEL: f6:
71; CHECK: agfi %r5, -524304
72; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 0(%r5)
73; CHECK: br %r14
74 %ptr = getelementptr i128, i128 *%src, i128 -32769
75 %pairval = cmpxchg i128 *%ptr, i128 %cmp, i128 %swap seq_cst seq_cst
76 %val = extractvalue { i128, i1 } %pairval, 0
77 ret i128 %val
78}
79
80; Check that CDSG does not allow an index.
81define i128 @f7(i128 %cmp, i128 %swap, i64 %src, i64 %index) {
82; CHECK-LABEL: f7:
83; CHECK: agr %r5, %r6
84; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 0(%r5)
85; CHECK: br %r14
86 %add1 = add i64 %src, %index
87 %ptr = inttoptr i64 %add1 to i128 *
88 %pairval = cmpxchg i128 *%ptr, i128 %cmp, i128 %swap seq_cst seq_cst
89 %val = extractvalue { i128, i1 } %pairval, 0
90 ret i128 %val
91}
92
93; Check that a constant %cmp value is loaded into a register first.
94define i128 @f8(i128 %swap, i128 *%ptr) {
95; CHECK-LABEL: f8:
96; CHECK: lghi {{%r[0-9]+}}, 1001
97; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 0(%r4)
98; CHECK: br %r14
99 %pairval = cmpxchg i128 *%ptr, i128 1001, i128 %swap seq_cst seq_cst
100 %val = extractvalue { i128, i1 } %pairval, 0
101 ret i128 %val
102}
103
104; Check that a constant %swap value is loaded into a register first.
105define i128 @f9(i128 %cmp, i128 *%ptr) {
106; CHECK-LABEL: f9:
107; CHECK: lghi {{%r[0-9]+}}, 1002
108; CHECK: cdsg {{%r[0-9]+}}, {{%r[0-9]+}}, 0(%r4)
109; CHECK: br %r14
110 %pairval = cmpxchg i128 *%ptr, i128 %cmp, i128 1002 seq_cst seq_cst
111 %val = extractvalue { i128, i1 } %pairval, 0
112 ret i128 %val
113}
Ulrich Weigand0f1de042017-09-28 16:22:54 +0000114
115; Check generating the comparison result.
116; CHECK-LABEL: f10
117; CHECK-DAG: lg %r1, 8(%r3)
118; CHECK-DAG: lg %r0, 0(%r3)
119; CHECK-DAG: lg %r13, 8(%r2)
120; CHECK-DAG: lg %r12, 0(%r2)
121; CHECK: cdsg %r12, %r0, 0(%r4)
122; CHECK-NEXT: ipm %r2
123; CHECK-NEXT: afi %r2, -268435456
124; CHECK-NEXT: srl %r2, 31
125; CHECK: br %r14
126define i32 @f10(i128 %cmp, i128 %swap, i128 *%src) {
127 %pairval = cmpxchg i128 *%src, i128 %cmp, i128 %swap seq_cst seq_cst
128 %val = extractvalue { i128, i1 } %pairval, 1
129 %res = zext i1 %val to i32
130 ret i32 %res
131}