1 ; Test STOCs that are presented as selects.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
5 ; 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
9 declare void @foo(i32 *)
11 ; Test the simple case, with the loaded value first.
12 define void @f1(i32 *%ptr, i32 %alt, i32 %limit) {
15 ; CHECK: stoche %r3, 0(%r2)
17 %cond = icmp ult i32 %limit, 42
18 %orig = load i32, i32 *%ptr
19 %res = select i1 %cond, i32 %orig, i32 %alt
20 store i32 %res, i32 *%ptr
24 ; ...and with the loaded value second
25 define void @f2(i32 *%ptr, i32 %alt, i32 %limit) {
28 ; CHECK: stocl %r3, 0(%r2)
30 %cond = icmp ult i32 %limit, 42
31 %orig = load i32, i32 *%ptr
32 %res = select i1 %cond, i32 %alt, i32 %orig
33 store i32 %res, i32 *%ptr
37 ; Test cases where the value is explicitly sign-extended to 64 bits, with the
39 define void @f3(i32 *%ptr, i64 %alt, i32 %limit) {
42 ; CHECK: stoche %r3, 0(%r2)
44 %cond = icmp ult i32 %limit, 42
45 %orig = load i32, i32 *%ptr
46 %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
53 ; ...and with the loaded value second
54 define void @f4(i32 *%ptr, i64 %alt, i32 %limit) {
57 ; CHECK: stocl %r3, 0(%r2)
59 %cond = icmp ult i32 %limit, 42
60 %orig = load i32, i32 *%ptr
61 %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
68 ; Test cases where the value is explicitly zero-extended to 32 bits, with the
70 define void @f5(i32 *%ptr, i64 %alt, i32 %limit) {
73 ; CHECK: stoche %r3, 0(%r2)
75 %cond = icmp ult i32 %limit, 42
76 %orig = load i32, i32 *%ptr
77 %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
84 ; ...and with the loaded value second
85 define void @f6(i32 *%ptr, i64 %alt, i32 %limit) {
88 ; CHECK: stocl %r3, 0(%r2)
90 %cond = icmp ult i32 %limit, 42
91 %orig = load i32, i32 *%ptr
92 %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
99 ; Check the high end of the aligned STOC range.
100 define void @f7(i32 *%base, i32 %alt, i32 %limit) {
102 ; CHECK: clfi %r4, 42
103 ; CHECK: stoche %r3, 524284(%r2)
105 %ptr = getelementptr i32, i32 *%base, i64 131071
106 %cond = icmp ult i32 %limit, 42
107 %orig = load i32, i32 *%ptr
108 %res = select i1 %cond, i32 %orig, i32 %alt
109 store i32 %res, i32 *%ptr
113 ; Check the next word up. Other sequences besides this one would be OK.
114 define void @f8(i32 *%base, i32 %alt, i32 %limit) {
116 ; CHECK: agfi %r2, 524288
117 ; CHECK: clfi %r4, 42
118 ; CHECK: stoche %r3, 0(%r2)
120 %ptr = getelementptr i32, i32 *%base, i64 131072
121 %cond = icmp ult i32 %limit, 42
122 %orig = load i32, i32 *%ptr
123 %res = select i1 %cond, i32 %orig, i32 %alt
124 store i32 %res, i32 *%ptr
128 ; Check the low end of the STOC range.
129 define void @f9(i32 *%base, i32 %alt, i32 %limit) {
131 ; CHECK: clfi %r4, 42
132 ; CHECK: stoche %r3, -524288(%r2)
134 %ptr = getelementptr i32, i32 *%base, i64 -131072
135 %cond = icmp ult i32 %limit, 42
136 %orig = load i32, i32 *%ptr
137 %res = select i1 %cond, i32 %orig, i32 %alt
138 store i32 %res, i32 *%ptr
142 ; Check the next word down, with the same comments as f8.
143 define void @f10(i32 *%base, i32 %alt, i32 %limit) {
145 ; CHECK: agfi %r2, -524292
146 ; CHECK: clfi %r4, 42
147 ; CHECK: stoche %r3, 0(%r2)
149 %ptr = getelementptr i32, i32 *%base, i64 -131073
150 %cond = icmp ult i32 %limit, 42
151 %orig = load i32, i32 *%ptr
152 %res = select i1 %cond, i32 %orig, i32 %alt
153 store i32 %res, i32 *%ptr
157 ; Try a frame index base.
158 define void @f11(i32 %alt, i32 %limit) {
160 ; CHECK: brasl %r14, foo@PLT
161 ; CHECK: stoche {{%r[0-9]+}}, {{[0-9]+}}(%r15)
162 ; CHECK: brasl %r14, foo@PLT
165 call void @foo(i32 *%ptr)
166 %cond = icmp ult i32 %limit, 42
167 %orig = load i32, i32 *%ptr
168 %res = select i1 %cond, i32 %orig, i32 %alt
169 store i32 %res, i32 *%ptr
170 call void @foo(i32 *%ptr)
174 ; Test that conditionally-executed stores do not use STOC, since STOC
175 ; is allowed to trap even when the condition is false.
176 define void @f12(i32 %a, i32 %b, i32 *%dest) {
181 %cmp = icmp ule i32 %a, %b
182 br i1 %cmp, label %store, label %exit
185 store i32 %b, i32 *%dest