blob: e15e37bdbef9e8d724e67e765f89998ebd6b230e [file] [log] [blame]
Richard Sandiforda68e6f52013-07-25 08:57:02 +00001; Test STOCs that are presented as selects.
2;
3; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
4
Ulrich Weigand524f2762016-11-28 13:34:08 +00005; Run the test again to make sure it still works the same even
6; in the presence of the load-store-on-condition-2 facility.
7; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z13 | FileCheck %s
8
Richard Sandiforda68e6f52013-07-25 08:57:02 +00009declare void @foo(i32 *)
10
11; Test the simple case, with the loaded value first.
12define void @f1(i32 *%ptr, i32 %alt, i32 %limit) {
13; CHECK-LABEL: f1:
14; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +000015; CHECK: stoche %r3, 0(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +000016; CHECK: br %r14
17 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000018 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +000019 %res = select i1 %cond, i32 %orig, i32 %alt
20 store i32 %res, i32 *%ptr
21 ret void
22}
23
24; ...and with the loaded value second
25define void @f2(i32 *%ptr, i32 %alt, i32 %limit) {
26; CHECK-LABEL: f2:
27; CHECK: clfi %r4, 42
28; CHECK: stocl %r3, 0(%r2)
29; CHECK: br %r14
30 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000031 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +000032 %res = select i1 %cond, i32 %alt, i32 %orig
33 store i32 %res, i32 *%ptr
34 ret void
35}
36
37; Test cases where the value is explicitly sign-extended to 64 bits, with the
38; loaded value first.
39define void @f3(i32 *%ptr, i64 %alt, i32 %limit) {
40; CHECK-LABEL: f3:
41; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +000042; CHECK: stoche %r3, 0(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +000043; CHECK: br %r14
44 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000045 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +000046 %ext = sext i32 %orig to i64
47 %res = select i1 %cond, i64 %ext, i64 %alt
48 %trunc = trunc i64 %res to i32
49 store i32 %trunc, i32 *%ptr
50 ret void
51}
52
53; ...and with the loaded value second
54define void @f4(i32 *%ptr, i64 %alt, i32 %limit) {
55; CHECK-LABEL: f4:
56; CHECK: clfi %r4, 42
57; CHECK: stocl %r3, 0(%r2)
58; CHECK: br %r14
59 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000060 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +000061 %ext = sext i32 %orig to i64
62 %res = select i1 %cond, i64 %alt, i64 %ext
63 %trunc = trunc i64 %res to i32
64 store i32 %trunc, i32 *%ptr
65 ret void
66}
67
68; Test cases where the value is explicitly zero-extended to 32 bits, with the
69; loaded value first.
70define void @f5(i32 *%ptr, i64 %alt, i32 %limit) {
71; CHECK-LABEL: f5:
72; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +000073; CHECK: stoche %r3, 0(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +000074; CHECK: br %r14
75 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000076 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +000077 %ext = zext i32 %orig to i64
78 %res = select i1 %cond, i64 %ext, i64 %alt
79 %trunc = trunc i64 %res to i32
80 store i32 %trunc, i32 *%ptr
81 ret void
82}
83
84; ...and with the loaded value second
85define void @f6(i32 *%ptr, i64 %alt, i32 %limit) {
86; CHECK-LABEL: f6:
87; CHECK: clfi %r4, 42
88; CHECK: stocl %r3, 0(%r2)
89; CHECK: br %r14
90 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +000091 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +000092 %ext = zext i32 %orig to i64
93 %res = select i1 %cond, i64 %alt, i64 %ext
94 %trunc = trunc i64 %res to i32
95 store i32 %trunc, i32 *%ptr
96 ret void
97}
98
99; Check the high end of the aligned STOC range.
100define void @f7(i32 *%base, i32 %alt, i32 %limit) {
101; CHECK-LABEL: f7:
102; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +0000103; CHECK: stoche %r3, 524284(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000104; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000105 %ptr = getelementptr i32, i32 *%base, i64 131071
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000106 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000107 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000108 %res = select i1 %cond, i32 %orig, i32 %alt
109 store i32 %res, i32 *%ptr
110 ret void
111}
112
113; Check the next word up. Other sequences besides this one would be OK.
114define void @f8(i32 *%base, i32 %alt, i32 %limit) {
115; CHECK-LABEL: f8:
116; CHECK: agfi %r2, 524288
117; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +0000118; CHECK: stoche %r3, 0(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000119; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000120 %ptr = getelementptr i32, i32 *%base, i64 131072
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000121 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000122 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000123 %res = select i1 %cond, i32 %orig, i32 %alt
124 store i32 %res, i32 *%ptr
125 ret void
126}
127
128; Check the low end of the STOC range.
129define void @f9(i32 *%base, i32 %alt, i32 %limit) {
130; CHECK-LABEL: f9:
131; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +0000132; CHECK: stoche %r3, -524288(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000133; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000134 %ptr = getelementptr i32, i32 *%base, i64 -131072
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000135 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000136 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000137 %res = select i1 %cond, i32 %orig, i32 %alt
138 store i32 %res, i32 *%ptr
139 ret void
140}
141
142; Check the next word down, with the same comments as f8.
143define void @f10(i32 *%base, i32 %alt, i32 %limit) {
144; CHECK-LABEL: f10:
145; CHECK: agfi %r2, -524292
146; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +0000147; CHECK: stoche %r3, 0(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000148; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000149 %ptr = getelementptr i32, i32 *%base, i64 -131073
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000150 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000151 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000152 %res = select i1 %cond, i32 %orig, i32 %alt
153 store i32 %res, i32 *%ptr
154 ret void
155}
156
157; Try a frame index base.
158define void @f11(i32 %alt, i32 %limit) {
159; CHECK-LABEL: f11:
160; CHECK: brasl %r14, foo@PLT
Richard Sandiford3d768e32013-07-31 12:30:20 +0000161; CHECK: stoche {{%r[0-9]+}}, {{[0-9]+}}(%r15)
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000162; CHECK: brasl %r14, foo@PLT
163; CHECK: br %r14
164 %ptr = alloca i32
165 call void @foo(i32 *%ptr)
166 %cond = icmp ult i32 %limit, 42
Ulrich Weigand9dd23b82018-07-20 12:12:10 +0000167 %orig = load i32, i32 *%ptr
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000168 %res = select i1 %cond, i32 %orig, i32 %alt
169 store i32 %res, i32 *%ptr
170 call void @foo(i32 *%ptr)
171 ret void
172}
173
174; Test that conditionally-executed stores do not use STOC, since STOC
175; is allowed to trap even when the condition is false.
176define void @f12(i32 %a, i32 %b, i32 *%dest) {
177; CHECK-LABEL: f12:
178; CHECK-NOT: stoc
179; CHECK: br %r14
180entry:
181 %cmp = icmp ule i32 %a, %b
182 br i1 %cmp, label %store, label %exit
183
184store:
185 store i32 %b, i32 *%dest
186 br label %exit
187
188exit:
189 ret void
190}