[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / SystemZ / cmpxchg-06.ll
blobb3168e2a6b08e0d03e08343568a30c75b96ebeef
1 ; Test 64-bit compare and swap.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
5 ; Check CDSG without a displacement.
6 define 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
21 ; Check the high end of the aligned CDSG range.
22 define 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
32 ; Check the next doubleword up, which needs separate address logic.
33 ; Other sequences besides this one would be OK.
34 define 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
45 ; Check the high end of the negative aligned CDSG range.
46 define 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
56 ; Check the low end of the CDSG range.
57 define 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
67 ; Check the next doubleword down, which needs separate address logic.
68 ; Other sequences besides this one would be OK.
69 define 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
80 ; Check that CDSG does not allow an index.
81 define 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
93 ; Check that a constant %cmp value is loaded into a register first.
94 define 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
104 ; Check that a constant %swap value is loaded into a register first.
105 define 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
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
126 define 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
133 declare void @g()
135 ; Check using the comparison result for a branch.
136 ; CHECK-LABEL: f11
137 ; CHECK-DAG: lg %r1, 8(%r3)
138 ; CHECK-DAG: lg %r0, 0(%r3)
139 ; CHECK-DAG: lg %r13, 8(%r2)
140 ; CHECK-DAG: lg %r12, 0(%r2)
141 ; CHECK:     cdsg %r12, %r0, 0(%r4)
142 ; CHECK-NEXT: jl [[LABEL:\.[^ ]*]]
143 ; CHECK: jg g
144 ; CHECK: [[LABEL]]:
145 ; CHECK: br %r14
146 define void @f11(i128 %cmp, i128 %swap, i128 *%src) {
147   %pairval = cmpxchg i128 *%src, i128 %cmp, i128 %swap seq_cst seq_cst
148   %cond = extractvalue { i128, i1 } %pairval, 1
149   br i1 %cond, label %call, label %exit
151 call:
152   tail call void @g()
153   br label %exit
155 exit:
156   ret void
159 ; ... and the same with the inverted direction.
160 ; CHECK-LABEL: f12
161 ; CHECK-DAG: lg %r1, 8(%r3)
162 ; CHECK-DAG: lg %r0, 0(%r3)
163 ; CHECK-DAG: lg %r13, 8(%r2)
164 ; CHECK-DAG: lg %r12, 0(%r2)
165 ; CHECK:     cdsg %r12, %r0, 0(%r4)
166 ; CHECK-NEXT: jl [[LABEL:\.[^ ]*]]
167 ; CHECK: br %r14
168 ; CHECK: [[LABEL]]:
169 ; CHECK: jg g
170 define void @f12(i128 %cmp, i128 %swap, i128 *%src) {
171   %pairval = cmpxchg i128 *%src, i128 %cmp, i128 %swap seq_cst seq_cst
172   %cond = extractvalue { i128, i1 } %pairval, 1
173   br i1 %cond, label %exit, label %call
175 call:
176   tail call void @g()
177   br label %exit
179 exit:
180   ret void