blob: e008fd7eeaaedb3b9c6c9855fdfcab0aa2c92f6c [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
5declare void @foo(i32 *)
6
7; Test the simple case, with the loaded value first.
8define void @f1(i32 *%ptr, i32 %alt, i32 %limit) {
9; CHECK-LABEL: f1:
10; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +000011; CHECK: stoche %r3, 0(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +000012; CHECK: br %r14
13 %cond = icmp ult i32 %limit, 42
14 %orig = load i32 *%ptr
15 %res = select i1 %cond, i32 %orig, i32 %alt
16 store i32 %res, i32 *%ptr
17 ret void
18}
19
20; ...and with the loaded value second
21define void @f2(i32 *%ptr, i32 %alt, i32 %limit) {
22; CHECK-LABEL: f2:
23; CHECK: clfi %r4, 42
24; CHECK: stocl %r3, 0(%r2)
25; CHECK: br %r14
26 %cond = icmp ult i32 %limit, 42
27 %orig = load i32 *%ptr
28 %res = select i1 %cond, i32 %alt, i32 %orig
29 store i32 %res, i32 *%ptr
30 ret void
31}
32
33; Test cases where the value is explicitly sign-extended to 64 bits, with the
34; loaded value first.
35define void @f3(i32 *%ptr, i64 %alt, i32 %limit) {
36; CHECK-LABEL: f3:
37; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +000038; CHECK: stoche %r3, 0(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +000039; CHECK: br %r14
40 %cond = icmp ult i32 %limit, 42
41 %orig = load i32 *%ptr
42 %ext = sext i32 %orig to i64
43 %res = select i1 %cond, i64 %ext, i64 %alt
44 %trunc = trunc i64 %res to i32
45 store i32 %trunc, i32 *%ptr
46 ret void
47}
48
49; ...and with the loaded value second
50define void @f4(i32 *%ptr, i64 %alt, i32 %limit) {
51; CHECK-LABEL: f4:
52; CHECK: clfi %r4, 42
53; CHECK: stocl %r3, 0(%r2)
54; CHECK: br %r14
55 %cond = icmp ult i32 %limit, 42
56 %orig = load i32 *%ptr
57 %ext = sext i32 %orig to i64
58 %res = select i1 %cond, i64 %alt, i64 %ext
59 %trunc = trunc i64 %res to i32
60 store i32 %trunc, i32 *%ptr
61 ret void
62}
63
64; Test cases where the value is explicitly zero-extended to 32 bits, with the
65; loaded value first.
66define void @f5(i32 *%ptr, i64 %alt, i32 %limit) {
67; CHECK-LABEL: f5:
68; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +000069; CHECK: stoche %r3, 0(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +000070; CHECK: br %r14
71 %cond = icmp ult i32 %limit, 42
72 %orig = load i32 *%ptr
73 %ext = zext i32 %orig to i64
74 %res = select i1 %cond, i64 %ext, i64 %alt
75 %trunc = trunc i64 %res to i32
76 store i32 %trunc, i32 *%ptr
77 ret void
78}
79
80; ...and with the loaded value second
81define void @f6(i32 *%ptr, i64 %alt, i32 %limit) {
82; CHECK-LABEL: f6:
83; CHECK: clfi %r4, 42
84; CHECK: stocl %r3, 0(%r2)
85; CHECK: br %r14
86 %cond = icmp ult i32 %limit, 42
87 %orig = load i32 *%ptr
88 %ext = zext i32 %orig to i64
89 %res = select i1 %cond, i64 %alt, i64 %ext
90 %trunc = trunc i64 %res to i32
91 store i32 %trunc, i32 *%ptr
92 ret void
93}
94
95; Check the high end of the aligned STOC range.
96define void @f7(i32 *%base, i32 %alt, i32 %limit) {
97; CHECK-LABEL: f7:
98; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +000099; CHECK: stoche %r3, 524284(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000100; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000101 %ptr = getelementptr i32, i32 *%base, i64 131071
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000102 %cond = icmp ult i32 %limit, 42
103 %orig = load i32 *%ptr
104 %res = select i1 %cond, i32 %orig, i32 %alt
105 store i32 %res, i32 *%ptr
106 ret void
107}
108
109; Check the next word up. Other sequences besides this one would be OK.
110define void @f8(i32 *%base, i32 %alt, i32 %limit) {
111; CHECK-LABEL: f8:
112; CHECK: agfi %r2, 524288
113; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +0000114; CHECK: stoche %r3, 0(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000115; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000116 %ptr = getelementptr i32, i32 *%base, i64 131072
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000117 %cond = icmp ult i32 %limit, 42
118 %orig = load i32 *%ptr
119 %res = select i1 %cond, i32 %orig, i32 %alt
120 store i32 %res, i32 *%ptr
121 ret void
122}
123
124; Check the low end of the STOC range.
125define void @f9(i32 *%base, i32 %alt, i32 %limit) {
126; CHECK-LABEL: f9:
127; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +0000128; CHECK: stoche %r3, -524288(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000129; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000130 %ptr = getelementptr i32, i32 *%base, i64 -131072
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000131 %cond = icmp ult i32 %limit, 42
132 %orig = load i32 *%ptr
133 %res = select i1 %cond, i32 %orig, i32 %alt
134 store i32 %res, i32 *%ptr
135 ret void
136}
137
138; Check the next word down, with the same comments as f8.
139define void @f10(i32 *%base, i32 %alt, i32 %limit) {
140; CHECK-LABEL: f10:
141; CHECK: agfi %r2, -524292
142; CHECK: clfi %r4, 42
Richard Sandiford3d768e32013-07-31 12:30:20 +0000143; CHECK: stoche %r3, 0(%r2)
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000144; CHECK: br %r14
David Blaikie79e6c742015-02-27 19:29:02 +0000145 %ptr = getelementptr i32, i32 *%base, i64 -131073
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000146 %cond = icmp ult i32 %limit, 42
147 %orig = load i32 *%ptr
148 %res = select i1 %cond, i32 %orig, i32 %alt
149 store i32 %res, i32 *%ptr
150 ret void
151}
152
153; Try a frame index base.
154define void @f11(i32 %alt, i32 %limit) {
155; CHECK-LABEL: f11:
156; CHECK: brasl %r14, foo@PLT
Richard Sandiford3d768e32013-07-31 12:30:20 +0000157; CHECK: stoche {{%r[0-9]+}}, {{[0-9]+}}(%r15)
Richard Sandiforda68e6f52013-07-25 08:57:02 +0000158; CHECK: brasl %r14, foo@PLT
159; CHECK: br %r14
160 %ptr = alloca i32
161 call void @foo(i32 *%ptr)
162 %cond = icmp ult i32 %limit, 42
163 %orig = load i32 *%ptr
164 %res = select i1 %cond, i32 %orig, i32 %alt
165 store i32 %res, i32 *%ptr
166 call void @foo(i32 *%ptr)
167 ret void
168}
169
170; Test that conditionally-executed stores do not use STOC, since STOC
171; is allowed to trap even when the condition is false.
172define void @f12(i32 %a, i32 %b, i32 *%dest) {
173; CHECK-LABEL: f12:
174; CHECK-NOT: stoc
175; CHECK: br %r14
176entry:
177 %cmp = icmp ule i32 %a, %b
178 br i1 %cmp, label %store, label %exit
179
180store:
181 store i32 %b, i32 *%dest
182 br label %exit
183
184exit:
185 ret void
186}