[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / SystemZ / htm-intrinsics.ll
blob107059f5cd839a133dbf48114a7bd7664b297f3d
1 ; Test transactional-execution intrinsics.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=zEC12 | FileCheck %s
5 declare i32 @llvm.s390.tbegin(i8 *, i32)
6 declare i32 @llvm.s390.tbegin.nofloat(i8 *, i32)
7 declare void @llvm.s390.tbeginc(i8 *, i32)
8 declare i32 @llvm.s390.tend()
9 declare void @llvm.s390.tabort(i64)
10 declare void @llvm.s390.ntstg(i64, i64 *)
11 declare i32 @llvm.s390.etnd()
12 declare void @llvm.s390.ppa.txassist(i32)
14 ; TBEGIN.
15 define void @test_tbegin() {
16 ; CHECK-LABEL: test_tbegin:
17 ; CHECK-NOT: stmg
18 ; CHECK: std %f8,
19 ; CHECK: std %f9,
20 ; CHECK: std %f10,
21 ; CHECK: std %f11,
22 ; CHECK: std %f12,
23 ; CHECK: std %f13,
24 ; CHECK: std %f14,
25 ; CHECK: std %f15,
26 ; CHECK: tbegin 0, 65292
27 ; CHECK: ld %f8,
28 ; CHECK: ld %f9,
29 ; CHECK: ld %f10,
30 ; CHECK: ld %f11,
31 ; CHECK: ld %f12,
32 ; CHECK: ld %f13,
33 ; CHECK: ld %f14,
34 ; CHECK: ld %f15,
35 ; CHECK: br %r14
36   call i32 @llvm.s390.tbegin(i8 *null, i32 65292)
37   ret void
40 ; TBEGIN (nofloat).
41 define void @test_tbegin_nofloat1() {
42 ; CHECK-LABEL: test_tbegin_nofloat1:
43 ; CHECK-NOT: stmg
44 ; CHECK-NOT: std
45 ; CHECK: tbegin 0, 65292
46 ; CHECK: br %r14
47   call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 65292)
48   ret void
51 ; TBEGIN (nofloat) with integer CC return value.
52 define i32 @test_tbegin_nofloat2() {
53 ; CHECK-LABEL: test_tbegin_nofloat2:
54 ; CHECK-NOT: stmg
55 ; CHECK-NOT: std
56 ; CHECK: tbegin 0, 65292
57 ; CHECK: ipm %r2
58 ; CHECK: srl %r2, 28
59 ; CHECK: br %r14
60   %res = call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 65292)
61   ret i32 %res
64 ; TBEGIN (nofloat) with implicit CC check.
65 define void @test_tbegin_nofloat3(i32 *%ptr) {
66 ; CHECK-LABEL: test_tbegin_nofloat3:
67 ; CHECK-NOT: stmg
68 ; CHECK-NOT: std
69 ; CHECK: tbegin 0, 65292
70 ; CHECK: bnhr %r14
71 ; CHECK: mvhi 0(%r2), 0
72 ; CHECK: br %r14
73   %res = call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 65292)
74   %cmp = icmp eq i32 %res, 2
75   br i1 %cmp, label %if.then, label %if.end
77 if.then:                                          ; preds = %entry
78   store i32 0, i32* %ptr, align 4
79   br label %if.end
81 if.end:                                           ; preds = %if.then, %entry
82   ret void
85 ; TBEGIN (nofloat) with dual CC use.
86 define i32 @test_tbegin_nofloat4(i32 %pad, i32 *%ptr) {
87 ; CHECK-LABEL: test_tbegin_nofloat4:
88 ; CHECK-NOT: stmg
89 ; CHECK-NOT: std
90 ; CHECK: tbegin 0, 65292
91 ; CHECK: ipm %r2
92 ; CHECK: srl %r2, 28
93 ; CHECK: ciblh %r2, 2, 0(%r14)
94 ; CHECK: mvhi 0(%r3), 0
95 ; CHECK: br %r14
96   %res = call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 65292)
97   %cmp = icmp eq i32 %res, 2
98   br i1 %cmp, label %if.then, label %if.end
100 if.then:                                          ; preds = %entry
101   store i32 0, i32* %ptr, align 4
102   br label %if.end
104 if.end:                                           ; preds = %if.then, %entry
105   ret i32 %res
108 ; TBEGIN (nofloat) with register.
109 define void @test_tbegin_nofloat5(i8 *%ptr) {
110 ; CHECK-LABEL: test_tbegin_nofloat5:
111 ; CHECK-NOT: stmg
112 ; CHECK-NOT: std
113 ; CHECK: tbegin 0(%r2), 65292
114 ; CHECK: br %r14
115   call i32 @llvm.s390.tbegin.nofloat(i8 *%ptr, i32 65292)
116   ret void
119 ; TBEGIN (nofloat) with GRSM 0x0f00.
120 define void @test_tbegin_nofloat6() {
121 ; CHECK-LABEL: test_tbegin_nofloat6:
122 ; CHECK: stmg %r6, %r15,
123 ; CHECK-NOT: std
124 ; CHECK: tbegin 0, 3840
125 ; CHECK: br %r14
126   call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 3840)
127   ret void
130 ; TBEGIN (nofloat) with GRSM 0xf100.
131 define void @test_tbegin_nofloat7() {
132 ; CHECK-LABEL: test_tbegin_nofloat7:
133 ; CHECK: stmg %r8, %r15,
134 ; CHECK-NOT: std
135 ; CHECK: tbegin 0, 61696
136 ; CHECK: br %r14
137   call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 61696)
138   ret void
141 ; TBEGIN (nofloat) with GRSM 0xfe00 -- stack pointer added automatically.
142 define void @test_tbegin_nofloat8() {
143 ; CHECK-LABEL: test_tbegin_nofloat8:
144 ; CHECK-NOT: stmg
145 ; CHECK-NOT: std
146 ; CHECK: tbegin 0, 65280
147 ; CHECK: br %r14
148   call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 65024)
149   ret void
152 ; TBEGIN (nofloat) with GRSM 0xfb00 -- no frame pointer needed.
153 define void @test_tbegin_nofloat9() {
154 ; CHECK-LABEL: test_tbegin_nofloat9:
155 ; CHECK: stmg %r10, %r15,
156 ; CHECK-NOT: std
157 ; CHECK: tbegin 0, 64256
158 ; CHECK: br %r14
159   call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 64256)
160   ret void
163 ; TBEGIN (nofloat) with GRSM 0xfb00 -- frame pointer added automatically.
164 define void @test_tbegin_nofloat10(i64 %n) {
165 ; CHECK-LABEL: test_tbegin_nofloat10:
166 ; CHECK: stmg %r11, %r15,
167 ; CHECK-NOT: std
168 ; CHECK: tbegin 0, 65280
169 ; CHECK: br %r14
170   %buf = alloca i8, i64 %n
171   call i32 @llvm.s390.tbegin.nofloat(i8 *null, i32 64256)
172   ret void
175 ; TBEGINC.
176 define void @test_tbeginc() {
177 ; CHECK-LABEL: test_tbeginc:
178 ; CHECK-NOT: stmg
179 ; CHECK-NOT: std
180 ; CHECK: tbeginc 0, 65288
181 ; CHECK: br %r14
182   call void @llvm.s390.tbeginc(i8 *null, i32 65288)
183   ret void
186 ; TEND with integer CC return value.
187 define i32 @test_tend1() {
188 ; CHECK-LABEL: test_tend1:
189 ; CHECK: tend
190 ; CHECK: ipm %r2
191 ; CHECK: srl %r2, 28
192 ; CHECK: br %r14
193   %res = call i32 @llvm.s390.tend()
194   ret i32 %res
197 ; TEND with implicit CC check.
198 define void @test_tend3(i32 *%ptr) {
199 ; CHECK-LABEL: test_tend3:
200 ; CHECK: tend
201 ; CHECK: ber %r14
202 ; CHECK: mvhi 0(%r2), 0
203 ; CHECK: br %r14
204   %res = call i32 @llvm.s390.tend()
205   %cmp = icmp eq i32 %res, 2
206   br i1 %cmp, label %if.then, label %if.end
208 if.then:                                          ; preds = %entry
209   store i32 0, i32* %ptr, align 4
210   br label %if.end
212 if.end:                                           ; preds = %if.then, %entry
213   ret void
216 ; TEND with dual CC use.
217 define i32 @test_tend2(i32 %pad, i32 *%ptr) {
218 ; CHECK-LABEL: test_tend2:
219 ; CHECK: tend
220 ; CHECK: ipm %r2
221 ; CHECK: srl %r2, 28
222 ; CHECK: ciblh %r2, 2, 0(%r14)
223 ; CHECK: mvhi 0(%r3), 0
224 ; CHECK: br %r14
225   %res = call i32 @llvm.s390.tend()
226   %cmp = icmp eq i32 %res, 2
227   br i1 %cmp, label %if.then, label %if.end
229 if.then:                                          ; preds = %entry
230   store i32 0, i32* %ptr, align 4
231   br label %if.end
233 if.end:                                           ; preds = %if.then, %entry
234   ret i32 %res
237 ; TABORT with register only.
238 define void @test_tabort1(i64 %val) {
239 ; CHECK-LABEL: test_tabort1:
240 ; CHECK: tabort 0(%r2)
241 ; CHECK: br %r14
242   call void @llvm.s390.tabort(i64 %val)
243   ret void
246 ; TABORT with immediate only.
247 define void @test_tabort2(i64 %val) {
248 ; CHECK-LABEL: test_tabort2:
249 ; CHECK: tabort 1234
250 ; CHECK: br %r14
251   call void @llvm.s390.tabort(i64 1234)
252   ret void
255 ; TABORT with register + immediate.
256 define void @test_tabort3(i64 %val) {
257 ; CHECK-LABEL: test_tabort3:
258 ; CHECK: tabort 1234(%r2)
259 ; CHECK: br %r14
260   %sum = add i64 %val, 1234
261   call void @llvm.s390.tabort(i64 %sum)
262   ret void
265 ; TABORT with out-of-range immediate.
266 define void @test_tabort4(i64 %val) {
267 ; CHECK-LABEL: test_tabort4:
268 ; CHECK: tabort 0({{%r[1-5]}})
269 ; CHECK: br %r14
270   call void @llvm.s390.tabort(i64 4096)
271   ret void
274 ; NTSTG with base pointer only.
275 define void @test_ntstg1(i64 *%ptr, i64 %val) {
276 ; CHECK-LABEL: test_ntstg1:
277 ; CHECK: ntstg %r3, 0(%r2)
278 ; CHECK: br %r14
279   call void @llvm.s390.ntstg(i64 %val, i64 *%ptr)
280   ret void
283 ; NTSTG with base and index.
284 ; Check that VSTL doesn't allow an index.
285 define void @test_ntstg2(i64 *%base, i64 %index, i64 %val) {
286 ; CHECK-LABEL: test_ntstg2:
287 ; CHECK: sllg [[REG:%r[1-5]]], %r3, 3
288 ; CHECK: ntstg %r4, 0([[REG]],%r2)
289 ; CHECK: br %r14
290   %ptr = getelementptr i64, i64 *%base, i64 %index
291   call void @llvm.s390.ntstg(i64 %val, i64 *%ptr)
292   ret void
295 ; NTSTG with the highest in-range displacement.
296 define void @test_ntstg3(i64 *%base, i64 %val) {
297 ; CHECK-LABEL: test_ntstg3:
298 ; CHECK: ntstg %r3, 524280(%r2)
299 ; CHECK: br %r14
300   %ptr = getelementptr i64, i64 *%base, i64 65535
301   call void @llvm.s390.ntstg(i64 %val, i64 *%ptr)
302   ret void
305 ; NTSTG with an out-of-range positive displacement.
306 define void @test_ntstg4(i64 *%base, i64 %val) {
307 ; CHECK-LABEL: test_ntstg4:
308 ; CHECK: ntstg %r3, 0({{%r[1-5]}})
309 ; CHECK: br %r14
310   %ptr = getelementptr i64, i64 *%base, i64 65536
311   call void @llvm.s390.ntstg(i64 %val, i64 *%ptr)
312   ret void
315 ; NTSTG with the lowest in-range displacement.
316 define void @test_ntstg5(i64 *%base, i64 %val) {
317 ; CHECK-LABEL: test_ntstg5:
318 ; CHECK: ntstg %r3, -524288(%r2)
319 ; CHECK: br %r14
320   %ptr = getelementptr i64, i64 *%base, i64 -65536
321   call void @llvm.s390.ntstg(i64 %val, i64 *%ptr)
322   ret void
325 ; NTSTG with an out-of-range negative displacement.
326 define void @test_ntstg6(i64 *%base, i64 %val) {
327 ; CHECK-LABEL: test_ntstg6:
328 ; CHECK: ntstg %r3, 0({{%r[1-5]}})
329 ; CHECK: br %r14
330   %ptr = getelementptr i64, i64 *%base, i64 -65537
331   call void @llvm.s390.ntstg(i64 %val, i64 *%ptr)
332   ret void
335 ; ETND.
336 define i32 @test_etnd() {
337 ; CHECK-LABEL: test_etnd:
338 ; CHECK: etnd %r2
339 ; CHECK: br %r14
340   %res = call i32 @llvm.s390.etnd()
341   ret i32 %res
344 ; PPA (Transaction-Abort Assist)
345 define void @test_ppa_txassist(i32 %val) {
346 ; CHECK-LABEL: test_ppa_txassist:
347 ; CHECK: ppa %r2, 0, 1
348 ; CHECK: br %r14
349   call void @llvm.s390.ppa.txassist(i32 %val)
350   ret void