1 ; Test STOCs that are presented as selects.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z196 | FileCheck %s
5 declare void @foo(i32 *)
7 ; Test the simple case, with the loaded value first.
8 define void @f1(i32 *%ptr, i32 %alt, i32 %limit) {
11 ; CHECK: stoche %r3, 0(%r2)
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
20 ; ...and with the loaded value second
21 define void @f2(i32 *%ptr, i32 %alt, i32 %limit) {
24 ; CHECK: stocl %r3, 0(%r2)
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
33 ; Test cases where the value is explicitly sign-extended to 64 bits, with the
35 define void @f3(i32 *%ptr, i64 %alt, i32 %limit) {
38 ; CHECK: stoche %r3, 0(%r2)
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
49 ; ...and with the loaded value second
50 define void @f4(i32 *%ptr, i64 %alt, i32 %limit) {
53 ; CHECK: stocl %r3, 0(%r2)
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
64 ; Test cases where the value is explicitly zero-extended to 32 bits, with the
66 define void @f5(i32 *%ptr, i64 %alt, i32 %limit) {
69 ; CHECK: stoche %r3, 0(%r2)
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
80 ; ...and with the loaded value second
81 define void @f6(i32 *%ptr, i64 %alt, i32 %limit) {
84 ; CHECK: stocl %r3, 0(%r2)
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
95 ; Check the high end of the aligned STOC range.
96 define void @f7(i32 *%base, i32 %alt, i32 %limit) {
99 ; CHECK: stoche %r3, 524284(%r2)
101 %ptr = getelementptr i32 *%base, i64 131071
102 %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
109 ; Check the next word up. Other sequences besides this one would be OK.
110 define void @f8(i32 *%base, i32 %alt, i32 %limit) {
112 ; CHECK: agfi %r2, 524288
113 ; CHECK: clfi %r4, 42
114 ; CHECK: stoche %r3, 0(%r2)
116 %ptr = getelementptr i32 *%base, i64 131072
117 %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
124 ; Check the low end of the STOC range.
125 define void @f9(i32 *%base, i32 %alt, i32 %limit) {
127 ; CHECK: clfi %r4, 42
128 ; CHECK: stoche %r3, -524288(%r2)
130 %ptr = getelementptr i32 *%base, i64 -131072
131 %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
138 ; Check the next word down, with the same comments as f8.
139 define void @f10(i32 *%base, i32 %alt, i32 %limit) {
141 ; CHECK: agfi %r2, -524292
142 ; CHECK: clfi %r4, 42
143 ; CHECK: stoche %r3, 0(%r2)
145 %ptr = getelementptr i32 *%base, i64 -131073
146 %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
153 ; Try a frame index base.
154 define void @f11(i32 %alt, i32 %limit) {
156 ; CHECK: brasl %r14, foo@PLT
157 ; CHECK: stoche {{%r[0-9]+}}, {{[0-9]+}}(%r15)
158 ; CHECK: brasl %r14, foo@PLT
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)
170 ; Test that conditionally-executed stores do not use STOC, since STOC
171 ; is allowed to trap even when the condition is false.
172 define void @f12(i32 %a, i32 %b, i32 *%dest) {
177 %cmp = icmp ule i32 %a, %b
178 br i1 %cmp, label %store, label %exit
181 store i32 %b, i32 *%dest